diff --git a/Editor/DrawDebugLibrary.meta b/Editor/DrawDebugLibrary.meta new file mode 100644 index 0000000..da5458a --- /dev/null +++ b/Editor/DrawDebugLibrary.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bfb845b368c96cd4ba331f8878a70332 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/BezierSplineDrawer2DInspector.cs b/Editor/DrawDebugLibrary/BezierSplineDrawer2DInspector.cs new file mode 100644 index 0000000..7568c3f --- /dev/null +++ b/Editor/DrawDebugLibrary/BezierSplineDrawer2DInspector.cs @@ -0,0 +1,2121 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(BezierSplineDrawer2D))] + public class BezierSplineDrawer2DInspector : VisualizerParentInspector + { + BezierSplineDrawer2D bezierSplineDrawer_unserializedMonoB; + Tool toolToSelectAfterThisInspectorGetsUnselcted = Tool.None; + Tool selectedToolDuringPreviousOnSceneGUI = Tool.None; + bool sheduleFocusSceneViewOnControlPoint = false; + int delayCounter_afterShedulingFocusSceneViewOnControlPoint = 0; + float dotLength_ofDottedLines = 4.0f; + bool hasRegisteredUndo_sinceMouseDown = false; + GUIContent plusSymbolIcon; + Vector3 sceneViewCamForward_normalized; + Vector3 sceneViewCamUp_normalized; + Vector3 sceneViewCamRight_normalized; + Vector3 sceneViewCam_to_anchorPoint; + BezierSplineDrawerInspector.ManyDrawnLinesWarningState manyDrawnLinesWarningState = BezierSplineDrawerInspector.ManyDrawnLinesWarningState.noWarning; + + void OnEnable() + { + OnEnable_base(); + bezierSplineDrawer_unserializedMonoB = (BezierSplineDrawer2D)target; + plusSymbolIcon = EditorGUIUtility.TrIconContent("Toolbar Plus", "Add new control point"); + + toolToSelectAfterThisInspectorGetsUnselcted = Tools.current; + ProcessChangingEditorTool(); + selectedToolDuringPreviousOnSceneGUI = Tools.current; + } + + public void OnDisable() + { + Tools.current = toolToSelectAfterThisInspectorGetsUnselcted; + } + + public void OnSceneGUI() + { + if (bezierSplineDrawer_unserializedMonoB != null) //-> sometimes after deleting the spline component in the inspector this "OnSceneGUI()" is still called, which would result in a missingRefException without this check + { + bezierSplineDrawer_unserializedMonoB.sheduledSceneViewRepaint_hasBeenExecuted = true; + + if (bezierSplineDrawer_unserializedMonoB.enabled) //-> GizmoLines automatically hide if a component is disabled, Handles do not: Therefore manual disabling here + { + TryFocusControlPointInSceneView_onKeypressF(); + TryProcessChangingEditorTool(); + + Matrix4x4 handlesMatrix_before = Handles.matrix; + Color handlesColor_before = Handles.color; + + DrawHandles(); + + Handles.matrix = handlesMatrix_before; + Handles.color = handlesColor_before; + } + } + } + + void TryFocusControlPointInSceneView_onKeypressF() + { + delayCounter_afterShedulingFocusSceneViewOnControlPoint++; + SheduleFocusing_onKeypressF(); + ExecuteSheduledFocusingAfterDelay(); + } + + void SheduleFocusing_onKeypressF() + { + Event currentEvent = Event.current; + if (currentEvent.type == EventType.KeyDown) + { + if (currentEvent.keyCode == KeyCode.F) + { + //this only works when the mouse is in the scene view window (in contrast to Unitys build-in behaviour, where you can focus the scene view camera via pressing "F" even when the mouse is not in the scene view) + sheduleFocusSceneViewOnControlPoint = true; + delayCounter_afterShedulingFocusSceneViewOnControlPoint = 0; + } + } + } + + void ExecuteSheduledFocusingAfterDelay() + { + if (sheduleFocusSceneViewOnControlPoint) + { + //This overwrites the focusing on the gameobject center (which is automatically executed by Unity onKeypressF) with focusing on the the selected control point instead. + //The sheduling is because otherwise Unitys automatic focussing on the gameobject will overwrite the here executed focusing + int delayValue = 20; //This is a guessed trial-an-error value. + if (delayCounter_afterShedulingFocusSceneViewOnControlPoint > delayValue) + { + sheduleFocusSceneViewOnControlPoint = false; + if (SceneView.lastActiveSceneView != null) + { + int i_ofFirstHighlightedControlPoint = bezierSplineDrawer_unserializedMonoB.Get_i_ofFirstHighlightedControlPoint(); + if (i_ofFirstHighlightedControlPoint == (-1)) + { + FrameSceneViewCam_soItSeesAllControlPoints(i_ofFirstHighlightedControlPoint); + } + else + { + FrameSceneViewCam_soItSeesSpecifiedControlPoints(i_ofFirstHighlightedControlPoint, true); + } + } + } + } + } + + void FrameSceneViewCam_soItSeesAllControlPoints(int i_ofFirstHighlightedControlPoint) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count == 0) + { + Bounds boundsOfSelection = new Bounds(bezierSplineDrawer_unserializedMonoB.Get_originPos_ofActiveDrawSpace_inUnitsOfGlobalSpace(), Vector3.zero); + SceneView.lastActiveSceneView.Frame(boundsOfSelection, false); + } + else + { + FrameSceneViewCam_soItSeesSpecifiedControlPoints(i_ofFirstHighlightedControlPoint, false); + } + } + + void FrameSceneViewCam_soItSeesSpecifiedControlPoints(int i_ofFirstHighlightedControlPoint, bool includeOnlySelectedControlPoints_notAllControlPoints) + { + Vector3 posGlobal_ofFirstFramedControlPoint; + if (includeOnlySelectedControlPoints_notAllControlPoints) + { + posGlobal_ofFirstFramedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i_ofFirstHighlightedControlPoint].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + } + else + { + //"listOfControlPointTriplets.Count" is guaranteed bigger than 0 here: + posGlobal_ofFirstFramedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[0].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + } + Bounds boundsOfSelection = new Bounds(posGlobal_ofFirstFramedControlPoint, Vector3.zero); + + for (int i = 0; i < bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count; i++) + { + if ((includeOnlySelectedControlPoints_notAllControlPoints == false) || bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].isHighlighted) + { + boundsOfSelection.Encapsulate(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()); + + InternalDXXL_BezierControlPointTriplet2D nextControlPoint = bezierSplineDrawer_unserializedMonoB.GetNextControlPointTriplet(i, false); + if (nextControlPoint != null) { boundsOfSelection.Encapsulate(nextControlPoint.anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()); } + + InternalDXXL_BezierControlPointTriplet2D previousControlPoint = bezierSplineDrawer_unserializedMonoB.GetPreviousControlPointTriplet(i, false); + if (previousControlPoint != null) { boundsOfSelection.Encapsulate(previousControlPoint.anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()); } + } + } + SceneView.lastActiveSceneView.Frame(boundsOfSelection, false); + } + + void DrawHandles() + { + if (bezierSplineDrawer_unserializedMonoB.hideAllHandles == false) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count == 0) + { + DrawPlusButton_asFallbackIfNoControlPointsExist(); + } + else + { + for (int i = 0; i < bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count; i++) + { + Handles.matrix = Matrix4x4.identity; + + AssignControlHandleIDs(i); + DrawLinesBetweenSubPoints(i); + DrawLinesAlongZToBoundGameobjects(i); + DrawIndexAsText(i); + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out sceneViewCamForward_normalized, out sceneViewCamUp_normalized, out sceneViewCamRight_normalized, out sceneViewCam_to_anchorPoint, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), DrawBasics.CameraForAutomaticOrientation.sceneViewCamera); + DrawNonInteractableAnchorPointVisualizer(i); + DrawNonInteractableHelperPointVisualizer(i, true, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()); + DrawNonInteractableHelperPointVisualizer(i, false, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()); + DrawPlusButtonsForAddingNewControlPoints_atSplineStartAndEnd(i); + DrawPlusButtonsForAddingNewControlPoints_somewhereOnUpcomingSplineSegment(i); + DrawUnitysBuildInHandlesAtSubPoints(i); + DrawCustomHandlesAtSubPoints(i); + TrySetSelectedListSlot_dueToHandlesInteraction(i); + Reset_recalculationFlags_duringNoHandleClickedOrDraggedPhases(i); + } + } + } + + ResetUndoRegistrationFlag_duringNoInteractionPhases(); + } + + void DrawPlusButton_asFallbackIfNoControlPointsExist() + { + Vector3 posOfPlusButton_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.Get_originPos_ofActiveDrawSpace_inUnitsOfGlobalSpace(); + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out sceneViewCamForward_normalized, out sceneViewCamUp_normalized, out sceneViewCamRight_normalized, out sceneViewCam_to_anchorPoint, posOfPlusButton_inUnitsOfGlobalSpace, DrawBasics.CameraForAutomaticOrientation.sceneViewCamera); + bool buttonHasBeenClicked = InternalDXXL_BezierHandles.PlusButton(posOfPlusButton_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.handleSizeOf_plusButtons, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, sceneViewCamForward_normalized, sceneViewCamUp_normalized, sceneViewCamRight_normalized, plusSymbolIcon); + if (buttonHasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CreateNewControlPoint_atSplineEnd(); + } + } + + void AssignControlHandleIDs(int i) + { + InternalDXXL_BezierControlPointTriplet2D concernedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + int hint_base = 100 * i; //probably also working without the int-hints + + concernedControlPoint.anchorPoint.controlID_ofCustomHandles_sphere = GUIUtility.GetControlID(hint_base + 1, FocusType.Passive); + concernedControlPoint.anchorPoint.controlID_ofCustomHandles_forwardCone = GUIUtility.GetControlID(hint_base + 2, FocusType.Passive); + concernedControlPoint.anchorPoint.controlID_ofCustomHandles_backwardCone = GUIUtility.GetControlID(hint_base + 3, FocusType.Passive); + concernedControlPoint.anchorPoint.controlID_ofUnityStylePositionHandleUp = GUIUtility.GetControlID(hint_base + 4, FocusType.Passive); + concernedControlPoint.anchorPoint.controlID_ofUnityStylePositionHandleRight = GUIUtility.GetControlID(hint_base + 5, FocusType.Passive); + concernedControlPoint.anchorPoint.controlID_ofUnityStyleRotationHandle2D = GUIUtility.GetControlID(hint_base + 6, FocusType.Passive); + + concernedControlPoint.forwardHelperPoint.controlID_ofCustomHandles_sphere = GUIUtility.GetControlID(hint_base + 7, FocusType.Passive); + concernedControlPoint.forwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithAnchor = GUIUtility.GetControlID(hint_base + 8, FocusType.Passive); + concernedControlPoint.forwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper = GUIUtility.GetControlID(hint_base + 9, FocusType.Passive); + concernedControlPoint.forwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithAnchor = GUIUtility.GetControlID(hint_base + 10, FocusType.Passive); + concernedControlPoint.forwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper = GUIUtility.GetControlID(hint_base + 11, FocusType.Passive); + concernedControlPoint.forwardHelperPoint.controlID_ofUnityStylePositionHandleUp = GUIUtility.GetControlID(hint_base + 12, FocusType.Passive); + concernedControlPoint.forwardHelperPoint.controlID_ofUnityStylePositionHandleRight = GUIUtility.GetControlID(hint_base + 13, FocusType.Passive); + + concernedControlPoint.backwardHelperPoint.controlID_ofCustomHandles_sphere = GUIUtility.GetControlID(hint_base + 14, FocusType.Passive); + concernedControlPoint.backwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithAnchor = GUIUtility.GetControlID(hint_base + 15, FocusType.Passive); + concernedControlPoint.backwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper = GUIUtility.GetControlID(hint_base + 16, FocusType.Passive); + concernedControlPoint.backwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithAnchor = GUIUtility.GetControlID(hint_base + 17, FocusType.Passive); + concernedControlPoint.backwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper = GUIUtility.GetControlID(hint_base + 18, FocusType.Passive); + concernedControlPoint.backwardHelperPoint.controlID_ofUnityStylePositionHandleUp = GUIUtility.GetControlID(hint_base + 19, FocusType.Passive); + concernedControlPoint.backwardHelperPoint.controlID_ofUnityStylePositionHandleRight = GUIUtility.GetControlID(hint_base + 20, FocusType.Passive); + } + + void DrawLinesBetweenSubPoints(int i) + { + TryDrawLineToForwardWeight(i); + TryDrawLineToBackwardWeight(i); + TryDrawLineFromForwardHelperPoint_toBackwardHelperPointOfNextControlPoint(i); + TryDrawLineFromForwardHelperPoint_toAnchorPointOfNextControlPoint(i); + TryDrawLineFromAnchorPoint_toBackwardHelperPointOfNextControlPoint(i); + } + + void TryDrawLineToForwardWeight(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.isUsed) + { + Vector3 lineStartPos_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + Vector3 lineEndPos_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + + TryDrawExpandedLowAlphaLine_fromAnchorToHelper(i, lineStartPos_inUnitsOfGlobalSpace, lineEndPos_inUnitsOfGlobalSpace); + + Handles.color = bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints; + Handles.DrawLine(lineStartPos_inUnitsOfGlobalSpace, lineEndPos_inUnitsOfGlobalSpace); + } + } + + void TryDrawLineToBackwardWeight(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.isUsed) + { + Vector3 lineStartPos_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + Vector3 lineEndPos_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + + TryDrawExpandedLowAlphaLine_fromAnchorToHelper(i, lineStartPos_inUnitsOfGlobalSpace, lineEndPos_inUnitsOfGlobalSpace); + + Handles.color = bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints; + Handles.DrawLine(lineStartPos_inUnitsOfGlobalSpace, lineEndPos_inUnitsOfGlobalSpace); + } + } + + void TryDrawExpandedLowAlphaLine_fromAnchorToHelper(int i, Vector3 lineStartPos_inUnitsOfGlobalSpace, Vector3 lineEndPos_inUnitsOfGlobalSpace) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].isHighlighted) + { + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, BezierSplineDrawerInspector.alpha_ofAdditionalExpandedLowAlphaLineToHelpers_ofSelectedControlPoints); + Handles.DrawAAPolyLine(BezierSplineDrawerInspector.width_ofAdditionalExpandedLowAlphaLineToHelpers_ofSelectedControlPoints, lineStartPos_inUnitsOfGlobalSpace, lineEndPos_inUnitsOfGlobalSpace); + } + } + + void TryDrawLineFromForwardHelperPoint_toBackwardHelperPointOfNextControlPoint(int i) + { + if (CheckIf_drawLineFromForwardHelperPoint_toBackwardHelperPointOfNextControlPoint(i)) + { + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, BezierSplineDrawerInspector.alphaOfDottedLineBetweenHelperPoints); + int i_ofNextControlPoint = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count); + Handles.DrawDottedLine(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i_ofNextControlPoint].backwardHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), dotLength_ofDottedLines); + } + } + + bool CheckIf_drawLineFromForwardHelperPoint_toBackwardHelperPointOfNextControlPoint(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.isUsed) + { + InternalDXXL_BezierControlPointTriplet2D nextControlPointTriplet = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetNextControlPointTripletAlongSplineDir(false); + if (nextControlPointTriplet == null) + { + return false; + } + else + { + return nextControlPointTriplet.backwardHelperPoint.isUsed; + } + } + else + { + return false; + } + } + + void TryDrawLineFromForwardHelperPoint_toAnchorPointOfNextControlPoint(int i) + { + if (CheckIf_drawLineFromForwardHelperPoint_toAnchorPointOfNextControlPoint(i)) + { + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, BezierSplineDrawerInspector.alphaOfDottedLineBetweenHelperPoints); + int i_ofNextControlPoint = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count); + Handles.DrawDottedLine(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i_ofNextControlPoint].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), dotLength_ofDottedLines); + } + } + + bool CheckIf_drawLineFromForwardHelperPoint_toAnchorPointOfNextControlPoint(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.isUsed) + { + InternalDXXL_BezierControlPointTriplet2D nextControlPointTriplet = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetNextControlPointTripletAlongSplineDir(false); + if (nextControlPointTriplet == null) + { + return false; + } + else + { + return (nextControlPointTriplet.backwardHelperPoint.isUsed == false); + } + } + else + { + return false; + } + } + + void TryDrawLineFromAnchorPoint_toBackwardHelperPointOfNextControlPoint(int i) + { + if (CheckIf_drawLineFromAnchorPoint_toBackwardHelperPointOfNextControlPoint(i)) + { + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, BezierSplineDrawerInspector.alphaOfDottedLineBetweenHelperPoints); + int i_ofNextControlPoint = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count); + Handles.DrawDottedLine(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i_ofNextControlPoint].backwardHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), dotLength_ofDottedLines); + } + } + + bool CheckIf_drawLineFromAnchorPoint_toBackwardHelperPointOfNextControlPoint(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.isUsed == false) + { + InternalDXXL_BezierControlPointTriplet2D nextControlPointTriplet = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetNextControlPointTripletAlongSplineDir(false); + if (nextControlPointTriplet == null) + { + return false; + } + else + { + return nextControlPointTriplet.backwardHelperPoint.isUsed; + } + } + else + { + return false; + } + } + + void DrawLinesAlongZToBoundGameobjects(int i) + { + if (bezierSplineDrawer_unserializedMonoB.showDottedLinesAlongZToBoundGameobjects) + { + Handles.color = bezierSplineDrawer_unserializedMonoB.colorOfLinesAlongZToBoundGameobjects; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + Handles.DrawDottedLine(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.boundGameobject.transform.position, bezierSplineDrawer_unserializedMonoB.dotLength_ofDottedLinesAlongZToBoundGameobjects); + } + + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + Handles.DrawDottedLine(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.boundGameobject.transform.position, bezierSplineDrawer_unserializedMonoB.dotLength_ofDottedLinesAlongZToBoundGameobjects); + } + + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + Handles.DrawDottedLine(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.boundGameobject.transform.position, bezierSplineDrawer_unserializedMonoB.dotLength_ofDottedLinesAlongZToBoundGameobjects); + } + } + } + + void TryProcessChangingEditorTool() + { + if (selectedToolDuringPreviousOnSceneGUI != Tools.current) + { + ProcessChangingEditorTool(); + } + selectedToolDuringPreviousOnSceneGUI = Tools.current; + } + + void ProcessChangingEditorTool() + { + if (Tools.current == Tool.Move) + { + if (bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_anchorPoints == bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_helperPoints) + { + //-> custom handles are "both on" or "both off" + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atAnchors = true; + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atHelpers = true; + } + else + { + //-> one custom handle is on, the other is off + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atAnchors = bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_anchorPoints; + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atHelpers = bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_helperPoints; + } + + bezierSplineDrawer_unserializedMonoB.showHandleFor_rotation = false; + } + else + { + if (Tools.current == Tool.Rotate) + { + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atAnchors = false; + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atHelpers = false; + bezierSplineDrawer_unserializedMonoB.showHandleFor_rotation = true; + } + else + { + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atAnchors = false; + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atHelpers = false; + bezierSplineDrawer_unserializedMonoB.showHandleFor_rotation = false; + } + } + } + + void DrawNonInteractableAnchorPointVisualizer(int i) + { + Vector3 position_ofAnchorPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + DrawNonInteractableSubPointVisualizer(i, position_ofAnchorPoint_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, bezierSplineDrawer_unserializedMonoB.handleSizeOf_customHandle_atAnchors, bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_anchorPoints); + } + + void DrawNonInteractableHelperPointVisualizer(int i, bool concerncedHelperPoint_isForward_notBackward, Vector3 position_ofHelperPoint_inUnitsOfGlobalSpace) + { + if (CheckIf_drawNonInteractableHelperPointVisualizer(i, concerncedHelperPoint_isForward_notBackward)) + { + DrawNonInteractableSubPointVisualizer(i, position_ofHelperPoint_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, bezierSplineDrawer_unserializedMonoB.handleSizeOf_customHandle_atHelpers, bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_helperPoints); + } + } + + void DrawNonInteractableSubPointVisualizer(int i, Vector3 position_ofSubPoint_inUnitsOfGlobalSpace, Color color, float handleSize, bool handlesAreActivated) + { + Handles.color = color; + float radius_ofSubPointIndicator = 0.5f * handleSize * HandleUtility.GetHandleSize(position_ofSubPoint_inUnitsOfGlobalSpace); + + if (handlesAreActivated == false) + { + Handles.DrawSolidDisc(position_ofSubPoint_inUnitsOfGlobalSpace, Vector3.back, radius_ofSubPointIndicator); + } + + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].isHighlighted) + { + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, BezierSplineDrawerInspector.alpha_ofExpandedNonInteractableFlatSubPointVisualizer_forHighlightedControlPoints); + Handles.DrawSolidDisc(position_ofSubPoint_inUnitsOfGlobalSpace, Vector3.back, BezierSplineDrawerInspector.sizeFactor_ofNonInteracalbeFlatSubPointVisualizer_forHighlightedPoints * radius_ofSubPointIndicator); + } + } + + bool CheckIf_drawNonInteractableHelperPointVisualizer(int i, bool concerncedHelperPoint_isForward_notBackward) + { + return bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetAHelperPoint(concerncedHelperPoint_isForward_notBackward).isUsed; + } + + void DrawIndexAsText(int i) + { + GUIStyle style_ofTextAtControlPoints = new GUIStyle(); + string space_beforeTextString = " "; + + float scaleFactorOfText = bezierSplineDrawer_unserializedMonoB.handleSizeOf_customHandle_atAnchors / BezierSplineDrawer2D.default_handleSizeOf_customHandle_atAnchors; + int scale_ofSpaceBeforeTextString = Mathf.RoundToInt(scaleFactorOfText * 11); + int scale_ofNumberItself = Mathf.RoundToInt(scaleFactorOfText * 25); + + string text_atControlPoint = "" + space_beforeTextString + "" + i + ""; + Handles.Label(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), text_atControlPoint, style_ofTextAtControlPoints); + } + + void DrawPlusButtonsForAddingNewControlPoints_atSplineStartAndEnd(int i) + { + if (bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed == false) + { + if (bezierSplineDrawer_unserializedMonoB.showHandleFor_plusButtons_atSplineStartAndEnd) + { + DrawPlusButtonsForAddingNewControlPoints_atSplineStart(i); + DrawPlusButtonsForAddingNewControlPoints_atSplineEnd(i); + } + } + } + + void DrawPlusButtonsForAddingNewControlPoints_atSplineStart(int i) + { + if (bezierSplineDrawer_unserializedMonoB.IsFirstControlPoint(i)) + { + InternalDXXL_BezierControlPointTriplet2D currControlPointTriplet = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + Vector2 currentFirstControlPoint_backTo_newlyCreatableControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_firstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized(currControlPointTriplet); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(currentFirstControlPoint_backTo_newlyCreatableControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized)) + { + currentFirstControlPoint_backTo_newlyCreatableControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized = (-bezierSplineDrawer_unserializedMonoB.Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized()); + } + Vector3 currentFirstControlPoint_backTo_newlyCreatableControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized_asV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(currentFirstControlPoint_backTo_newlyCreatableControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized); + float distanceToCurrentFirstControlPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.Get_distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace(); + Vector3 posOf_plusButtonAtSplineStart_inUnitsOfGlobalSpace = currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos() + currentFirstControlPoint_backTo_newlyCreatableControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized_asV3 * distanceToCurrentFirstControlPoint_inUnitsOfGlobalSpace; + + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, BezierSplineDrawerInspector.alphaOfSolidBackgroundLine_ofLinesTowardsPlusButtonsAtSplineEnds); + Handles.DrawLine(currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), posOf_plusButtonAtSplineStart_inUnitsOfGlobalSpace); + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, BezierSplineDrawerInspector.alphaOfDottedLine_ofLinesTowardsPlusButtonsAtSplineEnds); + Handles.DrawDottedLine(currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), posOf_plusButtonAtSplineStart_inUnitsOfGlobalSpace, dotLength_ofDottedLines); + + bool buttonHasBeenClicked = InternalDXXL_BezierHandles.PlusButton(posOf_plusButtonAtSplineStart_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.handleSizeOf_plusButtons, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, sceneViewCamForward_normalized, sceneViewCamUp_normalized, sceneViewCamRight_normalized, plusSymbolIcon); + if (buttonHasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CreateNewControlPoint_atSplineStart(); + } + } + } + + void DrawPlusButtonsForAddingNewControlPoints_atSplineEnd(int i) + { + if (bezierSplineDrawer_unserializedMonoB.IsLastControlPoint(i)) + { + InternalDXXL_BezierControlPointTriplet2D currControlPointTriplet = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + Vector2 currentLastControlPoint_to_newlyCreatableControlPoint_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized(currControlPointTriplet); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(currentLastControlPoint_to_newlyCreatableControlPoint_inUnitsOfGlobalSpace_normalized)) + { + currentLastControlPoint_to_newlyCreatableControlPoint_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + Vector3 currentLastControlPoint_to_newlyCreatableControlPoint_inUnitsOfGlobalSpace_normalized_asV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(currentLastControlPoint_to_newlyCreatableControlPoint_inUnitsOfGlobalSpace_normalized); + float distanceToCurrentLastControlPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.Get_distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace(); + Vector3 posOf_plusButtonAtSplineEnd_inUnitsOfGlobalSpace = currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos() + currentLastControlPoint_to_newlyCreatableControlPoint_inUnitsOfGlobalSpace_normalized_asV3 * distanceToCurrentLastControlPoint_inUnitsOfGlobalSpace; + + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, BezierSplineDrawerInspector.alphaOfSolidBackgroundLine_ofLinesTowardsPlusButtonsAtSplineEnds); + Handles.DrawLine(currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), posOf_plusButtonAtSplineEnd_inUnitsOfGlobalSpace); + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, BezierSplineDrawerInspector.alphaOfDottedLine_ofLinesTowardsPlusButtonsAtSplineEnds); + Handles.DrawDottedLine(currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), posOf_plusButtonAtSplineEnd_inUnitsOfGlobalSpace, dotLength_ofDottedLines); + + bool buttonHasBeenClicked = InternalDXXL_BezierHandles.PlusButton(posOf_plusButtonAtSplineEnd_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.handleSizeOf_plusButtons, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, sceneViewCamForward_normalized, sceneViewCamUp_normalized, sceneViewCamRight_normalized, plusSymbolIcon); + if (buttonHasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CreateNewControlPoint_atSplineEnd(); + } + } + } + + void DrawPlusButtonsForAddingNewControlPoints_somewhereOnUpcomingSplineSegment(int i) + { + if (bezierSplineDrawer_unserializedMonoB.showHandleFor_plusButtons_insideSegments) + { + InternalDXXL_BezierControlPointTriplet2D concernedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + if (bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed || concernedControlPoint.IsLastControlPoint() == false) + { + float pos0to1_insideSegment_ofPlusButton_beforeDrag = concernedControlPoint.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + Vector2 posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace_asV2 = concernedControlPoint.GetPosAtPlusButton_onUpcomingBezierSegment_inUnitsOfGlobalSpace(); + Vector3 posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace_asV2, bezierSplineDrawer_unserializedMonoB.GetZPos_global_for2D()); + Vector2 directionOfConeForShifting_inUnitsOfGlobalSpace_normalized = concernedControlPoint.GetTangentAtPlusButton_onUpcomingBezierSegment_inUnitsOfGlobalSpace(true); + float handleSize = bezierSplineDrawer_unserializedMonoB.handleSizeOf_plusButtons * HandleUtility.GetHandleSize(posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace); + + Handles.color = bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints; + Quaternion rotation_ofForwardCone = Quaternion.LookRotation(directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, Vector3.zero); + Quaternion rotation_ofBackwardCone = Quaternion.LookRotation(-directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, Vector3.zero); + Get_posOfPlusButtonCones(out Vector3 posOf_forwardCone_beforeDrag_inUnitsOfGlobalSpace, out Vector3 posOf_backwardCone_beforeDrag_inUnitsOfGlobalSpace, posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace, directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, handleSize); + + Start_handlesChangeCheck(); + float pos0to1_insideSegment_ofPlusButton_afterDragOfForwardCone = InternalDXXL_BezierHandles.ValueSliderAlongCurve(pos0to1_insideSegment_ofPlusButton_beforeDrag, posOf_forwardCone_beforeDrag_inUnitsOfGlobalSpace, rotation_ofForwardCone, directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, handleSize, Handles.ConeHandleCap, 1.0f); + bool forwardCone_hasChanged = End_handlesChangeCheck("Shift Button on Spline", i, false); + + Start_handlesChangeCheck(); + float pos0to1_insideSegment_ofPlusButton_afterDragOfBackwardCone = InternalDXXL_BezierHandles.ValueSliderAlongCurve(pos0to1_insideSegment_ofPlusButton_beforeDrag, posOf_backwardCone_beforeDrag_inUnitsOfGlobalSpace, rotation_ofBackwardCone, directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, handleSize, Handles.ConeHandleCap, 1.0f); + bool backwardCone_hasChanged = End_handlesChangeCheck("Shift Button on Spline", i, false); + + if (forwardCone_hasChanged) { Update_progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment(pos0to1_insideSegment_ofPlusButton_afterDragOfForwardCone, concernedControlPoint); } + if (backwardCone_hasChanged) { Update_progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment(pos0to1_insideSegment_ofPlusButton_afterDragOfBackwardCone, concernedControlPoint); } + + bool buttonHasBeenClicked = InternalDXXL_BezierHandles.PlusButton(posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.handleSizeOf_plusButtons, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, sceneViewCamForward_normalized, sceneViewCamUp_normalized, sceneViewCamRight_normalized, plusSymbolIcon); + if (buttonHasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CreateNewControlPoint_somewhereOnUpcomingSplineSegment(i); + } + } + } + } + + void Get_posOfPlusButtonCones(out Vector3 posOf_forwardCone_beforeDrag_inUnitsOfGlobalSpace, out Vector3 posOf_backwardCone_beforeDrag_inUnitsOfGlobalSpace, Vector3 posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace, Vector2 directionOfConeForShifting_inUnitsOfGlobalSpace_normalized_asV2, float handleSize) + { + Vector3 directionOfConeForShifting_inUnitsOfGlobalSpace_normalized = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(directionOfConeForShifting_inUnitsOfGlobalSpace_normalized_asV2); + + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 unused1, out Vector3 unused2, out Vector3 unused3, out Vector3 sceneViewCam_to_plusButton, posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace, DrawBasics.CameraForAutomaticOrientation.sceneViewCamera); + float acuteAngleDeg0to90_betweenObserverViewDir_andCurveTangent = UtilitiesDXXL_Math.AcuteAngle_0to90(sceneViewCam_to_plusButton, directionOfConeForShifting_inUnitsOfGlobalSpace_normalized); + acuteAngleDeg0to90_betweenObserverViewDir_andCurveTangent = Mathf.Max(acuteAngleDeg0to90_betweenObserverViewDir_andCurveTangent, 15.0f); + + float offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton = 1.0f / Mathf.Sin(acuteAngleDeg0to90_betweenObserverViewDir_andCurveTangent * Mathf.Deg2Rad); + float offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofForwardConeHandle; + float offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofBackwardConeHandle; + + bool curveDirectionGoesAwayFromSceneViewCamera = (Vector3.Dot(sceneViewCam_to_plusButton, directionOfConeForShifting_inUnitsOfGlobalSpace_normalized) > 0.0f); + if (curveDirectionGoesAwayFromSceneViewCamera) + { + offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofForwardConeHandle = 1.0f; + offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofBackwardConeHandle = offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton; + } + else + { + offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofForwardConeHandle = offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton; + offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofBackwardConeHandle = 1.0f; + } + + float relConeOffset_ifObservingCamViesPerp = 0.75f; + float offsetOfForwardConeHandle = handleSize * relConeOffset_ifObservingCamViesPerp * offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofForwardConeHandle; + float offsetOfBackwardConeHandle = handleSize * relConeOffset_ifObservingCamViesPerp * offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofBackwardConeHandle; + + posOf_forwardCone_beforeDrag_inUnitsOfGlobalSpace = posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace + directionOfConeForShifting_inUnitsOfGlobalSpace_normalized * offsetOfForwardConeHandle; + posOf_backwardCone_beforeDrag_inUnitsOfGlobalSpace = posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace - directionOfConeForShifting_inUnitsOfGlobalSpace_normalized * offsetOfBackwardConeHandle; + } + + void Update_progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment(float pos0to1_insideSegment_ofPlusButton_afterDrag, InternalDXXL_BezierControlPointTriplet2D concernedControlPoint) + { + pos0to1_insideSegment_ofPlusButton_afterDrag = Mathf.Clamp(pos0to1_insideSegment_ofPlusButton_afterDrag, 0.05f, 0.95f); + concernedControlPoint.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment = pos0to1_insideSegment_ofPlusButton_afterDrag; + } + + BezierSplineDrawerInspector.PartOfTripleHandleCompound nearest_anchorSubHandle; + BezierSplineDrawerInspector.PartOfTripleHandleCompound middle_anchorSubHandle; + BezierSplineDrawerInspector.PartOfTripleHandleCompound farest_anchorSubHandle; + + void DrawCustomHandlesAtSubPoints(int i) + { + Determine_nearestMiddleFarestSubHandle(i); + + DrawCustomHandleAtASubPoint(farest_anchorSubHandle, i); + DrawCustomHandleAtASubPoint(middle_anchorSubHandle, i); + DrawCustomHandleAtASubPoint(nearest_anchorSubHandle, i); + } + + void Determine_nearestMiddleFarestSubHandle(int i) + { + float dotProduct_camViewDir_directionOfForwardCone = Vector3.Dot(sceneViewCam_to_anchorPoint, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized); + float dotProduct_camViewDir_directionOfBackwardCone = Vector3.Dot(sceneViewCam_to_anchorPoint, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized); + + if ((dotProduct_camViewDir_directionOfForwardCone > 0.0f) && (dotProduct_camViewDir_directionOfBackwardCone > 0.0f)) + { + nearest_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.center; + if (dotProduct_camViewDir_directionOfForwardCone > dotProduct_camViewDir_directionOfBackwardCone) + { + middle_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.backward; + farest_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.forward; + } + else + { + middle_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.forward; + farest_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.backward; + } + } + else + { + if ((dotProduct_camViewDir_directionOfForwardCone < 0.0f) && (dotProduct_camViewDir_directionOfBackwardCone < 0.0f)) + { + farest_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.center; + if (dotProduct_camViewDir_directionOfForwardCone < dotProduct_camViewDir_directionOfBackwardCone) + { + nearest_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.forward; + middle_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.backward; + } + else + { + nearest_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.backward; + middle_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.forward; + } + } + else + { + middle_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.center; + if (dotProduct_camViewDir_directionOfForwardCone < 0.0f) + { + nearest_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.forward; + farest_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.backward; + } + else + { + nearest_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.backward; + farest_anchorSubHandle = BezierSplineDrawerInspector.PartOfTripleHandleCompound.forward; + } + } + } + } + + void DrawCustomHandleAtASubPoint(BezierSplineDrawerInspector.PartOfTripleHandleCompound subHandleToDraw, int i) + { + switch (subHandleToDraw) + { + case BezierSplineDrawerInspector.PartOfTripleHandleCompound.center: + DrawAnchorPointsCustomHandle(i); + break; + case BezierSplineDrawerInspector.PartOfTripleHandleCompound.forward: + DrawAHelperPointHandle(i, true); + break; + case BezierSplineDrawerInspector.PartOfTripleHandleCompound.backward: + DrawAHelperPointHandle(i, false); + break; + default: + break; + } + } + + void DrawAnchorPointsCustomHandle(int i) + { + if (bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_anchorPoints) + { + Handles.color = bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints; + + float size_ofAnchorPointsCustomHandle = bezierSplineDrawer_unserializedMonoB.handleSizeOf_customHandle_atAnchors * HandleUtility.GetHandleSize(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()); + + bool drawForwardCone_ofAnchorPointsCustomHandle = CheckIf_drawForwardCone_ofAnchorPointsCustomHandle(i); + bool drawBackwardCone_ofAnchorPointsCustomHandle = CheckIf_drawBackwardCone_ofAnchorPointsCustomHandle(i); + + if (drawForwardCone_ofAnchorPointsCustomHandle) { TryRecalcHandleDirectionOfForwardConeOnAnchorHandle(i); } + if (drawBackwardCone_ofAnchorPointsCustomHandle) { TryRecalcHandleDirectionOfBackwardConeOnAnchorHandle(i); } + + bool flipBackwardCone_dueToIsLastControlPointOfNonClosedSpline = FlipDirectionOfAnchorPointsCustomHandleBackwardCone(i); + if (flipBackwardCone_dueToIsLastControlPointOfNonClosedSpline) + { + //-> "forward cone" (whichever of the three handles it may be) is always skipped here + //-> so this just flips the draw order of the remaining two subHandles: sphere and the backward cone + DrawASubHandle_ofAnchorPointsCustomHandle(nearest_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + DrawASubHandle_ofAnchorPointsCustomHandle(middle_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + DrawASubHandle_ofAnchorPointsCustomHandle(farest_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + } + else + { + DrawASubHandle_ofAnchorPointsCustomHandle(farest_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + DrawASubHandle_ofAnchorPointsCustomHandle(middle_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + DrawASubHandle_ofAnchorPointsCustomHandle(nearest_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + } + } + } + + bool CheckIf_drawForwardCone_ofAnchorPointsCustomHandle(int i) + { + if ((bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed == false) && bezierSplineDrawer_unserializedMonoB.IsLastControlPoint(i)) + { + return false; + } + return true; + } + + void TryRecalcHandleDirectionOfForwardConeOnAnchorHandle(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_forwardCone_duringNextOnSceneGUI) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.isUsed) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + } + else + { + InternalDXXL_BezierControlSubPoint2D nextUsedNonSuperimposedSubPointAlongSplineDir = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + if (nextUsedNonSuperimposedSubPointAlongSplineDir != null) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized = (nextUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace() - bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace()).normalized; + } + else + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + } + } + } + + bool CheckIf_drawBackwardCone_ofAnchorPointsCustomHandle(int i) + { + if ((bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed == false) && (bezierSplineDrawer_unserializedMonoB.IsFirstControlPoint(i))) + { + return false; + } + + //note 1: for non-kinked juncture types the backwardHelper cannot be disabled (meaning "isUsed == true" is always guaranteed). Therefore the backward direction cone is always redundant and can be skipped, because it is the same as the forward direction. + //note 2: the one case, where no forward direction for non-kinked juncture-types would be possible is the splineEnd of non-closed splines. But such spline end points are always forced to "juncture=kinked", and therefore don't need special treatment here + return (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + } + + void TryRecalcHandleDirectionOfBackwardConeOnAnchorHandle(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_backwardCone_duringNextOnSceneGUI) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.isUsed) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + } + else + { + InternalDXXL_BezierControlSubPoint2D previousUsedNonSuperimposedSubPointAlongSplineDir = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + if (previousUsedNonSuperimposedSubPointAlongSplineDir != null) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized = (previousUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace() - bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace()).normalized; + } + else + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized = (-bezierSplineDrawer_unserializedMonoB.Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized()); + } + } + } + } + + void DrawASubHandle_ofAnchorPointsCustomHandle(BezierSplineDrawerInspector.PartOfTripleHandleCompound subHandleToDraw, int i, bool drawForwardCone_ofAnchorPointsCustomHandle, bool drawBackwardCone_ofAnchorPointsCustomHandle, float size_ofAnchorPointsCustomHandle) + { + switch (subHandleToDraw) + { + case BezierSplineDrawerInspector.PartOfTripleHandleCompound.center: + DrawAnchorPointsCustomHandles_freeMoveSubHandle(i, size_ofAnchorPointsCustomHandle); + break; + case BezierSplineDrawerInspector.PartOfTripleHandleCompound.forward: + if (drawForwardCone_ofAnchorPointsCustomHandle) { DrawAnchorPointsCustomHandles_forwardConeSubHandle(i, size_ofAnchorPointsCustomHandle); } + break; + case BezierSplineDrawerInspector.PartOfTripleHandleCompound.backward: + if (drawBackwardCone_ofAnchorPointsCustomHandle) { DrawAnchorPointsCustomHandles_backwardConeSubHandle(i, size_ofAnchorPointsCustomHandle); } + break; + default: + break; + } + } + + void DrawAnchorPointsCustomHandles_freeMoveSubHandle(int i, float size_ofAnchorPointsCustomHandle) + { + Start_handlesChangeCheck(); + Vector3 pos_shiftedByFreeMoveHandle_inUnitsOfGlobalSpace = Handles.Slider2D(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.controlID_ofCustomHandles_sphere, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), Vector3.back, Vector3.up, Vector3.right, size_ofAnchorPointsCustomHandle, Handles.SphereHandleCap, Vector2.one); + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (hasChanged) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.SetPos_inUnitsOfGlobalSpace(pos_shiftedByFreeMoveHandle_inUnitsOfGlobalSpace, true, null); + } + } + + void DrawAnchorPointsCustomHandles_forwardConeSubHandle(int i, float size_ofAnchorPointsCustomHandle) + { + Vector3 posOffset_fromAnchorPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized * size_ofAnchorPointsCustomHandle; + Vector3 pos_ofForwardCone_beforeDrag_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos() + posOffset_fromAnchorPoint_inUnitsOfGlobalSpace; + + Start_handlesChangeCheck(); + Vector3 pos_ofForwardCone_afterDrag_inUnitsOfGlobalSpace = Handles.Slider(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.controlID_ofCustomHandles_forwardCone, pos_ofForwardCone_beforeDrag_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized, size_ofAnchorPointsCustomHandle, Handles.ConeHandleCap, 1.0f); + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (hasChanged) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_forwardCone_duringNextOnSceneGUI = false; //Without this there is strange flickering behaviour, see notes at "recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = false" + Vector3 posDifference_inUnitsOfGlobalSpace = pos_ofForwardCone_afterDrag_inUnitsOfGlobalSpace - pos_ofForwardCone_beforeDrag_inUnitsOfGlobalSpace; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.AddPosOffset_inUnitsOfGlobalSpace(posDifference_inUnitsOfGlobalSpace, true, null); + } + } + + void DrawAnchorPointsCustomHandles_backwardConeSubHandle(int i, float size_ofAnchorPointsCustomHandle) + { + bool flipDirectionOfCone = FlipDirectionOfAnchorPointsCustomHandleBackwardCone(i); + Vector3 posOffset_fromAnchorPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized * size_ofAnchorPointsCustomHandle; + if (flipDirectionOfCone) { posOffset_fromAnchorPoint_inUnitsOfGlobalSpace = -posOffset_fromAnchorPoint_inUnitsOfGlobalSpace; } + Vector3 pos_ofBackwardCone_beforeDrag_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos() + posOffset_fromAnchorPoint_inUnitsOfGlobalSpace; + Vector3 usedDirection_inUnitsOfGlobalSpace = flipDirectionOfCone ? (-bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized) : bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized; + + Start_handlesChangeCheck(); + Vector3 pos_ofBackwardCone_afterDrag_inUnitsOfGlobalSpace = Handles.Slider(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.controlID_ofCustomHandles_backwardCone, pos_ofBackwardCone_beforeDrag_inUnitsOfGlobalSpace, usedDirection_inUnitsOfGlobalSpace, size_ofAnchorPointsCustomHandle, Handles.ConeHandleCap, 1.0f); + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (hasChanged) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_backwardCone_duringNextOnSceneGUI = false; //Without this there is strange flickering behaviour, see notes at "recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = false" + Vector3 posDifference_inUnitsOfGlobalSpace = pos_ofBackwardCone_afterDrag_inUnitsOfGlobalSpace - pos_ofBackwardCone_beforeDrag_inUnitsOfGlobalSpace; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.AddPosOffset_inUnitsOfGlobalSpace(posDifference_inUnitsOfGlobalSpace, true, null); + } + } + + bool FlipDirectionOfAnchorPointsCustomHandleBackwardCone(int i) + { + //-> this is only for visual continuity (because the default case is that the conesAtAnchorHandles point along forwardOfSpline). + if (bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed == false) + { + if (bezierSplineDrawer_unserializedMonoB.IsLastControlPoint(i)) + { + return true; + } + } + return false; + } + + BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle nearest_helperSubHandle; + BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle secondNearest_helperSubHandle; + BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle middle_helperSubHandle; + BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle secondFarest_helperSubHandle; + BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle farest_helperSubHandle; + bool nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints; + bool secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints; + bool secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints; + bool farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints; + void DrawAHelperPointHandle(int i, bool helperHandleToDraw_isForwardNotBackward) + { + if (bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_helperPoints) + { + InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetAHelperPoint(helperHandleToDraw_isForwardNotBackward); + if (concernedHelperPoint.isUsed) + { + Handles.color = bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints; + + bool draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor = CheckIf_draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor(i, concernedHelperPoint); + bool draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir = CheckIf_draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir(i, concernedHelperPoint); + + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_helperPosition, concernedHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), DrawBasics.CameraForAutomaticOrientation.sceneViewCamera); + + TryRecalc_directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized(concernedHelperPoint); + TryRecalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized(i, concernedHelperPoint); + + Determine_nearestMiddleAndFarestSubHandles_ofHelperPointsCustomHandle(concernedHelperPoint, cam_to_helperPosition); + + DrawASubHandle_ofHelperPointsCustomHandle(farest_helperSubHandle, farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, i, draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, concernedHelperPoint); + DrawASubHandle_ofHelperPointsCustomHandle(secondFarest_helperSubHandle, secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, i, draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, concernedHelperPoint); + DrawASubHandle_ofHelperPointsCustomHandle(middle_helperSubHandle, false, i, draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, concernedHelperPoint); + DrawASubHandle_ofHelperPointsCustomHandle(secondNearest_helperSubHandle, secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, i, draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, concernedHelperPoint); + DrawASubHandle_ofHelperPointsCustomHandle(nearest_helperSubHandle, nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, i, draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, concernedHelperPoint); + } + } + } + + bool CheckIf_draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor(int i, InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint) + { + if (concernedHelperPoint.GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + return false; + } + else + { + return (concernedHelperPoint.GetOppositeHelperPoint().isUsed); + } + } + + bool CheckIf_draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir(int i, InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint) + { + InternalDXXL_BezierControlPointTriplet2D neighboringControlPoint = concernedHelperPoint.Get_neighboringControlPoint(false); + if (neighboringControlPoint != null) + { + if (concernedHelperPoint.isForward_notBackward) + { + return neighboringControlPoint.backwardHelperPoint.isUsed; + } + else + { + return neighboringControlPoint.forwardHelperPoint.isUsed; + } + } + else + { + return false; + } + } + + void TryRecalc_directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized(InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint) + { + if (concernedHelperPoint.recalc_directionForHandles_alongLineWithMountingAnchor_duringNextOnSceneGUI) + { + if (concernedHelperPoint.isForward_notBackward) + { + concernedHelperPoint.directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = concernedHelperPoint.Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + } + else + { + concernedHelperPoint.directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = -concernedHelperPoint.Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + } + } + } + + void TryRecalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized(int i, InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint) + { + if (concernedHelperPoint.recalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_duringNextOnSceneGUI) + { + if (concernedHelperPoint.isForward_notBackward) + { + InternalDXXL_BezierControlSubPoint2D nextUsedNonSuperimposedSubPointAlongSplineDir = concernedHelperPoint.GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + + if (nextUsedNonSuperimposedSubPointAlongSplineDir != null) + { + concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = (nextUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace_asV3DrawPos() - concernedHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()).normalized; + } + else + { + concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + } + else + { + InternalDXXL_BezierControlSubPoint2D previousUsedNonSuperimposedSubPointAlongSplineDir = concernedHelperPoint.GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + if (previousUsedNonSuperimposedSubPointAlongSplineDir != null) + { + concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = (concernedHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos() - previousUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()).normalized; + } + else + { + concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + } + } + } + + void Determine_nearestMiddleAndFarestSubHandles_ofHelperPointsCustomHandle(InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint, Vector3 cam_to_helperPosition) + { + middle_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.sphere; + + float dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor = Vector3.Dot(cam_to_helperPosition, concernedHelperPoint.directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized); + float dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir = Vector3.Dot(cam_to_helperPosition, concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized); + if ((dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor > 0.0f) && (dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir > 0.0f)) + { + //both dirs point AWAY from camera: + if (dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor > dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir) + { + //"dirAlongLineWithAnchor" points STEEPER away from camera than "dir_toNeighborOfNeighbor": + nearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + secondNearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + secondFarest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + farest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + } + else + { + //"dir_toNeighborOfNeighbor" points STEEPER away from camera than "dirAlongLineWithAnchor": + nearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + secondNearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + secondFarest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + farest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + } + } + else + { + if ((dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor < 0.0f) && (dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir < 0.0f)) + { + //both dirs point TOWARDS camera: + if (dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor < dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir) + { + //"dirAlongLineWithAnchor" points STEEPER towards camera than "dir_toNeighborOfNeighbor": + nearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + secondNearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + secondFarest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + farest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + } + else + { + //"dir_toNeighborOfNeighbor" points STEEPER towards camera than "dirAlongLineWithAnchor": + nearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + secondNearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + secondFarest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + farest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + } + } + else + { + if ((dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor > 0.0f) && (dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir < 0.0f)) + { + //"dirAlongLineWithAnchor" points AWAY from camera, "dir_toNeighborOfNeighbor" points TOWARDS camera: + float abs_dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir = -dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir; + if (dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor > abs_dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir) + { + //"dirAlongLineWithAnchor" points STEEPER away from camera than "(cylinder)dir_toNeighborOfNeighbor": + nearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + secondNearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + secondFarest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + farest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + } + else + { + //"(cylinder)dir_toNeighborOfNeighbor" points STEEPER away from camera than "dirAlongLineWithAnchor": + nearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + secondNearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + secondFarest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + farest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + } + } + else + { + //"dirAlongLineWithAnchor" points TOWARDS camera, "dir_toNeighborOfNeighbor" points AWAY from camera: + float abs_dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor = -dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor; + if (abs_dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor > dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir) + { + //"(cylinder)dirAlongLineWithAnchor" points STEEPER away from camera than "dir_toNeighborOfNeighbor": + nearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + secondNearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + secondFarest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + farest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + } + else + { + //"dir_toNeighborOfNeighbor" points STEEPER away from camera than "(cylinder)dirAlongLineWithAnchor": + nearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + secondNearest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + secondFarest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + farest_helperSubHandle = BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + } + } + } + } + } + + void DrawASubHandle_ofHelperPointsCustomHandle(BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle subHandleToDraw, bool belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, int i, bool draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, bool draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint) + { + float handleSize_unmodified = bezierSplineDrawer_unserializedMonoB.handleSizeOf_customHandle_atHelpers * HandleUtility.GetHandleSize(concernedHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()); + switch (subHandleToDraw) + { + case BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.sphere: + DrawHelperPointsCustomHandles_sphereHandle(i, concernedHelperPoint.controlID_ofCustomHandles_sphere, concernedHelperPoint, handleSize_unmodified); + break; + case BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor: + DrawAnUnidirectionalSubHandle_ofHelperPointsCustomHandle(i, concernedHelperPoint.controlID_ofCustomHandles_coneAlongLineWithAnchor, concernedHelperPoint, 1.0f, handleSize_unmodified, Handles.ConeHandleCap, belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, true, false, false); + break; + case BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir: + DrawAnUnidirectionalSubHandle_ofHelperPointsCustomHandle(i, concernedHelperPoint.controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper, concernedHelperPoint, 1.0f, handleSize_unmodified, Handles.ConeHandleCap, belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, false, false, false); + break; + case BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor: + if (draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor) + { + DrawAnUnidirectionalSubHandle_ofHelperPointsCustomHandle(i, concernedHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithAnchor, concernedHelperPoint, -1.0f * BezierSplineDrawerInspector.offsetFactor_forCylinderHandles, BezierSplineDrawerInspector.scaleFactor_forCylinderHandles * handleSize_unmodified, Handles.CylinderHandleCap, belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, false, true, false); + } + break; + case BezierSplineDrawerInspector.PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir: + if (draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir) + { + DrawAnUnidirectionalSubHandle_ofHelperPointsCustomHandle(i, concernedHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper, concernedHelperPoint, -1.0f * BezierSplineDrawerInspector.offsetFactor_forCylinderHandles, BezierSplineDrawerInspector.scaleFactor_forCylinderHandles * handleSize_unmodified, Handles.CylinderHandleCap, belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, false, false, true); + } + break; + default: + break; + } + } + + void DrawHelperPointsCustomHandles_sphereHandle(int i, int controlID_ofHandle, InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint, float handleSize) + { + Start_handlesChangeCheck(); + Vector3 posOfSphereHandle_afterDrag_shifedInsideCamPlane_inUnitsOfGlobalSpace = Handles.Slider2D(controlID_ofHandle, concernedHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), Vector3.back, Vector3.up, Vector3.right, handleSize, Handles.SphereHandleCap, Vector2.one); + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (hasChanged) + { + concernedHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfSphereHandle_afterDrag_shifedInsideCamPlane_inUnitsOfGlobalSpace, true, null); + } + } + + void DrawAnUnidirectionalSubHandle_ofHelperPointsCustomHandle(int i, int controlID_ofHandle, InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint, float handlePosOffsetFactorAlongDir, float handleSize, Handles.CapFunction capFunction, bool belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, bool tryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint, bool mirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint, bool mirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint) + { + Vector3 dragDirection_inUnitsOfGlobalSpace_normalized = belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints ? concernedHelperPoint.directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized : concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized; + Vector3 handleOffset = dragDirection_inUnitsOfGlobalSpace_normalized * handleSize * handlePosOffsetFactorAlongDir; + Vector3 posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace = concernedHelperPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + Vector3 posOfConeHandle_beforeDrag_inUnitsOfGlobalSpace = posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace + handleOffset; + + Start_handlesChangeCheck(); + Vector3 posOfConeHandle_afterDrag_inUnitsOfGlobalSpace = Handles.Slider(controlID_ofHandle, posOfConeHandle_beforeDrag_inUnitsOfGlobalSpace, dragDirection_inUnitsOfGlobalSpace_normalized, handleSize, capFunction, 1.0f); + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (hasChanged) + { + if (belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints) + { + concernedHelperPoint.recalc_directionForHandles_alongLineWithMountingAnchor_duringNextOnSceneGUI = false; + } + else + { + concernedHelperPoint.recalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_duringNextOnSceneGUI = false; + } + + Vector3 shiftOffset_throughDragSlider_inUnitsOfGlobalSpace = posOfConeHandle_afterDrag_inUnitsOfGlobalSpace - posOfConeHandle_beforeDrag_inUnitsOfGlobalSpace; + Vector3 posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace = posOfConeHandle_afterDrag_inUnitsOfGlobalSpace - handleOffset; + + TryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint(concernedHelperPoint, tryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint, posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace, posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace); + + float absDistanceToMountingAnchorPoint_beforeDrag_inUnitsOfGlobalSpace = concernedHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + concernedHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace, true, null); + float absDistanceToMountingAnchorPoint_afterDrag_inUnitsOfGlobalSpace = concernedHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + + TryMirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint(concernedHelperPoint, mirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint, absDistanceToMountingAnchorPoint_beforeDrag_inUnitsOfGlobalSpace, absDistanceToMountingAnchorPoint_afterDrag_inUnitsOfGlobalSpace); + TryMirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint(i, concernedHelperPoint, mirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint, shiftOffset_throughDragSlider_inUnitsOfGlobalSpace); + } + } + + void TryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint(InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint, bool tryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint, Vector3 posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace, Vector3 posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace) + { + if (tryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint) + { + if (concernedHelperPoint.isUsed && concernedHelperPoint.GetOppositeHelperPoint().isUsed) + { + if (concernedHelperPoint.GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned) + { + Vector2 posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace_asV2 = posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace; + Vector2 posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace_asV2 = posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace; + Vector3 anchor_to_helperPosBeforeDrag = posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace_asV2 - concernedHelperPoint.GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace(); + Vector3 anchor_to_helperPosAfterDrag = posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace_asV2 - concernedHelperPoint.GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace(); + float dotProduct_ofDirectionFromAnchorToConcernedHelper_beforeAndAfterDrag = Vector3.Dot(anchor_to_helperPosBeforeDrag, anchor_to_helperPosAfterDrag); + bool coneSliderPassedTheMountingAnchorPoint = (dotProduct_ofDirectionFromAnchorToConcernedHelper_beforeAndAfterDrag < 0.0f); + if (coneSliderPassedTheMountingAnchorPoint) + { + concernedHelperPoint.Get_controlPointTriplet_thisSubPointIsPartOf().Invert_alignedHelperPoints_areOnTheSameSideOfTheAnchor(); + } + } + } + } + } + + void TryMirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint(InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint, bool mirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint, float absDistanceToMountingAnchorPoint_beforeDrag_inUnitsOfGlobalSpace, float absDistanceToMountingAnchorPoint_afterDrag_inUnitsOfGlobalSpace) + { + if (mirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint) + { + float absChangeRatio_ofDistance_throughSliderDrag = absDistanceToMountingAnchorPoint_afterDrag_inUnitsOfGlobalSpace / absDistanceToMountingAnchorPoint_beforeDrag_inUnitsOfGlobalSpace; + if (UtilitiesDXXL_Math.FloatIsValid(absChangeRatio_ofDistance_throughSliderDrag)) + { + float newAbsDistanceToAnchorPoint_ofOppositeHelperPoint_inUnitsOfGlobalSpace = concernedHelperPoint.GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace() * absChangeRatio_ofDistance_throughSliderDrag; + concernedHelperPoint.GetOppositeHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistanceToAnchorPoint_ofOppositeHelperPoint_inUnitsOfGlobalSpace, true, null); //-> oppositeHelperPoint is guaranteed "isUsed = true" here + //bool cylinderSliderPassedTheMountingAnchorPoint -> No further action required because "concernedHelperPoint.SetPos_inUnitsOfGlobalSpace()" already executed the "flip" of the other helper side. + } + } + } + + void TryMirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint(int i, InternalDXXL_BezierControlHelperSubPoint2D concernedHelperPoint, bool mirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint, Vector3 shiftOffset_throughDragSlider_inUnitsOfGlobalSpace) + { + if (mirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint) + { + InternalDXXL_BezierControlHelperSubPoint2D neighboringHelperPoint_ofNeighboringControlPoint = concernedHelperPoint.Get_neighboringHelperPoint_ofNeighboringControlPoint(false); + if (neighboringHelperPoint_ofNeighboringControlPoint != null) + { + neighboringHelperPoint_ofNeighboringControlPoint.AddPosOffset_inUnitsOfGlobalSpace(-shiftOffset_throughDragSlider_inUnitsOfGlobalSpace, true, null); + } + } + } + + void DrawUnitysBuildInHandlesAtSubPoints(int i) + { + //Could be improved: The handles here in the 2D version could be drawn "back-to-front"-order as "DrawCustomHandlesAtSubPoints()" does, because here custom handles are used and not Unitys build-in PositionHandle and RotatoinHandle (see explanation in the corresponding function of the 3D-version) + //Though in 2D it is anyway not as important, because all handles lie in a plane and therefore the readability what's "nearer or farer" is anyway clearer. + InternalDXXL_BezierControlPointTriplet2D concernedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + TryDrawAUnityRotationHandle(i); + TryDrawAUnityPositionHandle(i, concernedControlPoint.backwardHelperPoint); + TryDrawAUnityPositionHandle(i, concernedControlPoint.forwardHelperPoint); + TryDrawAUnityPositionHandle(i, concernedControlPoint.anchorPoint); + } + + void TryDrawAUnityPositionHandle(int i, InternalDXXL_BezierControlSubPoint2D concernedSubPoint) + { + if (CheckIf_drawPositionHandle(concernedSubPoint)) + { + if (concernedSubPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI) { Recalc_globalRotation_ofPositionHandle(concernedSubPoint); } + + float handleSizeFactor = (concernedSubPoint.subPointType == InternalDXXL_BezierControlSubPoint.SubPointType.anchor) ? bezierSplineDrawer_unserializedMonoB.handleSizeFor_position_atAnchors : bezierSplineDrawer_unserializedMonoB.handleSizeFor_position_atHelpers; + float handleSize = handleSizeFactor * HandleUtility.GetHandleSize(concernedSubPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()); + + Vector3 direction_ofUpHandle = concernedSubPoint.globalRotation_ofPositionHandle * Vector3.up; + Handles.color = Handles.yAxisColor; + + Start_handlesChangeCheck(); + Vector3 pos_shiftedByPositionUpHandle_inUnitsOfGlobalSpace = Handles.Slider(concernedSubPoint.controlID_ofUnityStylePositionHandleUp, concernedSubPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), direction_ofUpHandle, handleSize, Handles.ArrowHandleCap, 1.0f); + bool up_hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + Vector3 direction_ofRightHandle = concernedSubPoint.globalRotation_ofPositionHandle * Vector3.right; + Handles.color = Handles.xAxisColor; + + Start_handlesChangeCheck(); + Vector3 pos_shiftedByPositionRightHandle_inUnitsOfGlobalSpace = Handles.Slider(concernedSubPoint.controlID_ofUnityStylePositionHandleRight, concernedSubPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), direction_ofRightHandle, handleSize, Handles.ArrowHandleCap, 1.0f); + bool right_hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (up_hasChanged) + { + concernedSubPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = false; //Without this there is strange flickering behaviour, maybe due to some internals of how "Handles.PositionHandle()" works. The flickering appears for "Editor.pivotMode=local" when you grab a the position handle that points to the neighboring control point and then get nearer towards this other control point. + concernedSubPoint.SetPos_inUnitsOfGlobalSpace(pos_shiftedByPositionUpHandle_inUnitsOfGlobalSpace, true, null); + } + + if (right_hasChanged) + { + concernedSubPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = false; //Without this there is strange flickering behaviour, maybe due to some internals of how "Handles.PositionHandle()" works. The flickering appears for "Editor.pivotMode=local" when you grab a the position handle that points to the neighboring control point and then get nearer towards this other control point. + concernedSubPoint.SetPos_inUnitsOfGlobalSpace(pos_shiftedByPositionRightHandle_inUnitsOfGlobalSpace, true, null); + } + } + } + + bool CheckIf_drawPositionHandle(InternalDXXL_BezierControlSubPoint2D concernedSubPoint) + { + if (concernedSubPoint.subPointType == InternalDXXL_BezierControlSubPoint.SubPointType.anchor) + { + return (bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atAnchors && concernedSubPoint.isUsed); + } + else + { + return (bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atHelpers && concernedSubPoint.isUsed); + } + } + + void Recalc_globalRotation_ofPositionHandle(InternalDXXL_BezierControlSubPoint2D concernedSubPoint) + { + switch (Tools.pivotRotation) + { + case PivotRotation.Local: + concernedSubPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (concernedSubPoint.boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled && (concernedSubPoint.subPointType == InternalDXXL_BezierControlSubPoint.SubPointType.anchor)) + { + if (UtilitiesDXXL_EngineBasics.CheckIfThisOrAParentHasANonZRotation_2D(concernedSubPoint.boundGameobject.transform)) + { + Recalc_globalRotation_ofPositionHandle_caseLocalPivotWithoutBoundGameobject(concernedSubPoint); + } + else + { + concernedSubPoint.globalRotation_ofPositionHandle = concernedSubPoint.boundGameobject.transform.rotation; + } + } + else + { + Recalc_globalRotation_ofPositionHandle_caseLocalPivotWithoutBoundGameobject(concernedSubPoint); + } + break; + case PivotRotation.Global: + Recalc_globalRotation_ofPositionHandle_caseGlobalPivot(concernedSubPoint); + break; + default: + break; + } + } + + void Recalc_globalRotation_ofPositionHandle_caseLocalPivotWithoutBoundGameobject(InternalDXXL_BezierControlSubPoint2D concernedSubPoint) + { + Vector3 posOfConcernedSubPoint_inUnitsOfGlobalSpace = concernedSubPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + Vector3 posOfNextNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace = posOfConcernedSubPoint_inUnitsOfGlobalSpace; + Vector3 posOfPreviousNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace = posOfConcernedSubPoint_inUnitsOfGlobalSpace; + bool the3MountingPointsLieOnALine_soThePlaneIsUndefined = false; + + InternalDXXL_BezierControlSubPoint2D nextUsedNonSuperimposedSubPointAlongSplineDir = concernedSubPoint.GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + if (nextUsedNonSuperimposedSubPointAlongSplineDir != null) + { + posOfNextNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace = nextUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + } + else + { + the3MountingPointsLieOnALine_soThePlaneIsUndefined = true; + } + + InternalDXXL_BezierControlSubPoint2D previousUsedNonSuperimposedSubPointAlongSplineDir = concernedSubPoint.GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + if (previousUsedNonSuperimposedSubPointAlongSplineDir != null) + { + posOfPreviousNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace = previousUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(); + } + else + { + the3MountingPointsLieOnALine_soThePlaneIsUndefined = true; + } + + Vector3 normalOfPlane_inUnitsOfGlobalSpace_notNormalized = Vector3.forward; + if (the3MountingPointsLieOnALine_soThePlaneIsUndefined == false) + { + Vector3 planeMountingVector1_inUnitsOfGlobalSpace = posOfConcernedSubPoint_inUnitsOfGlobalSpace - posOfNextNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace; + Vector3 planeMountingVector2_inUnitsOfGlobalSpace = posOfConcernedSubPoint_inUnitsOfGlobalSpace - posOfPreviousNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace; + normalOfPlane_inUnitsOfGlobalSpace_notNormalized = Vector3.Cross(planeMountingVector1_inUnitsOfGlobalSpace, planeMountingVector2_inUnitsOfGlobalSpace); + + the3MountingPointsLieOnALine_soThePlaneIsUndefined = (UtilitiesDXXL_Math.GetBiggestAbsComponent(normalOfPlane_inUnitsOfGlobalSpace_notNormalized) < 0.001f); + } + + if (the3MountingPointsLieOnALine_soThePlaneIsUndefined) + { + Vector3 forwardDirectionPreferablyAlongHandleAxis_inUnitsOfGlobalSpace = concernedSubPoint.GetDirectionAlongSplineForwardBasedOnNeighborPoints_inUnitsOfGlobalSpace(); + if (UtilitiesDXXL_Math.ApproximatelyZero(forwardDirectionPreferablyAlongHandleAxis_inUnitsOfGlobalSpace)) + { + Recalc_globalRotation_ofPositionHandle_caseGlobalPivot(concernedSubPoint); + } + else + { + Vector3 up_ofCreatedRotation = Vector3.Cross(Vector3.forward, forwardDirectionPreferablyAlongHandleAxis_inUnitsOfGlobalSpace); + concernedSubPoint.globalRotation_ofPositionHandle = Quaternion.LookRotation(Vector3.forward, up_ofCreatedRotation); + } + } + else + { + Vector3 rotation_forward = normalOfPlane_inUnitsOfGlobalSpace_notNormalized; + Vector3 rotation_up = posOfNextNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace - posOfPreviousNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace; + concernedSubPoint.globalRotation_ofPositionHandle = Quaternion.LookRotation(rotation_forward, rotation_up); + } + } + + void Recalc_globalRotation_ofPositionHandle_caseGlobalPivot(InternalDXXL_BezierControlSubPoint2D concernedSubPoint) + { + switch (bezierSplineDrawer_unserializedMonoB.drawSpace) + { + case BezierSplineDrawer.DrawSpace.global: + concernedSubPoint.globalRotation_ofPositionHandle = Quaternion.identity; + break; + case BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject: + Recalc_globalRotation_ofPositionHandle_caseGlobalPivotButLocalDrawSpace(concernedSubPoint); + break; + default: + break; + } + } + + void Recalc_globalRotation_ofPositionHandle_caseGlobalPivotButLocalDrawSpace(InternalDXXL_BezierControlSubPoint2D concernedSubPoint) + { + switch (bezierSplineDrawer_unserializedMonoB.positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal) + { + case BezierSplineDrawer.PositionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal.localDrawSpace: + concernedSubPoint.globalRotation_ofPositionHandle = bezierSplineDrawer_unserializedMonoB.transform.rotation; + break; + case BezierSplineDrawer.PositionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal.globalSpace: + concernedSubPoint.globalRotation_ofPositionHandle = Quaternion.identity; + break; + default: + break; + } + } + + void TryDrawAUnityRotationHandle(int i) + { + InternalDXXL_BezierControlPointTriplet2D concernedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + if (CheckIf_drawRotationHandle(concernedControlPoint)) + { + InternalDXXL_BezierControlAnchorSubPoint2D concernedAnchorPoint = concernedControlPoint.anchorPoint; + float handleSize = bezierSplineDrawer_unserializedMonoB.handleSizeFor_rotation * HandleUtility.GetHandleSize(concernedAnchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos()); + + if (concernedAnchorPoint.recalc_rotation_ofRotationHandleDuringRotationDragPhases_duringNextOnSceneGUI) { concernedAnchorPoint.rotation_ofRotationHandleDuringRotationDragPhases = Quaternion.identity; } + + Handles.color = Handles.zAxisColor; + + Start_handlesChangeCheck(); + Quaternion rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace = Handles.Disc(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.controlID_ofUnityStyleRotationHandle2D, concernedAnchorPoint.rotation_ofRotationHandleDuringRotationDragPhases, concernedAnchorPoint.GetPos_inUnitsOfGlobalSpace_asV3DrawPos(), Vector3.forward, handleSize, false, 1.0f); + bool hasChanged = End_handlesChangeCheck("Rotation of Bezier Point", i, true); + + if (hasChanged) + { + concernedAnchorPoint.recalc_rotation_ofRotationHandleDuringRotationDragPhases_duringNextOnSceneGUI = false; + Set_rotation_afterChangeThroughRotationHandle(rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, concernedAnchorPoint.rotation_ofRotationHandleDuringRotationDragPhases, concernedAnchorPoint); + concernedAnchorPoint.rotation_ofRotationHandleDuringRotationDragPhases = rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace; + } + } + } + + bool CheckIf_drawRotationHandle(InternalDXXL_BezierControlPointTriplet2D concernedControlPoint) + { + if (bezierSplineDrawer_unserializedMonoB.showHandleFor_rotation) + { + return (concernedControlPoint.forwardHelperPoint.isUsed || concernedControlPoint.backwardHelperPoint.isUsed); + } + else + { + return false; + } + } + + void Set_rotation_afterChangeThroughRotationHandle(Quaternion rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, Quaternion rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, InternalDXXL_BezierControlAnchorSubPoint2D concernedAnchorPoint) + { + Quaternion rotationIncrement = GetRotationIncrement(rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace); + + if (concernedAnchorPoint.junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + if (concernedAnchorPoint.GetBackwardHelperPoint().isUsed) + { + concernedAnchorPoint.AddRotation_toBackwardDirection(rotationIncrement, true, null); + } + + if (concernedAnchorPoint.GetForwardHelperPoint().isUsed) + { + concernedAnchorPoint.AddRotation_toForwardDirection(rotationIncrement, true, null); + } + } + else + { + if (concernedAnchorPoint.GetForwardHelperPoint().isUsed) + { + concernedAnchorPoint.AddRotation_toForwardDirection(rotationIncrement, true, null); + } + else + { + if (concernedAnchorPoint.GetBackwardHelperPoint().isUsed) + { + concernedAnchorPoint.AddRotation_toBackwardDirection(rotationIncrement, true, null); + } + } + } + } + + Quaternion GetRotationIncrement(Quaternion rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, Quaternion rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace) + { + Quaternion rotationIncrement = rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace * Quaternion.Inverse(rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace); + rotationIncrement.Normalize(); //-> the quaternion difference multiplication seems to introduce non-normalized quaternions somehow, therefore normalizing here. + return rotationIncrement; + } + + void Reset_recalculationFlags_duringNoHandleClickedOrDraggedPhases(int i) + { + if (GUIUtility.hotControl == 0) //-> no handle is selcted or dragged = mouse button is not held down + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_forwardCone_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_backwardCone_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_rotation_ofRotationHandleDuringRotationDragPhases_duringNextOnSceneGUI = true; + + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.recalc_directionForHandles_alongLineWithMountingAnchor_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.recalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_duringNextOnSceneGUI = true; + + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.recalc_directionForHandles_alongLineWithMountingAnchor_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.recalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_duringNextOnSceneGUI = true; + + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = true; + } + } + + void ResetUndoRegistrationFlag_duringNoInteractionPhases() + { + if (GUIUtility.hotControl == 0) //-> no handle is selcted or dragged = mouse button is not held down + { + hasRegisteredUndo_sinceMouseDown = false; + } + } + + void Start_handlesChangeCheck() + { + EditorGUI.BeginChangeCheck(); + } + + bool End_handlesChangeCheck(string nameOfUndoEntry, int i_controlPointWithInteraction, bool markConcernedControlPoint_asSelected) + { + bool hasChanged = EditorGUI.EndChangeCheck(); + if (hasChanged) + { + TryRegisterStateForUndo(nameOfUndoEntry, true, false); + if (markConcernedControlPoint_asSelected) + { + bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i_controlPointWithInteraction); + } + } + return hasChanged; + } + + void TryRegisterStateForUndo(string nameOfUndoEntry, bool includeTransformsOfAllBoundGameobjects, bool includeConnectionComponentsOfAllBoundGameobjects) + { + if (hasRegisteredUndo_sinceMouseDown == false) + { + bezierSplineDrawer_unserializedMonoB.RegisterStateForUndo(nameOfUndoEntry, includeTransformsOfAllBoundGameobjects, includeConnectionComponentsOfAllBoundGameobjects); + hasRegisteredUndo_sinceMouseDown = true; + } + } + + void TrySetSelectedListSlot_dueToHandlesInteraction(int i) + { + InternalDXXL_BezierControlAnchorSubPoint2D anchorPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint; + InternalDXXL_BezierControlHelperSubPoint2D forwardHelperPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint; + InternalDXXL_BezierControlHelperSubPoint2D backwardHelperPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint; + + if (anchorPoint.controlID_ofCustomHandles_sphere == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (anchorPoint.controlID_ofCustomHandles_forwardCone == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (anchorPoint.controlID_ofCustomHandles_backwardCone == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (anchorPoint.controlID_ofUnityStylePositionHandleUp == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (anchorPoint.controlID_ofUnityStylePositionHandleRight == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (anchorPoint.controlID_ofUnityStyleRotationHandle2D == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + + if (forwardHelperPoint.controlID_ofCustomHandles_sphere == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (forwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithAnchor == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (forwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (forwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithAnchor == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (forwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (forwardHelperPoint.controlID_ofUnityStylePositionHandleUp == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (forwardHelperPoint.controlID_ofUnityStylePositionHandleRight == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + + if (backwardHelperPoint.controlID_ofCustomHandles_sphere == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (backwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithAnchor == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (backwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (backwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithAnchor == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (backwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (backwardHelperPoint.controlID_ofUnityStylePositionHandleUp == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (backwardHelperPoint.controlID_ofUnityStylePositionHandleRight == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + } + + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + + serializedObject.Update(); + + float allowedConsumedLines_0to1 = DrawConsumedLines("spline curve"); + TryDrawInfoTextHowToReducedDrawnLines(allowedConsumedLines_0to1); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + + SerializedProperty sP_lineWidth = serializedObject.FindProperty("lineWidth"); + EditorGUILayout.PropertyField(sP_lineWidth, new GUIContent("Width")); + sP_lineWidth.floatValue = Mathf.Max(sP_lineWidth.floatValue, 0.0f); + + SerializedProperty sP_straightSubDivisionsPerSegment = serializedObject.FindProperty("straightSubDivisionsPerSegment"); + EditorGUILayout.PropertyField(sP_straightSubDivisionsPerSegment, new GUIContent("Resolution (=straight lines per bezier segment)")); + sP_straightSubDivisionsPerSegment.intValue = Mathf.Max(sP_straightSubDivisionsPerSegment.intValue, 3); + + DrawCloseRingToggle(); + DrawDrawSpaceSection(); + DrawHandlesSection(); + DrawControlPointsSection(); + DrawZPosChooserFor2D(); + DrawTextInputInclMarkupHelper(); + DrawCheckboxFor_drawOnlyIfSelected("Spline curve"); + DrawCheckboxFor_hiddenByNearerObjects("Spline curve"); + + serializedObject.ApplyModifiedProperties(); + ResetUndoRegistrationFlag_duringNoInteractionPhases(); + + EditorGUI.indentLevel = indentLevel_before; + } + + void TryDrawInfoTextHowToReducedDrawnLines(float allowedConsumedLines_0to1) + { + if (GUIUtility.hotControl == 0) //-> no handle is selcted or dragged = mouse button is not held down. Otherwise the warning box would disappear while the user drags the mentioned "Width"- or "Resolution"-field, which results in unconvenient line jumps. + { + if (allowedConsumedLines_0to1 > 0.5f) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(serializedObject.FindProperty("lineWidth").floatValue) == false) + { + if (serializedObject.FindProperty("straightSubDivisionsPerSegment").intValue > 20) + { + manyDrawnLinesWarningState = BezierSplineDrawerInspector.ManyDrawnLinesWarningState.reduceWidthAndResolution; + } + else + { + manyDrawnLinesWarningState = BezierSplineDrawerInspector.ManyDrawnLinesWarningState.reduceWidth; + } + } + else + { + if (serializedObject.FindProperty("straightSubDivisionsPerSegment").intValue > 10) + { + manyDrawnLinesWarningState = BezierSplineDrawerInspector.ManyDrawnLinesWarningState.reduceResolution; + } + else + { + manyDrawnLinesWarningState = BezierSplineDrawerInspector.ManyDrawnLinesWarningState.noWarning; + } + } + } + else + { + manyDrawnLinesWarningState = BezierSplineDrawerInspector.ManyDrawnLinesWarningState.noWarning; + } + } + + switch (manyDrawnLinesWarningState) + { + case BezierSplineDrawerInspector.ManyDrawnLinesWarningState.noWarning: + break; + case BezierSplineDrawerInspector.ManyDrawnLinesWarningState.reduceWidthAndResolution: + EditorGUILayout.HelpBox("Many drawn lines could be saved if 'Width' would be set to 0. Another option is to decrease the 'Resolution'.", MessageType.Info, true); + break; + case BezierSplineDrawerInspector.ManyDrawnLinesWarningState.reduceWidth: + EditorGUILayout.HelpBox("Many drawn lines could be saved if 'Width' would be set to 0.", MessageType.Info, true); + break; + case BezierSplineDrawerInspector.ManyDrawnLinesWarningState.reduceResolution: + EditorGUILayout.HelpBox("To save drawn lines it may help to decrease the 'Resolution'.", MessageType.Info, true); + break; + default: + break; + } + } + + void DrawDrawSpaceSection() //two times "Draw" in the name is in meant this way + { + SerializedProperty sP_drawSpaceSection_isOutfolded = serializedObject.FindProperty("drawSpaceSection_isOutfolded"); + sP_drawSpaceSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_drawSpaceSection_isOutfolded.boolValue, "Draw Space", true); + if (sP_drawSpaceSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + DrawDrawSpaceEnum(); + + SerializedProperty sP_keepWorldPos_duringDrawSpaceChange = serializedObject.FindProperty("keepWorldPos_duringDrawSpaceChange"); + sP_keepWorldPos_duringDrawSpaceChange.boolValue = EditorGUILayout.ToggleLeft(new GUIContent("Keep world position during space change", "If this is selected then the global position and shape of the spline will stay the same when the draw space gets changed." + Environment.NewLine + Environment.NewLine + "If it is unselected then the spline will keep it's shape but will be scaled and rotated to fit the new draw space."), sP_keepWorldPos_duringDrawSpaceChange.boolValue); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + } + + void DrawDrawSpaceEnum() //two times "Draw" in the name is in meant this way + { + serializedObject.ApplyModifiedProperties(); + + if (bezierSplineDrawer_unserializedMonoB.drawSpace == BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject) + { + if (UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale_2D(bezierSplineDrawer_unserializedMonoB.transform)) + { + EditorGUILayout.HelpBox("The transform of this gameobject or of a parent has a non-uniform scale. This may lead to wrong or weird results, when drawing in local space.", MessageType.Warning, true); + } + + if (UtilitiesDXXL_EngineBasics.CheckIfThisOrAParentHasANonZRotation_2D(bezierSplineDrawer_unserializedMonoB.transform)) + { + EditorGUILayout.HelpBox("The transform of this gameobject or of a parent has a non-z rotation. This may lead to wrong or weird results, when drawing in local space.", MessageType.Warning, true); + } + } + + BezierSplineDrawer.DrawSpace drawSpace_after = (BezierSplineDrawer.DrawSpace)EditorGUILayout.EnumPopup(GUIContent.none, bezierSplineDrawer_unserializedMonoB.drawSpace); + if (drawSpace_after != bezierSplineDrawer_unserializedMonoB.drawSpace) + { + bezierSplineDrawer_unserializedMonoB.RegisterStateForUndo("Change Spline Space", true, false); + bezierSplineDrawer_unserializedMonoB.ChangeDrawSpace(drawSpace_after); + } + + serializedObject.Update(); + } + + void DrawCloseRingToggle() + { + serializedObject.ApplyModifiedProperties(); + + bool closeGapState_after = EditorGUILayout.Toggle(new GUIContent("Close ring from end to start"), bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed); + if (closeGapState_after != bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed) + { + bezierSplineDrawer_unserializedMonoB.ChangeCloseGapState(closeGapState_after); + } + + serializedObject.Update(); + } + + void DrawControlPointsSection() + { + SerializedProperty sP_controlPointsList_isOutfolded = serializedObject.FindProperty("controlPointsList_isOutfolded"); + sP_controlPointsList_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_controlPointsList_isOutfolded.boolValue, "Control Points", true); + if (sP_controlPointsList_isOutfolded.boolValue) + { + DrawNonSerializedControlPointsList(); + DrawSectionWithDefaultValuesOfNewlyCreatedPoints(); + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + } + + void DrawNonSerializedControlPointsList() + { + //-> exceptionally: no indent here to have more display space for the list + + serializedObject.ApplyModifiedProperties(); + + bezierSplineDrawer_unserializedMonoB.TryResheduleSceneViewRepaint(); + + Rect firstControlPointRect = default; + bool firstControlPointRect_hasBeenFilled = false; + + for (int i = 0; i < bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count; i++) + { + float height_ofCurrentControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetPropertyHeightForInspectorList(); + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].inspectorRect_reservedForThisTriplet = EditorGUILayout.GetControlRect(true, height_ofCurrentControlPoint); + + if (firstControlPointRect_hasBeenFilled == false) + { + firstControlPointRect = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].inspectorRect_reservedForThisTriplet; + firstControlPointRect_hasBeenFilled = true; + } + } + + float height_ofEmptyControlPointHoldingOnlyPlusButton = InternalDXXL_BezierControlPointTriplet.GetPropertyHeightForEmptyControlPointHoldingOnlyAPlusButtonAndFoldAllButtons(); + Rect rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons = EditorGUILayout.GetControlRect(true, height_ofEmptyControlPointHoldingOnlyPlusButton); + + if (firstControlPointRect_hasBeenFilled == false) + { + firstControlPointRect = rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons; + } + + float y_ofListsLowerEnd = rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons.y + rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons.height; + float heightOfListBackground = y_ofListsLowerEnd - firstControlPointRect.y; + Rect space_ofBackgroundColorRect = new Rect(firstControlPointRect.x, firstControlPointRect.y, firstControlPointRect.width, heightOfListBackground); + Rect space_ofBackgroundColorRectFrame = new Rect(space_ofBackgroundColorRect.x - 1.0f, space_ofBackgroundColorRect.y - 1.0f, space_ofBackgroundColorRect.width + 2.0f, space_ofBackgroundColorRect.height + 2.0f); + EditorGUI.DrawRect(space_ofBackgroundColorRectFrame, BezierSplineDrawer.color_ofControlPointListBackgroundFrameInInspecor); + EditorGUI.DrawRect(space_ofBackgroundColorRect, BezierSplineDrawer.color_ofControlPointListBackgroundInInspecor); + + for (int i = 0; i < bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count; i++) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].DrawValuesToInspector(); + } + + for (int i = 0; i < bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count; i++) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].minusButtonAtThisListItem_hasBeenClickedInInspector) + { + bezierSplineDrawer_unserializedMonoB.TryDeleteControlPoint_dueToMinusButtonAtControlPointListItemHasBeenClicked(i); + bezierSplineDrawer_unserializedMonoB.SheduleSceneViewRepaint(); + break; //-> only one change at a time + } + + bool didChangeSomething = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].TryApplyChangesAfterInspectorInput(); + if (didChangeSomething) + { + bezierSplineDrawer_unserializedMonoB.SheduleSceneViewRepaint(); + break; //-> only one change at a time + } + } + + DrawEmptyControlPointBelowControlPointsList_thatHoldsOnlyAPlusButtonAndFoldAllButtons(rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons); + + serializedObject.Update(); + } + + void DrawEmptyControlPointBelowControlPointsList_thatHoldsOnlyAPlusButtonAndFoldAllButtons(Rect rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons) + { + bool greyOutBothFoldAllButtons = ((bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count == 0) || ((bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count == 1) && (bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed == false))); + bool greyOutUnfoldAllButton = greyOutBothFoldAllButtons || bezierSplineDrawer_unserializedMonoB.CheckIf_allFoldableHelperPoints_areUnfolded_inTheInspectorList(); + bool greyOutCollapseAllButton = greyOutBothFoldAllButtons || bezierSplineDrawer_unserializedMonoB.CheckIf_allFoldableHelperPoints_areCollapsed_inTheInspectorList(); + + InternalDXXL_BezierControlPointTriplet.DrawEmptyControlPointHoldingOnlyAPlusButton_forInspector(out bool plusButtonBelowListOfControlPoints_hasBeenClicked, out bool unfoldAllWeightsBelowListOfControlPoints_hasBeenClicked, out bool collapseAllWeightsBelowListOfControlPoints_hasBeenClicked, rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, plusSymbolIcon, greyOutUnfoldAllButton, greyOutCollapseAllButton); + if (plusButtonBelowListOfControlPoints_hasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CreateNewControlPoint_dueToPlusButtonBelowControlPointsListHasBeenClicked(); + bezierSplineDrawer_unserializedMonoB.SheduleSceneViewRepaint(); + } + + if (unfoldAllWeightsBelowListOfControlPoints_hasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.UnfoldAllHelperPointInTheInspectorList(); + } + + if (collapseAllWeightsBelowListOfControlPoints_hasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CollapseAllHelperPointInTheInspectorList(); + } + } + + void DrawSectionWithDefaultValuesOfNewlyCreatedPoints() + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded = serializedObject.FindProperty("defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded"); + sP_defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded.boolValue, "Default values of newly created control points", true); + if (sP_defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + DrawSectionWithDefaultOffsetOfNewlyCreatedPoints(); + DrawSectionWithDefaultOrientationOfNewlyCreatedPoints(); + DrawSectionWithDefaultWeightDistancesOfNewlyCreatedPoints(); + DrawSectionWithDefaultJunctureTypeOfNewlyCreatedPoints(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawSectionWithDefaultOffsetOfNewlyCreatedPoints() + { + SerializedProperty sP_defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded = serializedObject.FindProperty("defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded"); + sP_defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded.boolValue, "Default Position Offset", true); + if (sP_defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_definitionType_ofDefaultPosOffset = serializedObject.FindProperty("definitionType_ofDefaultPosOffset"); + EditorGUILayout.PropertyField(sP_definitionType_ofDefaultPosOffset, new GUIContent("Offset source")); + switch (sP_definitionType_ofDefaultPosOffset.enumValueIndex) + { + case (int)BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.straightExtentionOfCurveEnd: + SerializedProperty sP_distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace = serializedObject.FindProperty("distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace"); + EditorGUILayout.PropertyField(sP_distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace, new GUIContent("Distance")); + sP_distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace.floatValue = Mathf.Max(sP_distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace.floatValue, 0.0f); + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + break; + case (int)BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.customOffset: + DrawSpecificationOf_customVector2_1("Custom offset value", false, null, false, false, true, false); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSectionWithDefaultOrientationOfNewlyCreatedPoints() + { + SerializedProperty sP_defaultRotOfNewlyCreatedPoints_subSection_isOutfolded = serializedObject.FindProperty("defaultRotOfNewlyCreatedPoints_subSection_isOutfolded"); + sP_defaultRotOfNewlyCreatedPoints_subSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_defaultRotOfNewlyCreatedPoints_subSection_isOutfolded.boolValue, "Default Initial Orientation", true); + if (sP_defaultRotOfNewlyCreatedPoints_subSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_definitionType_ofDefaultRot = serializedObject.FindProperty("definitionType_ofDefaultRot"); + EditorGUILayout.PropertyField(sP_definitionType_ofDefaultRot, new GUIContent("Orientation source")); + switch (sP_definitionType_ofDefaultRot.enumValueIndex) + { + case (int)BezierSplineDrawer.DefinitionType_ofDefaultRot.sameAsCurveEnd: + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + break; + case (int)BezierSplineDrawer.DefinitionType_ofDefaultRot.customOrientation: + DrawSpecificationOf_customVector2_2("Custom forward vector that defines the orientation", false, null, true, false, true, false); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSectionWithDefaultWeightDistancesOfNewlyCreatedPoints() + { + SerializedProperty sP_defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded = serializedObject.FindProperty("defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded"); + sP_defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded.boolValue, "Default Initial Weight Distances", true); + if (sP_defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace = serializedObject.FindProperty("forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace"); + EditorGUILayout.PropertyField(sP_forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace, new GUIContent("Forward")); + sP_forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace.floatValue = Mathf.Max(sP_forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace.floatValue, 0.0f); + + SerializedProperty sP_backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace = serializedObject.FindProperty("backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace"); + EditorGUILayout.PropertyField(sP_backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace, new GUIContent("Backward")); + sP_backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace.floatValue = Mathf.Max(sP_backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace.floatValue, 0.0f); + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSectionWithDefaultJunctureTypeOfNewlyCreatedPoints() + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("junctureType_ofNewlyCreatedPoints"), new GUIContent("Default Juncture Type")); + } + + void DrawHandlesSection() + { + SerializedProperty sP_handlesSection_isOutfolded = serializedObject.FindProperty("handlesSection_isOutfolded"); + SerializedProperty sP_hideAllHandles = serializedObject.FindProperty("hideAllHandles"); + + Rect rect_ofHandlesHeadline = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight); + Rect rect_ofHandlesHeadlineFoldout = new Rect(rect_ofHandlesHeadline.x, rect_ofHandlesHeadline.y, EditorGUIUtility.singleLineHeight, rect_ofHandlesHeadline.height); + Rect rect_ofHandlesHeadlineTextWithCheckbox = new Rect(rect_ofHandlesHeadline.x, rect_ofHandlesHeadline.y, rect_ofHandlesHeadline.width, rect_ofHandlesHeadline.height); + + sP_hideAllHandles.boolValue = !EditorGUI.ToggleLeft(rect_ofHandlesHeadlineTextWithCheckbox, new GUIContent("Handles"), !sP_hideAllHandles.boolValue); + sP_handlesSection_isOutfolded.boolValue = EditorGUI.Foldout(rect_ofHandlesHeadlineFoldout, sP_handlesSection_isOutfolded.boolValue, GUIContent.none, true); + + if (sP_handlesSection_isOutfolded.boolValue == true) + { + EditorGUI.BeginDisabledGroup(sP_hideAllHandles.boolValue); + DrawHandlesSection_outfoldedPart(); + EditorGUI.EndDisabledGroup(); + } + } + + void DrawHandlesSection_outfoldedPart() + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + GUIStyle labelStyle_withRichtext = new GUIStyle(); + + DrawPositionHandlesSection(labelStyle_withRichtext); + DrawRotationHandlesSection(labelStyle_withRichtext); + DrawCustomHandlesSection(labelStyle_withRichtext); + DrawPlusButtonHandleSection(labelStyle_withRichtext); + DrawDottedLineAlongZToBoundGameobjectsSection(labelStyle_withRichtext); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawPositionHandlesSection(GUIStyle labelStyle_withRichtext) + { + EditorGUILayout.LabelField("Move Position Handle (Unity style)", labelStyle_withRichtext); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_showHandleFor_position_atAnchors = serializedObject.FindProperty("showHandleFor_position_atAnchors"); + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_showHandleFor_position_atAnchors, new GUIContent("At Anchor Points (show/size)")); + EditorGUI.BeginDisabledGroup(!sP_showHandleFor_position_atAnchors.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeFor_position_atAnchors"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + SerializedProperty sP_showHandleFor_position_atHelpers = serializedObject.FindProperty("showHandleFor_position_atHelpers"); + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_showHandleFor_position_atHelpers, new GUIContent("At Helper Points (show/size)")); + EditorGUI.BeginDisabledGroup(!sP_showHandleFor_position_atHelpers.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeFor_position_atHelpers"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + bool drawSpaceIsLocal = (serializedObject.FindProperty("drawSpace").enumValueIndex == (int)BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject); + bool positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal_chooserIsAvailable = (Tools.pivotRotation == PivotRotation.Global) && drawSpaceIsLocal; + string positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal_displayName = "Global orientation in local draw space"; + if (positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal_chooserIsAvailable) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal"), new GUIContent(positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal_displayName, "If your Editor tool handle rotation is set to 'global' orientation, but you work in a local draw space for a spline then the question arises which space should be considered as 'global' in den local draw space and accordingly how the position handle should be displayed." + Environment.NewLine + Environment.NewLine + "Chose 'global space' if you want the position handles aligned with the global world space." + Environment.NewLine + Environment.NewLine + "Chose 'local draw space' if you want the position handles aligned with the local draw space.")); + } + else + { + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.PropertyField(serializedObject.FindProperty("positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal"), new GUIContent(positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal_displayName, "Only available if Editor tool handle rotation is set to 'global' and if draw space is 'local'.")); + EditorGUI.EndDisabledGroup(); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + + void DrawRotationHandlesSection(GUIStyle labelStyle_withRichtext) + { + EditorGUILayout.LabelField("Rotate Handle", labelStyle_withRichtext); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_showHandleFor_rotation = serializedObject.FindProperty("showHandleFor_rotation"); + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_showHandleFor_rotation, new GUIContent("Show / Size")); + EditorGUI.BeginDisabledGroup(!sP_showHandleFor_rotation.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeFor_rotation"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + + void DrawCustomHandlesSection(GUIStyle labelStyle_withRichtext) + { + EditorGUILayout.LabelField("Spline Custom Handles", labelStyle_withRichtext); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUILayout.LabelField("At Anchor Points"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + SerializedProperty sP_showCustomHandleFor_anchorPoints = serializedObject.FindProperty("showCustomHandleFor_anchorPoints"); + EditorGUILayout.PropertyField(sP_showCustomHandleFor_anchorPoints, new GUIContent("Show")); + EditorGUI.BeginDisabledGroup(!sP_showCustomHandleFor_anchorPoints.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeOf_customHandle_atAnchors"), new GUIContent("Size")); + EditorGUI.EndDisabledGroup(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_ofAnchorPoints"), new GUIContent("Color")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("At Helper Points"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + SerializedProperty sP_showCustomHandleFor_helperPoints = serializedObject.FindProperty("showCustomHandleFor_helperPoints"); + EditorGUILayout.PropertyField(sP_showCustomHandleFor_helperPoints, new GUIContent("Show")); + EditorGUI.BeginDisabledGroup(!sP_showCustomHandleFor_helperPoints.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeOf_customHandle_atHelpers"), new GUIContent("Size")); + EditorGUI.EndDisabledGroup(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_ofHelperPoints"), new GUIContent("Color")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + + void DrawPlusButtonHandleSection(GUIStyle labelStyle_withRichtext) + { + EditorGUILayout.LabelField("Add Point Buttons ('+')", labelStyle_withRichtext); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_showHandleFor_plusButtons_atSplineStartAndEnd = serializedObject.FindProperty("showHandleFor_plusButtons_atSplineStartAndEnd"); + SerializedProperty sP_showHandleFor_plusButtons_insideSegments = serializedObject.FindProperty("showHandleFor_plusButtons_insideSegments"); + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_showHandleFor_plusButtons_atSplineStartAndEnd, new GUIContent("At Start/End")); + EditorGUILayout.PropertyField(sP_showHandleFor_plusButtons_insideSegments, new GUIContent("Inside Curve")); + GUILayout.EndHorizontal(); + + bool atLeastOnePlusButtonOption_isChecked = (sP_showHandleFor_plusButtons_atSplineStartAndEnd.boolValue || sP_showHandleFor_plusButtons_insideSegments.boolValue); + EditorGUI.BeginDisabledGroup(!atLeastOnePlusButtonOption_isChecked); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeOf_plusButtons"), new GUIContent("Size")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + + void DrawDottedLineAlongZToBoundGameobjectsSection(GUIStyle labelStyle_withRichtext) + { + EditorGUILayout.LabelField("Dotted Lines along Z to bound Gameobjects", labelStyle_withRichtext); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("showDottedLinesAlongZToBoundGameobjects"), new GUIContent("Show")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorOfLinesAlongZToBoundGameobjects"), GUIContent.none); + GUILayout.EndHorizontal(); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("dotLength_ofDottedLinesAlongZToBoundGameobjects"), new GUIContent("Dash Length")); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/BezierSplineDrawer2DInspector.cs.meta b/Editor/DrawDebugLibrary/BezierSplineDrawer2DInspector.cs.meta new file mode 100644 index 0000000..f81f222 --- /dev/null +++ b/Editor/DrawDebugLibrary/BezierSplineDrawer2DInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45cf81c1a7d89284dab549f3c2e6aa3f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/BezierSplineDrawerInspector.cs b/Editor/DrawDebugLibrary/BezierSplineDrawerInspector.cs new file mode 100644 index 0000000..6865ea4 --- /dev/null +++ b/Editor/DrawDebugLibrary/BezierSplineDrawerInspector.cs @@ -0,0 +1,2226 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(BezierSplineDrawer))] + public class BezierSplineDrawerInspector : VisualizerParentInspector + { + BezierSplineDrawer bezierSplineDrawer_unserializedMonoB; + Tool toolToSelectAfterThisInspectorGetsUnselcted = Tool.None; + Tool selectedToolDuringPreviousOnSceneGUI = Tool.None; + bool sheduleFocusSceneViewOnControlPoint = false; + int delayCounter_afterShedulingFocusSceneViewOnControlPoint = 0; + float dotLength_ofDottedLines = 4.0f; + bool hasRegisteredUndo_sinceMouseDown = false; + GUIContent plusSymbolIcon; + Vector3 sceneViewCamForward_normalized; + Vector3 sceneViewCamUp_normalized; + Vector3 sceneViewCamRight_normalized; + Vector3 sceneViewCam_to_anchorPoint; + + public enum ManyDrawnLinesWarningState { noWarning, reduceWidthAndResolution, reduceWidth, reduceResolution }; + ManyDrawnLinesWarningState manyDrawnLinesWarningState = ManyDrawnLinesWarningState.noWarning; + + void OnEnable() + { + OnEnable_base(); + bezierSplineDrawer_unserializedMonoB = (BezierSplineDrawer)target; + bezierSplineDrawer_unserializedMonoB.ResetAll_rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation(); + plusSymbolIcon = EditorGUIUtility.TrIconContent("Toolbar Plus", "Add new control point"); + + toolToSelectAfterThisInspectorGetsUnselcted = Tools.current; + ProcessChangingEditorTool(); + selectedToolDuringPreviousOnSceneGUI = Tools.current; + } + + public void OnDisable() + { + Tools.current = toolToSelectAfterThisInspectorGetsUnselcted; + } + + public void OnSceneGUI() + { + if (bezierSplineDrawer_unserializedMonoB != null) //-> sometimes after deleting the spline component in the inspector this "OnSceneGUI()" is still called, which would result in a missingRefException without this check + { + bezierSplineDrawer_unserializedMonoB.sheduledSceneViewRepaint_hasBeenExecuted = true; + + if (bezierSplineDrawer_unserializedMonoB.enabled) //-> GizmoLines automatically hide if a component is disabled, Handles do not: Therefore manual disabling here + { + TryFocusControlPointInSceneView_onKeypressF(); + TryProcessChangingEditorTool(); + TryResetRotationOfIndependentRotationHandles(); + + Matrix4x4 handlesMatrix_before = Handles.matrix; + Color handlesColor_before = Handles.color; + + DrawHandles(); + + Handles.matrix = handlesMatrix_before; + Handles.color = handlesColor_before; + } + } + } + + void TryFocusControlPointInSceneView_onKeypressF() + { + delayCounter_afterShedulingFocusSceneViewOnControlPoint++; + SheduleFocusing_onKeypressF(); + ExecuteSheduledFocusingAfterDelay(); + } + + void SheduleFocusing_onKeypressF() + { + Event currentEvent = Event.current; + if (currentEvent.type == EventType.KeyDown) + { + if (currentEvent.keyCode == KeyCode.F) + { + //this only works when the mouse is in the scene view window (in contrast to Unitys build-in behaviour, where you can focus the scene view camera via pressing "F" even when the mouse is not in the scene view) + sheduleFocusSceneViewOnControlPoint = true; + delayCounter_afterShedulingFocusSceneViewOnControlPoint = 0; + } + } + } + + void ExecuteSheduledFocusingAfterDelay() + { + if (sheduleFocusSceneViewOnControlPoint) + { + //This overwrites the focusing on the gameobject center (which is automatically executed by Unity onKeypressF) with focusing on the the selected control point instead. + //The sheduling is because otherwise Unitys automatic focussing on the gameobject will overwrite the here executed focusing + int delayValue = 20; //This is a guessed trial-an-error value. + if (delayCounter_afterShedulingFocusSceneViewOnControlPoint > delayValue) + { + sheduleFocusSceneViewOnControlPoint = false; + if (SceneView.lastActiveSceneView != null) + { + int i_ofFirstHighlightedControlPoint = bezierSplineDrawer_unserializedMonoB.Get_i_ofFirstHighlightedControlPoint(); + if (i_ofFirstHighlightedControlPoint == (-1)) + { + FrameSceneViewCam_soItSeesAllControlPoints(i_ofFirstHighlightedControlPoint); + } + else + { + FrameSceneViewCam_soItSeesSpecifiedControlPoints(i_ofFirstHighlightedControlPoint, true); + } + } + } + } + } + + void FrameSceneViewCam_soItSeesAllControlPoints(int i_ofFirstHighlightedControlPoint) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count == 0) + { + Bounds boundsOfSelection = new Bounds(bezierSplineDrawer_unserializedMonoB.Get_originPos_ofActiveDrawSpace_inUnitsOfGlobalSpace(), Vector3.zero); + SceneView.lastActiveSceneView.Frame(boundsOfSelection, false); + } + else + { + FrameSceneViewCam_soItSeesSpecifiedControlPoints(i_ofFirstHighlightedControlPoint, false); + } + } + + void FrameSceneViewCam_soItSeesSpecifiedControlPoints(int i_ofFirstHighlightedControlPoint, bool includeOnlySelectedControlPoints_notAllControlPoints) + { + Vector3 posGlobal_ofFirstFramedControlPoint; + if (includeOnlySelectedControlPoints_notAllControlPoints) + { + posGlobal_ofFirstFramedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i_ofFirstHighlightedControlPoint].anchorPoint.GetPos_inUnitsOfGlobalSpace(); + } + else + { + //"listOfControlPointTriplets.Count" is guaranteed bigger than 0 here: + posGlobal_ofFirstFramedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[0].anchorPoint.GetPos_inUnitsOfGlobalSpace(); + } + Bounds boundsOfSelection = new Bounds(posGlobal_ofFirstFramedControlPoint, Vector3.zero); + + for (int i = 0; i < bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count; i++) + { + if ((includeOnlySelectedControlPoints_notAllControlPoints == false) || bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].isHighlighted) + { + boundsOfSelection.Encapsulate(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace()); + + InternalDXXL_BezierControlPointTriplet nextControlPoint = bezierSplineDrawer_unserializedMonoB.GetNextControlPointTriplet(i, false); + if (nextControlPoint != null) { boundsOfSelection.Encapsulate(nextControlPoint.anchorPoint.GetPos_inUnitsOfGlobalSpace()); } + + InternalDXXL_BezierControlPointTriplet previousControlPoint = bezierSplineDrawer_unserializedMonoB.GetPreviousControlPointTriplet(i, false); + if (previousControlPoint != null) { boundsOfSelection.Encapsulate(previousControlPoint.anchorPoint.GetPos_inUnitsOfGlobalSpace()); } + } + } + SceneView.lastActiveSceneView.Frame(boundsOfSelection, false); + } + + void DrawHandles() + { + if (bezierSplineDrawer_unserializedMonoB.hideAllHandles == false) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count == 0) + { + DrawPlusButton_asFallbackIfNoControlPointsExist(); + } + else + { + for (int i = 0; i < bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count; i++) + { + Handles.matrix = Matrix4x4.identity; + + AssignControlHandleIDs(i); + DrawLinesBetweenSubPoints(i); + DrawIndexAsText(i); + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out sceneViewCamForward_normalized, out sceneViewCamUp_normalized, out sceneViewCamRight_normalized, out sceneViewCam_to_anchorPoint, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace(), DrawBasics.CameraForAutomaticOrientation.sceneViewCamera); + DrawNonInteractableAnchorPointVisualizer(i); + DrawNonInteractableHelperPointVisualizer(i, true, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.GetPos_inUnitsOfGlobalSpace()); + DrawNonInteractableHelperPointVisualizer(i, false, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.GetPos_inUnitsOfGlobalSpace()); + DrawPlusButtonsForAddingNewControlPoints_atSplineStartAndEnd(i); + DrawPlusButtonsForAddingNewControlPoints_somewhereOnUpcomingSplineSegment(i); + DrawUnitysBuildInHandlesAtSubPoints(i); + DrawCustomHandlesAtSubPoints(i); + TrySetSelectedListSlot_dueToHandlesInteraction(i); + Reset_recalculationFlags_duringNoHandleClickedOrDraggedPhases(i); + } + } + } + + ResetUndoRegistrationFlag_duringNoInteractionPhases(); + } + + void DrawPlusButton_asFallbackIfNoControlPointsExist() + { + Vector3 posOfPlusButton_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.Get_originPos_ofActiveDrawSpace_inUnitsOfGlobalSpace(); + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out sceneViewCamForward_normalized, out sceneViewCamUp_normalized, out sceneViewCamRight_normalized, out sceneViewCam_to_anchorPoint, posOfPlusButton_inUnitsOfGlobalSpace, DrawBasics.CameraForAutomaticOrientation.sceneViewCamera); + bool buttonHasBeenClicked = InternalDXXL_BezierHandles.PlusButton(posOfPlusButton_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.handleSizeOf_plusButtons, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, sceneViewCamForward_normalized, sceneViewCamUp_normalized, sceneViewCamRight_normalized, plusSymbolIcon); + if (buttonHasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CreateNewControlPoint_atSplineEnd(); + } + } + + void AssignControlHandleIDs(int i) + { + InternalDXXL_BezierControlPointTriplet concernedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + int hint_base = 100 * i; //probably also working without the int-hints + + concernedControlPoint.anchorPoint.controlID_ofCustomHandles_sphere = GUIUtility.GetControlID(hint_base + 1, FocusType.Passive); + concernedControlPoint.anchorPoint.controlID_ofCustomHandles_forwardCone = GUIUtility.GetControlID(hint_base + 2, FocusType.Passive); + concernedControlPoint.anchorPoint.controlID_ofCustomHandles_backwardCone = GUIUtility.GetControlID(hint_base + 3, FocusType.Passive); + + concernedControlPoint.forwardHelperPoint.controlID_ofCustomHandles_sphere = GUIUtility.GetControlID(hint_base + 4, FocusType.Passive); + concernedControlPoint.forwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithAnchor = GUIUtility.GetControlID(hint_base + 5, FocusType.Passive); + concernedControlPoint.forwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper = GUIUtility.GetControlID(hint_base + 6, FocusType.Passive); + concernedControlPoint.forwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithAnchor = GUIUtility.GetControlID(hint_base + 7, FocusType.Passive); + concernedControlPoint.forwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper = GUIUtility.GetControlID(hint_base + 8, FocusType.Passive); + + concernedControlPoint.backwardHelperPoint.controlID_ofCustomHandles_sphere = GUIUtility.GetControlID(hint_base + 9, FocusType.Passive); + concernedControlPoint.backwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithAnchor = GUIUtility.GetControlID(hint_base + 10, FocusType.Passive); + concernedControlPoint.backwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper = GUIUtility.GetControlID(hint_base + 11, FocusType.Passive); + concernedControlPoint.backwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithAnchor = GUIUtility.GetControlID(hint_base + 12, FocusType.Passive); + concernedControlPoint.backwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper = GUIUtility.GetControlID(hint_base + 13, FocusType.Passive); + } + + void DrawLinesBetweenSubPoints(int i) + { + TryDrawLineToForwardWeight(i); + TryDrawLineToBackwardWeight(i); + TryDrawLineFromForwardHelperPoint_toBackwardHelperPointOfNextControlPoint(i); + TryDrawLineFromForwardHelperPoint_toAnchorPointOfNextControlPoint(i); + TryDrawLineFromAnchorPoint_toBackwardHelperPointOfNextControlPoint(i); + } + + void TryDrawLineToForwardWeight(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.isUsed) + { + Vector3 lineStartPos_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 lineEndPos_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + + TryDrawExpandedLowAlphaLine_fromAnchorToHelper(i, lineStartPos_inUnitsOfGlobalSpace, lineEndPos_inUnitsOfGlobalSpace); + + Handles.color = bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints; + Handles.DrawLine(lineStartPos_inUnitsOfGlobalSpace, lineEndPos_inUnitsOfGlobalSpace); + } + } + + void TryDrawLineToBackwardWeight(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.isUsed) + { + Vector3 lineStartPos_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 lineEndPos_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + + TryDrawExpandedLowAlphaLine_fromAnchorToHelper(i, lineStartPos_inUnitsOfGlobalSpace, lineEndPos_inUnitsOfGlobalSpace); + + Handles.color = bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints; + Handles.DrawLine(lineStartPos_inUnitsOfGlobalSpace, lineEndPos_inUnitsOfGlobalSpace); + } + } + + public static float width_ofAdditionalExpandedLowAlphaLineToHelpers_ofSelectedControlPoints = 15.0f; + public static float alpha_ofAdditionalExpandedLowAlphaLineToHelpers_ofSelectedControlPoints = 0.3f; + void TryDrawExpandedLowAlphaLine_fromAnchorToHelper(int i, Vector3 lineStartPos_inUnitsOfGlobalSpace, Vector3 lineEndPos_inUnitsOfGlobalSpace) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].isHighlighted) + { + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, alpha_ofAdditionalExpandedLowAlphaLineToHelpers_ofSelectedControlPoints); + Handles.DrawAAPolyLine(width_ofAdditionalExpandedLowAlphaLineToHelpers_ofSelectedControlPoints, lineStartPos_inUnitsOfGlobalSpace, lineEndPos_inUnitsOfGlobalSpace); + } + } + + public static float alphaOfDottedLineBetweenHelperPoints = 0.45f; + void TryDrawLineFromForwardHelperPoint_toBackwardHelperPointOfNextControlPoint(int i) + { + if (CheckIf_drawLineFromForwardHelperPoint_toBackwardHelperPointOfNextControlPoint(i)) + { + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, alphaOfDottedLineBetweenHelperPoints); + int i_ofNextControlPoint = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count); + Handles.DrawDottedLine(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i_ofNextControlPoint].backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), dotLength_ofDottedLines); + } + } + + bool CheckIf_drawLineFromForwardHelperPoint_toBackwardHelperPointOfNextControlPoint(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.isUsed) + { + InternalDXXL_BezierControlPointTriplet nextControlPointTriplet = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetNextControlPointTripletAlongSplineDir(false); + if (nextControlPointTriplet == null) + { + return false; + } + else + { + return nextControlPointTriplet.backwardHelperPoint.isUsed; + } + } + else + { + return false; + } + } + + void TryDrawLineFromForwardHelperPoint_toAnchorPointOfNextControlPoint(int i) + { + if (CheckIf_drawLineFromForwardHelperPoint_toAnchorPointOfNextControlPoint(i)) + { + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, alphaOfDottedLineBetweenHelperPoints); + int i_ofNextControlPoint = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count); + Handles.DrawDottedLine(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i_ofNextControlPoint].anchorPoint.GetPos_inUnitsOfGlobalSpace(), dotLength_ofDottedLines); + } + } + + bool CheckIf_drawLineFromForwardHelperPoint_toAnchorPointOfNextControlPoint(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.isUsed) + { + InternalDXXL_BezierControlPointTriplet nextControlPointTriplet = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetNextControlPointTripletAlongSplineDir(false); + if (nextControlPointTriplet == null) + { + return false; + } + else + { + return (nextControlPointTriplet.backwardHelperPoint.isUsed == false); + } + } + else + { + return false; + } + } + + void TryDrawLineFromAnchorPoint_toBackwardHelperPointOfNextControlPoint(int i) + { + if (CheckIf_drawLineFromAnchorPoint_toBackwardHelperPointOfNextControlPoint(i)) + { + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, alphaOfDottedLineBetweenHelperPoints); + int i_ofNextControlPoint = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count); + Handles.DrawDottedLine(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace(), bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i_ofNextControlPoint].backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), dotLength_ofDottedLines); + } + } + + bool CheckIf_drawLineFromAnchorPoint_toBackwardHelperPointOfNextControlPoint(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.isUsed == false) + { + InternalDXXL_BezierControlPointTriplet nextControlPointTriplet = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetNextControlPointTripletAlongSplineDir(false); + if (nextControlPointTriplet == null) + { + return false; + } + else + { + return nextControlPointTriplet.backwardHelperPoint.isUsed; + } + } + else + { + return false; + } + } + + void TryProcessChangingEditorTool() + { + if (selectedToolDuringPreviousOnSceneGUI != Tools.current) + { + ProcessChangingEditorTool(); + } + selectedToolDuringPreviousOnSceneGUI = Tools.current; + } + + void ProcessChangingEditorTool() + { + if (Tools.current == Tool.Move) + { + if (bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_anchorPoints == bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_helperPoints) + { + //-> custom handles are "both on" or "both off" + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atAnchors = true; + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atHelpers = true; + } + else + { + //-> one custom handle is on, the other is off + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atAnchors = bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_anchorPoints; + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atHelpers = bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_helperPoints; + } + + bezierSplineDrawer_unserializedMonoB.showHandleFor_rotation = false; + } + else + { + if (Tools.current == Tool.Rotate) + { + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atAnchors = false; + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atHelpers = false; + bezierSplineDrawer_unserializedMonoB.showHandleFor_rotation = true; + } + else + { + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atAnchors = false; + bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atHelpers = false; + bezierSplineDrawer_unserializedMonoB.showHandleFor_rotation = false; + } + } + } + + void TryResetRotationOfIndependentRotationHandles() + { + //this emulates an "reset on activate rotation handle"-behaviour: + if (bezierSplineDrawer_unserializedMonoB.showHandleFor_rotation == false) + { + bezierSplineDrawer_unserializedMonoB.ResetAll_rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation(); + } + } + + void DrawNonInteractableAnchorPointVisualizer(int i) + { + Vector3 position_ofAnchorPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace(); + DrawNonInteractableSubPointVisualizer(i, position_ofAnchorPoint_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, bezierSplineDrawer_unserializedMonoB.handleSizeOf_customHandle_atAnchors, bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_anchorPoints); + } + + void DrawNonInteractableHelperPointVisualizer(int i, bool concerncedHelperPoint_isForward_notBackward, Vector3 position_ofHelperPoint_inUnitsOfGlobalSpace) + { + if (CheckIf_drawNonInteractableHelperPointVisualizer(i, concerncedHelperPoint_isForward_notBackward)) + { + DrawNonInteractableSubPointVisualizer(i, position_ofHelperPoint_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, bezierSplineDrawer_unserializedMonoB.handleSizeOf_customHandle_atHelpers, bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_helperPoints); + } + } + + public static float sizeFactor_ofNonInteracalbeFlatSubPointVisualizer_forHighlightedPoints = 3.25f; + public static float alpha_ofExpandedNonInteractableFlatSubPointVisualizer_forHighlightedControlPoints = 0.15f; + void DrawNonInteractableSubPointVisualizer(int i, Vector3 position_ofSubPoint_inUnitsOfGlobalSpace, Color color, float handleSize, bool handlesAreActivated) + { + Handles.color = color; + float radius_ofSubPointIndicator = 0.5f * handleSize * HandleUtility.GetHandleSize(position_ofSubPoint_inUnitsOfGlobalSpace); + + if (handlesAreActivated == false) + { + Handles.DrawSolidDisc(position_ofSubPoint_inUnitsOfGlobalSpace, sceneViewCamForward_normalized, radius_ofSubPointIndicator); + } + + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].isHighlighted) + { + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alpha_ofExpandedNonInteractableFlatSubPointVisualizer_forHighlightedControlPoints); + Handles.DrawSolidDisc(position_ofSubPoint_inUnitsOfGlobalSpace, sceneViewCamForward_normalized, sizeFactor_ofNonInteracalbeFlatSubPointVisualizer_forHighlightedPoints * radius_ofSubPointIndicator); + } + } + + bool CheckIf_drawNonInteractableHelperPointVisualizer(int i, bool concerncedHelperPoint_isForward_notBackward) + { + return bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetAHelperPoint(concerncedHelperPoint_isForward_notBackward).isUsed; + } + + void DrawIndexAsText(int i) + { + GUIStyle style_ofTextAtControlPoints = new GUIStyle(); + string space_beforeTextString = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].isHighlighted ? " " : " "; + + float scaleFactorOfText = bezierSplineDrawer_unserializedMonoB.handleSizeOf_customHandle_atAnchors / BezierSplineDrawer.default_handleSizeOf_customHandle_atAnchors; + int scale_ofSpaceBeforeTextString = Mathf.RoundToInt(scaleFactorOfText * 11); + int scale_ofNumberItself = Mathf.RoundToInt(scaleFactorOfText * 25); + + string text_atControlPoint = "" + space_beforeTextString + "" + i + ""; + Handles.Label(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace(), text_atControlPoint, style_ofTextAtControlPoints); + } + + void DrawPlusButtonsForAddingNewControlPoints_atSplineStartAndEnd(int i) + { + if (bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed == false) + { + if (bezierSplineDrawer_unserializedMonoB.showHandleFor_plusButtons_atSplineStartAndEnd) + { + DrawPlusButtonsForAddingNewControlPoints_atSplineStart(i); + DrawPlusButtonsForAddingNewControlPoints_atSplineEnd(i); + } + } + } + + public static float alphaOfSolidBackgroundLine_ofLinesTowardsPlusButtonsAtSplineEnds = 0.25f; + public static float alphaOfDottedLine_ofLinesTowardsPlusButtonsAtSplineEnds = 0.5f; + void DrawPlusButtonsForAddingNewControlPoints_atSplineStart(int i) + { + if (bezierSplineDrawer_unserializedMonoB.IsFirstControlPoint(i)) + { + InternalDXXL_BezierControlPointTriplet currControlPointTriplet = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + Vector3 currentFirstControlPoint_backTo_newlyCreatableControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_firstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized(currControlPointTriplet); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(currentFirstControlPoint_backTo_newlyCreatableControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized)) + { + currentFirstControlPoint_backTo_newlyCreatableControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized = (-bezierSplineDrawer_unserializedMonoB.Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized()); + } + float distanceToCurrentFirstControlPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.Get_distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace(); + Vector3 posOf_plusButtonAtSplineStart_inUnitsOfGlobalSpace = currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace() + currentFirstControlPoint_backTo_newlyCreatableControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized * distanceToCurrentFirstControlPoint_inUnitsOfGlobalSpace; + + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, alphaOfSolidBackgroundLine_ofLinesTowardsPlusButtonsAtSplineEnds); + Handles.DrawLine(currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace(), posOf_plusButtonAtSplineStart_inUnitsOfGlobalSpace); + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, alphaOfDottedLine_ofLinesTowardsPlusButtonsAtSplineEnds); + Handles.DrawDottedLine(currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace(), posOf_plusButtonAtSplineStart_inUnitsOfGlobalSpace, dotLength_ofDottedLines); + + bool buttonHasBeenClicked = InternalDXXL_BezierHandles.PlusButton(posOf_plusButtonAtSplineStart_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.handleSizeOf_plusButtons, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, sceneViewCamForward_normalized, sceneViewCamUp_normalized, sceneViewCamRight_normalized, plusSymbolIcon); + if (buttonHasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CreateNewControlPoint_atSplineStart(); + } + } + } + + void DrawPlusButtonsForAddingNewControlPoints_atSplineEnd(int i) + { + if (bezierSplineDrawer_unserializedMonoB.IsLastControlPoint(i)) + { + InternalDXXL_BezierControlPointTriplet currControlPointTriplet = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + Vector3 currentLastControlPoint_to_newlyCreatableControlPoint_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized(currControlPointTriplet); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(currentLastControlPoint_to_newlyCreatableControlPoint_inUnitsOfGlobalSpace_normalized)) + { + currentLastControlPoint_to_newlyCreatableControlPoint_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + float distanceToCurrentLastControlPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.Get_distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace(); + Vector3 posOf_plusButtonAtSplineEnd_inUnitsOfGlobalSpace = currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace() + currentLastControlPoint_to_newlyCreatableControlPoint_inUnitsOfGlobalSpace_normalized * distanceToCurrentLastControlPoint_inUnitsOfGlobalSpace; + + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, alphaOfSolidBackgroundLine_ofLinesTowardsPlusButtonsAtSplineEnds); + Handles.DrawLine(currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace(), posOf_plusButtonAtSplineEnd_inUnitsOfGlobalSpace); + Handles.color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints, alphaOfDottedLine_ofLinesTowardsPlusButtonsAtSplineEnds); + Handles.DrawDottedLine(currControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace(), posOf_plusButtonAtSplineEnd_inUnitsOfGlobalSpace, dotLength_ofDottedLines); + + bool buttonHasBeenClicked = InternalDXXL_BezierHandles.PlusButton(posOf_plusButtonAtSplineEnd_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.handleSizeOf_plusButtons, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, sceneViewCamForward_normalized, sceneViewCamUp_normalized, sceneViewCamRight_normalized, plusSymbolIcon); + if (buttonHasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CreateNewControlPoint_atSplineEnd(); + } + } + } + + void DrawPlusButtonsForAddingNewControlPoints_somewhereOnUpcomingSplineSegment(int i) + { + if (bezierSplineDrawer_unserializedMonoB.showHandleFor_plusButtons_insideSegments) + { + InternalDXXL_BezierControlPointTriplet concernedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + if (bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed || concernedControlPoint.IsLastControlPoint() == false) + { + float pos0to1_insideSegment_ofPlusButton_beforeDrag = concernedControlPoint.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + Vector3 posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace = concernedControlPoint.GetPosAtPlusButton_onUpcomingBezierSegment_inUnitsOfGlobalSpace(); + Vector3 directionOfConeForShifting_inUnitsOfGlobalSpace_normalized = concernedControlPoint.GetTangentAtPlusButton_onUpcomingBezierSegment_inUnitsOfGlobalSpace(true); + float handleSize = bezierSplineDrawer_unserializedMonoB.handleSizeOf_plusButtons * HandleUtility.GetHandleSize(posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace); + + Handles.color = bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints; + Quaternion rotation_ofForwardCone = Quaternion.LookRotation(directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, Vector3.zero); + Quaternion rotation_ofBackwardCone = Quaternion.LookRotation(-directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, Vector3.zero); + Get_posOfPlusButtonCones(out Vector3 posOf_forwardCone_beforeDrag_inUnitsOfGlobalSpace, out Vector3 posOf_backwardCone_beforeDrag_inUnitsOfGlobalSpace, posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace, directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, handleSize); + + Start_handlesChangeCheck(); + float pos0to1_insideSegment_ofPlusButton_afterDragOfForwardCone = InternalDXXL_BezierHandles.ValueSliderAlongCurve(pos0to1_insideSegment_ofPlusButton_beforeDrag, posOf_forwardCone_beforeDrag_inUnitsOfGlobalSpace, rotation_ofForwardCone, directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, handleSize, Handles.ConeHandleCap, 1.0f); + bool forwardCone_hasChanged = End_handlesChangeCheck("Shift Button on Spline", i, false); + + Start_handlesChangeCheck(); + float pos0to1_insideSegment_ofPlusButton_afterDragOfBackwardCone = InternalDXXL_BezierHandles.ValueSliderAlongCurve(pos0to1_insideSegment_ofPlusButton_beforeDrag, posOf_backwardCone_beforeDrag_inUnitsOfGlobalSpace, rotation_ofBackwardCone, directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, handleSize, Handles.ConeHandleCap, 1.0f); + bool backwardCone_hasChanged = End_handlesChangeCheck("Shift Button on Spline", i, false); + + if (forwardCone_hasChanged) { Update_progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment(pos0to1_insideSegment_ofPlusButton_afterDragOfForwardCone, concernedControlPoint); } + if (backwardCone_hasChanged) { Update_progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment(pos0to1_insideSegment_ofPlusButton_afterDragOfBackwardCone, concernedControlPoint); } + + bool buttonHasBeenClicked = InternalDXXL_BezierHandles.PlusButton(posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.handleSizeOf_plusButtons, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, sceneViewCamForward_normalized, sceneViewCamUp_normalized, sceneViewCamRight_normalized, plusSymbolIcon); + if (buttonHasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CreateNewControlPoint_somewhereOnUpcomingSplineSegment(i); + } + } + } + } + + void Get_posOfPlusButtonCones(out Vector3 posOf_forwardCone_beforeDrag_inUnitsOfGlobalSpace, out Vector3 posOf_backwardCone_beforeDrag_inUnitsOfGlobalSpace, Vector3 posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace, Vector3 directionOfConeForShifting_inUnitsOfGlobalSpace_normalized, float handleSize) + { + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 unused1, out Vector3 unused2, out Vector3 unused3, out Vector3 sceneViewCam_to_plusButton, posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace, DrawBasics.CameraForAutomaticOrientation.sceneViewCamera); + float acuteAngleDeg0to90_betweenObserverViewDir_andCurveTangent = UtilitiesDXXL_Math.AcuteAngle_0to90(sceneViewCam_to_plusButton, directionOfConeForShifting_inUnitsOfGlobalSpace_normalized); + acuteAngleDeg0to90_betweenObserverViewDir_andCurveTangent = Mathf.Max(acuteAngleDeg0to90_betweenObserverViewDir_andCurveTangent, 15.0f); + + float offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton = 1.0f / Mathf.Sin(acuteAngleDeg0to90_betweenObserverViewDir_andCurveTangent * Mathf.Deg2Rad); + float offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofForwardConeHandle; + float offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofBackwardConeHandle; + + bool curveDirectionGoesAwayFromSceneViewCamera = (Vector3.Dot(sceneViewCam_to_plusButton, directionOfConeForShifting_inUnitsOfGlobalSpace_normalized) > 0.0f); + if (curveDirectionGoesAwayFromSceneViewCamera) + { + offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofForwardConeHandle = 1.0f; + offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofBackwardConeHandle = offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton; + } + else + { + offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofForwardConeHandle = offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton; + offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofBackwardConeHandle = 1.0f; + } + + float relConeOffset_ifObservingCamViesPerp = 0.75f; + float offsetOfForwardConeHandle = handleSize * relConeOffset_ifObservingCamViesPerp * offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofForwardConeHandle; + float offsetOfBackwardConeHandle = handleSize * relConeOffset_ifObservingCamViesPerp * offsetFactor_toCompensateViewAngle_andMakeConesStillPeekOutBehindPlusButton_ofBackwardConeHandle; + + posOf_forwardCone_beforeDrag_inUnitsOfGlobalSpace = posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace + directionOfConeForShifting_inUnitsOfGlobalSpace_normalized * offsetOfForwardConeHandle; + posOf_backwardCone_beforeDrag_inUnitsOfGlobalSpace = posOfPlusButton_beforeDrag_inUnitsOfGlobalSpace - directionOfConeForShifting_inUnitsOfGlobalSpace_normalized * offsetOfBackwardConeHandle; + } + + void Update_progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment(float pos0to1_insideSegment_ofPlusButton_afterDrag, InternalDXXL_BezierControlPointTriplet concernedControlPoint) + { + pos0to1_insideSegment_ofPlusButton_afterDrag = Mathf.Clamp(pos0to1_insideSegment_ofPlusButton_afterDrag, 0.05f, 0.95f); + concernedControlPoint.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment = pos0to1_insideSegment_ofPlusButton_afterDrag; + } + + public enum PartOfTripleHandleCompound { center, forward, backward } + PartOfTripleHandleCompound nearest_anchorSubHandle; + PartOfTripleHandleCompound middle_anchorSubHandle; + PartOfTripleHandleCompound farest_anchorSubHandle; + + void DrawCustomHandlesAtSubPoints(int i) + { + Determine_nearestMiddleFarestSubHandle(i); + + DrawCustomHandleAtASubPoint(farest_anchorSubHandle, i); + DrawCustomHandleAtASubPoint(middle_anchorSubHandle, i); + DrawCustomHandleAtASubPoint(nearest_anchorSubHandle, i); + } + + void Determine_nearestMiddleFarestSubHandle(int i) + { + float dotProduct_camViewDir_directionOfForwardCone = Vector3.Dot(sceneViewCam_to_anchorPoint, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized); + float dotProduct_camViewDir_directionOfBackwardCone = Vector3.Dot(sceneViewCam_to_anchorPoint, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized); + + if ((dotProduct_camViewDir_directionOfForwardCone > 0.0f) && (dotProduct_camViewDir_directionOfBackwardCone > 0.0f)) + { + nearest_anchorSubHandle = PartOfTripleHandleCompound.center; + if (dotProduct_camViewDir_directionOfForwardCone > dotProduct_camViewDir_directionOfBackwardCone) + { + middle_anchorSubHandle = PartOfTripleHandleCompound.backward; + farest_anchorSubHandle = PartOfTripleHandleCompound.forward; + } + else + { + middle_anchorSubHandle = PartOfTripleHandleCompound.forward; + farest_anchorSubHandle = PartOfTripleHandleCompound.backward; + } + } + else + { + if ((dotProduct_camViewDir_directionOfForwardCone < 0.0f) && (dotProduct_camViewDir_directionOfBackwardCone < 0.0f)) + { + farest_anchorSubHandle = PartOfTripleHandleCompound.center; + if (dotProduct_camViewDir_directionOfForwardCone < dotProduct_camViewDir_directionOfBackwardCone) + { + nearest_anchorSubHandle = PartOfTripleHandleCompound.forward; + middle_anchorSubHandle = PartOfTripleHandleCompound.backward; + } + else + { + nearest_anchorSubHandle = PartOfTripleHandleCompound.backward; + middle_anchorSubHandle = PartOfTripleHandleCompound.forward; + } + } + else + { + middle_anchorSubHandle = PartOfTripleHandleCompound.center; + if (dotProduct_camViewDir_directionOfForwardCone < 0.0f) + { + nearest_anchorSubHandle = PartOfTripleHandleCompound.forward; + farest_anchorSubHandle = PartOfTripleHandleCompound.backward; + } + else + { + nearest_anchorSubHandle = PartOfTripleHandleCompound.backward; + farest_anchorSubHandle = PartOfTripleHandleCompound.forward; + } + } + } + } + + void DrawCustomHandleAtASubPoint(PartOfTripleHandleCompound subHandleToDraw, int i) + { + switch (subHandleToDraw) + { + case PartOfTripleHandleCompound.center: + DrawAnchorPointsCustomHandle(i); + break; + case PartOfTripleHandleCompound.forward: + DrawAHelperPointHandle(i, true); + break; + case PartOfTripleHandleCompound.backward: + DrawAHelperPointHandle(i, false); + break; + default: + break; + } + } + + void DrawAnchorPointsCustomHandle(int i) + { + if (bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_anchorPoints) + { + Handles.color = bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints; + + float size_ofAnchorPointsCustomHandle = bezierSplineDrawer_unserializedMonoB.handleSizeOf_customHandle_atAnchors * HandleUtility.GetHandleSize(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace()); + + bool drawForwardCone_ofAnchorPointsCustomHandle = CheckIf_drawForwardCone_ofAnchorPointsCustomHandle(i); + bool drawBackwardCone_ofAnchorPointsCustomHandle = CheckIf_drawBackwardCone_ofAnchorPointsCustomHandle(i); + + if (drawForwardCone_ofAnchorPointsCustomHandle) { TryRecalcHandleDirectionOfForwardConeOnAnchorHandle(i); } + if (drawBackwardCone_ofAnchorPointsCustomHandle) { TryRecalcHandleDirectionOfBackwardConeOnAnchorHandle(i); } + + bool flipBackwardCone_dueToIsLastControlPointOfNonClosedSpline = FlipDirectionOfAnchorPointsCustomHandleBackwardCone(i); + if (flipBackwardCone_dueToIsLastControlPointOfNonClosedSpline) + { + //-> "forward cone" (whichever of the three handles it may be) is always skipped here + //-> so this just flips the draw order of the remaining two subHandles: sphere and the backward cone + DrawASubHandle_ofAnchorPointsCustomHandle(nearest_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + DrawASubHandle_ofAnchorPointsCustomHandle(middle_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + DrawASubHandle_ofAnchorPointsCustomHandle(farest_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + } + else + { + DrawASubHandle_ofAnchorPointsCustomHandle(farest_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + DrawASubHandle_ofAnchorPointsCustomHandle(middle_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + DrawASubHandle_ofAnchorPointsCustomHandle(nearest_anchorSubHandle, i, drawForwardCone_ofAnchorPointsCustomHandle, drawBackwardCone_ofAnchorPointsCustomHandle, size_ofAnchorPointsCustomHandle); + } + } + } + + bool CheckIf_drawForwardCone_ofAnchorPointsCustomHandle(int i) + { + if ((bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed == false) && bezierSplineDrawer_unserializedMonoB.IsLastControlPoint(i)) + { + return false; + } + return true; + } + + void TryRecalcHandleDirectionOfForwardConeOnAnchorHandle(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_forwardCone_duringNextOnSceneGUI) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.isUsed) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + } + else + { + InternalDXXL_BezierControlSubPoint nextUsedNonSuperimposedSubPointAlongSplineDir = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + if (nextUsedNonSuperimposedSubPointAlongSplineDir != null) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized = (nextUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace() - bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace()).normalized; + } + else + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + } + } + } + + bool CheckIf_drawBackwardCone_ofAnchorPointsCustomHandle(int i) + { + if ((bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed == false) && (bezierSplineDrawer_unserializedMonoB.IsFirstControlPoint(i))) + { + return false; + } + + //note 1: for non-kinked juncture types the backwardHelper cannot be disabled (meaning "isUsed == true" is always guaranteed). Therefore the backward direction cone is always redundant and can be skipped, because it is the same as the forward direction. + //note 2: the one case, where no forward direction for non-kinked juncture-types would be possible is the splineEnd of non-closed splines. But such spline end points are always forced to "juncture=kinked", and therefore don't need special treatment here + return (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + } + + void TryRecalcHandleDirectionOfBackwardConeOnAnchorHandle(int i) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_backwardCone_duringNextOnSceneGUI) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.isUsed) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + } + else + { + InternalDXXL_BezierControlSubPoint previousUsedNonSuperimposedSubPointAlongSplineDir = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + if (previousUsedNonSuperimposedSubPointAlongSplineDir != null) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized = (previousUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace() - bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace()).normalized; + } + else + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized = (-bezierSplineDrawer_unserializedMonoB.Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized()); + } + } + } + } + + void DrawASubHandle_ofAnchorPointsCustomHandle(PartOfTripleHandleCompound subHandleToDraw, int i, bool drawForwardCone_ofAnchorPointsCustomHandle, bool drawBackwardCone_ofAnchorPointsCustomHandle, float size_ofAnchorPointsCustomHandle) + { + switch (subHandleToDraw) + { + case PartOfTripleHandleCompound.center: + DrawAnchorPointsCustomHandles_freeMoveSubHandle(i, size_ofAnchorPointsCustomHandle); + break; + case PartOfTripleHandleCompound.forward: + if (drawForwardCone_ofAnchorPointsCustomHandle) { DrawAnchorPointsCustomHandles_forwardConeSubHandle(i, size_ofAnchorPointsCustomHandle); } + break; + case PartOfTripleHandleCompound.backward: + if (drawBackwardCone_ofAnchorPointsCustomHandle) { DrawAnchorPointsCustomHandles_backwardConeSubHandle(i, size_ofAnchorPointsCustomHandle); } + break; + default: + break; + } + } + + void DrawAnchorPointsCustomHandles_freeMoveSubHandle(int i, float size_ofAnchorPointsCustomHandle) + { + Start_handlesChangeCheck(); +#if UNITY_2022_1_OR_NEWER + var fmh_813_318_639186733279200821 = Quaternion.identity; Vector3 pos_shiftedByFreeMoveHandle_inUnitsOfGlobalSpace = Handles.FreeMoveHandle(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.controlID_ofCustomHandles_sphere, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace(), size_ofAnchorPointsCustomHandle, Vector3.one, Handles.SphereHandleCap); +#else + Vector3 pos_shiftedByFreeMoveHandle_inUnitsOfGlobalSpace = Handles.FreeMoveHandle(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace(), Quaternion.identity, size_ofAnchorPointsCustomHandle, Vector3.one, Handles.SphereHandleCap); +#endif + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (hasChanged) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.SetPos_inUnitsOfGlobalSpace(pos_shiftedByFreeMoveHandle_inUnitsOfGlobalSpace, true, null); + } + } + + void DrawAnchorPointsCustomHandles_forwardConeSubHandle(int i, float size_ofAnchorPointsCustomHandle) + { + Vector3 posOffset_fromAnchorPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized * size_ofAnchorPointsCustomHandle; + Vector3 pos_ofForwardCone_beforeDrag_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace() + posOffset_fromAnchorPoint_inUnitsOfGlobalSpace; + + Start_handlesChangeCheck(); + Vector3 pos_ofForwardCone_afterDrag_inUnitsOfGlobalSpace = Handles.Slider(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.controlID_ofCustomHandles_forwardCone, pos_ofForwardCone_beforeDrag_inUnitsOfGlobalSpace, bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized, size_ofAnchorPointsCustomHandle, Handles.ConeHandleCap, 1.0f); + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (hasChanged) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_forwardCone_duringNextOnSceneGUI = false; //Without this there is strange flickering behaviour, see notes at "recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = false" + Vector3 posDifference_inUnitsOfGlobalSpace = pos_ofForwardCone_afterDrag_inUnitsOfGlobalSpace - pos_ofForwardCone_beforeDrag_inUnitsOfGlobalSpace; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.AddPosOffset_inUnitsOfGlobalSpace(posDifference_inUnitsOfGlobalSpace, true, null); + } + } + + void DrawAnchorPointsCustomHandles_backwardConeSubHandle(int i, float size_ofAnchorPointsCustomHandle) + { + bool flipDirectionOfCone = FlipDirectionOfAnchorPointsCustomHandleBackwardCone(i); + Vector3 posOffset_fromAnchorPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized * size_ofAnchorPointsCustomHandle; + if (flipDirectionOfCone) { posOffset_fromAnchorPoint_inUnitsOfGlobalSpace = -posOffset_fromAnchorPoint_inUnitsOfGlobalSpace; } + Vector3 pos_ofBackwardCone_beforeDrag_inUnitsOfGlobalSpace = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.GetPos_inUnitsOfGlobalSpace() + posOffset_fromAnchorPoint_inUnitsOfGlobalSpace; + Vector3 usedDirection_inUnitsOfGlobalSpace = flipDirectionOfCone ? (-bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized) : bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized; + + Start_handlesChangeCheck(); + Vector3 pos_ofBackwardCone_afterDrag_inUnitsOfGlobalSpace = Handles.Slider(bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.controlID_ofCustomHandles_backwardCone, pos_ofBackwardCone_beforeDrag_inUnitsOfGlobalSpace, usedDirection_inUnitsOfGlobalSpace, size_ofAnchorPointsCustomHandle, Handles.ConeHandleCap, 1.0f); + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (hasChanged) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_backwardCone_duringNextOnSceneGUI = false; //Without this there is strange flickering behaviour, see notes at "recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = false" + Vector3 posDifference_inUnitsOfGlobalSpace = pos_ofBackwardCone_afterDrag_inUnitsOfGlobalSpace - pos_ofBackwardCone_beforeDrag_inUnitsOfGlobalSpace; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.AddPosOffset_inUnitsOfGlobalSpace(posDifference_inUnitsOfGlobalSpace, true, null); + } + } + + bool FlipDirectionOfAnchorPointsCustomHandleBackwardCone(int i) + { + //-> this is only for visual continuity (because the default case is that the conesAtAnchorHandles point along forwardOfSpline). + if (bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed == false) + { + if (bezierSplineDrawer_unserializedMonoB.IsLastControlPoint(i)) + { + return true; + } + } + return false; + } + + public enum PartOfHelperPointsCustomHandle { sphere, coneAlongHelperDirFromAnchor, coneAlongToNeighborsHelperDir, cylinderAlongHelperDirFromAnchor, cylinderAlongToNeighborsHelperDir } + PartOfHelperPointsCustomHandle nearest_helperSubHandle; + PartOfHelperPointsCustomHandle secondNearest_helperSubHandle; + PartOfHelperPointsCustomHandle middle_helperSubHandle; + PartOfHelperPointsCustomHandle secondFarest_helperSubHandle; + PartOfHelperPointsCustomHandle farest_helperSubHandle; + bool nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints; + bool secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints; + bool secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints; + bool farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints; + void DrawAHelperPointHandle(int i, bool helperHandleToDraw_isForwardNotBackward) + { + if (bezierSplineDrawer_unserializedMonoB.showCustomHandleFor_helperPoints) + { + InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetAHelperPoint(helperHandleToDraw_isForwardNotBackward); + if (concernedHelperPoint.isUsed) + { + Handles.color = bezierSplineDrawer_unserializedMonoB.color_ofHelperPoints; + + bool draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor = CheckIf_draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor(i, concernedHelperPoint); + bool draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir = CheckIf_draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir(i, concernedHelperPoint); + + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_helperPosition, concernedHelperPoint.GetPos_inUnitsOfGlobalSpace(), DrawBasics.CameraForAutomaticOrientation.sceneViewCamera); + + TryRecalc_directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized(concernedHelperPoint); + TryRecalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized(i, concernedHelperPoint); + TryRecalc_camPlane_inclinedIntoHandlesDir_inUnitsOfGlobalSpace(concernedHelperPoint); + + Determine_nearestMiddleAndFarestSubHandles_ofHelperPointsCustomHandle(concernedHelperPoint, cam_to_helperPosition); + + DrawASubHandle_ofHelperPointsCustomHandle(farest_helperSubHandle, farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, i, draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, concernedHelperPoint); + DrawASubHandle_ofHelperPointsCustomHandle(secondFarest_helperSubHandle, secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, i, draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, concernedHelperPoint); + DrawASubHandle_ofHelperPointsCustomHandle(middle_helperSubHandle, false, i, draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, concernedHelperPoint); + DrawASubHandle_ofHelperPointsCustomHandle(secondNearest_helperSubHandle, secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, i, draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, concernedHelperPoint); + DrawASubHandle_ofHelperPointsCustomHandle(nearest_helperSubHandle, nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, i, draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, concernedHelperPoint); + } + } + } + + bool CheckIf_draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor(int i, InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint) + { + if (concernedHelperPoint.GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + return false; + } + else + { + return (concernedHelperPoint.GetOppositeHelperPoint().isUsed); + } + } + + bool CheckIf_draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir(int i, InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint) + { + InternalDXXL_BezierControlPointTriplet neighboringControlPoint = concernedHelperPoint.Get_neighboringControlPoint(false); + if (neighboringControlPoint != null) + { + if (concernedHelperPoint.isForward_notBackward) + { + return neighboringControlPoint.backwardHelperPoint.isUsed; + } + else + { + return neighboringControlPoint.forwardHelperPoint.isUsed; + } + } + else + { + return false; + } + } + + void TryRecalc_directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized(InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint) + { + if (concernedHelperPoint.recalc_directionForHandles_alongLineWithMountingAnchor_duringNextOnSceneGUI) + { + if (concernedHelperPoint.isForward_notBackward) + { + concernedHelperPoint.directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = concernedHelperPoint.Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + } + else + { + concernedHelperPoint.directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = -concernedHelperPoint.Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + } + } + } + + void TryRecalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized(int i, InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint) + { + if (concernedHelperPoint.recalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_duringNextOnSceneGUI) + { + if (concernedHelperPoint.isForward_notBackward) + { + InternalDXXL_BezierControlSubPoint nextUsedNonSuperimposedSubPointAlongSplineDir = concernedHelperPoint.GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + + if (nextUsedNonSuperimposedSubPointAlongSplineDir != null) + { + concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = (nextUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace() - concernedHelperPoint.GetPos_inUnitsOfGlobalSpace()).normalized; + } + else + { + concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + } + else + { + InternalDXXL_BezierControlSubPoint previousUsedNonSuperimposedSubPointAlongSplineDir = concernedHelperPoint.GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + if (previousUsedNonSuperimposedSubPointAlongSplineDir != null) + { + concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = (concernedHelperPoint.GetPos_inUnitsOfGlobalSpace() - previousUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace()).normalized; + } + else + { + concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + } + } + } + + void TryRecalc_camPlane_inclinedIntoHandlesDir_inUnitsOfGlobalSpace(InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint) + { + if (concernedHelperPoint.recalc_handlesPlanesThatShouldntBeRecalcedDuringDrag_duringNextOnSceneGUI) + { + Vector3 planePoint1 = concernedHelperPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 planePoint1_to_planePoint2 = concernedHelperPoint.Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + Vector3 planePoint2 = planePoint1 + planePoint1_to_planePoint2; + Vector3 perpTo_handleDir_andTo_camViewDir = Vector3.Cross(planePoint1_to_planePoint2, sceneViewCam_to_anchorPoint); + + if (UtilitiesDXXL_Math.ApproximatelyZero(perpTo_handleDir_andTo_camViewDir)) + { + //-> handles direction is parallel to the view direction of the observing sceneViewCamera + concernedHelperPoint.camPlane_inclinedIntoHandlesDir_inUnitsOfGlobalSpace.Recreate(planePoint1, sceneViewCam_to_anchorPoint); + } + else + { + Vector3 planePoint3 = planePoint1 + perpTo_handleDir_andTo_camViewDir; + concernedHelperPoint.camPlane_inclinedIntoHandlesDir_inUnitsOfGlobalSpace.Recreate(planePoint1, planePoint2, planePoint3); + } + } + } + + void Determine_nearestMiddleAndFarestSubHandles_ofHelperPointsCustomHandle(InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint, Vector3 cam_to_helperPosition) + { + middle_helperSubHandle = PartOfHelperPointsCustomHandle.sphere; + + float dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor = Vector3.Dot(cam_to_helperPosition, concernedHelperPoint.directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized); + float dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir = Vector3.Dot(cam_to_helperPosition, concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized); + if ((dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor > 0.0f) && (dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir > 0.0f)) + { + //both dirs point AWAY from camera: + if (dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor > dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir) + { + //"dirAlongLineWithAnchor" points STEEPER away from camera than "dir_toNeighborOfNeighbor": + nearest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + secondNearest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + secondFarest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + farest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + } + else + { + //"dir_toNeighborOfNeighbor" points STEEPER away from camera than "dirAlongLineWithAnchor": + nearest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + secondNearest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + secondFarest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + farest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + } + } + else + { + if ((dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor < 0.0f) && (dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir < 0.0f)) + { + //both dirs point TOWARDS camera: + if (dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor < dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir) + { + //"dirAlongLineWithAnchor" points STEEPER towards camera than "dir_toNeighborOfNeighbor": + nearest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + secondNearest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + secondFarest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + farest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + } + else + { + //"dir_toNeighborOfNeighbor" points STEEPER towards camera than "dirAlongLineWithAnchor": + nearest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + secondNearest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + secondFarest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + farest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + } + } + else + { + if ((dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor > 0.0f) && (dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir < 0.0f)) + { + //"dirAlongLineWithAnchor" points AWAY from camera, "dir_toNeighborOfNeighbor" points TOWARDS camera: + float abs_dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir = -dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir; + if (dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor > abs_dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir) + { + //"dirAlongLineWithAnchor" points STEEPER away from camera than "(cylinder)dir_toNeighborOfNeighbor": + nearest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + secondNearest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + secondFarest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + farest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + } + else + { + //"(cylinder)dir_toNeighborOfNeighbor" points STEEPER away from camera than "dirAlongLineWithAnchor": + nearest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + secondNearest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + secondFarest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + farest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + } + } + else + { + //"dirAlongLineWithAnchor" points TOWARDS camera, "dir_toNeighborOfNeighbor" points AWAY from camera: + float abs_dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor = -dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor; + if (abs_dotProduct_camViewDir_directionOfConeAlongHelperDirFromAnchor > dotProduct_camViewDir_directionOfConeAlongToNeighborsHelperDir) + { + //"(cylinder)dirAlongLineWithAnchor" points STEEPER away from camera than "dir_toNeighborOfNeighbor": + nearest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + secondNearest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + secondFarest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + farest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + } + else + { + //"dir_toNeighborOfNeighbor" points STEEPER away from camera than "(cylinder)dirAlongLineWithAnchor": + nearest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir; + secondNearest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor; + secondFarest_helperSubHandle = PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor; + farest_helperSubHandle = PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir; + + nearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + secondNearest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + secondFarest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = true; + farest_helperSubHandle_belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints = false; + } + } + } + } + } + + public static float scaleFactor_forCylinderHandles = 0.75f; + public static float offsetFactor_forCylinderHandles = 1.2f; + void DrawASubHandle_ofHelperPointsCustomHandle(PartOfHelperPointsCustomHandle subHandleToDraw, bool belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, int i, bool draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor, bool draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir, InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint) + { + float handleSize_unmodified = bezierSplineDrawer_unserializedMonoB.handleSizeOf_customHandle_atHelpers * HandleUtility.GetHandleSize(concernedHelperPoint.GetPos_inUnitsOfGlobalSpace()); + switch (subHandleToDraw) + { + case PartOfHelperPointsCustomHandle.sphere: + DrawHelperPointsCustomHandles_sphereHandle(i, concernedHelperPoint.controlID_ofCustomHandles_sphere, concernedHelperPoint, handleSize_unmodified); + break; + case PartOfHelperPointsCustomHandle.coneAlongHelperDirFromAnchor: + DrawAnUnidirectionalSubHandle_ofHelperPointsCustomHandle(i, concernedHelperPoint.controlID_ofCustomHandles_coneAlongLineWithAnchor, concernedHelperPoint, 1.0f, handleSize_unmodified, Handles.ConeHandleCap, belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, true, false, false); + break; + case PartOfHelperPointsCustomHandle.coneAlongToNeighborsHelperDir: + DrawAnUnidirectionalSubHandle_ofHelperPointsCustomHandle(i, concernedHelperPoint.controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper, concernedHelperPoint, 1.0f, handleSize_unmodified, Handles.ConeHandleCap, belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, false, false, false); + break; + case PartOfHelperPointsCustomHandle.cylinderAlongHelperDirFromAnchor: + if (draw_helperPointsCustomHandles_cylinderAlongHelperDirFromAnchor) + { + DrawAnUnidirectionalSubHandle_ofHelperPointsCustomHandle(i, concernedHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithAnchor, concernedHelperPoint, -1.0f * offsetFactor_forCylinderHandles, scaleFactor_forCylinderHandles * handleSize_unmodified, Handles.CylinderHandleCap, belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, false, true, false); + } + break; + case PartOfHelperPointsCustomHandle.cylinderAlongToNeighborsHelperDir: + if (draw_helperPointsCustomHandles_cylinderAlongToNeighborsHelperDir) + { + DrawAnUnidirectionalSubHandle_ofHelperPointsCustomHandle(i, concernedHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper, concernedHelperPoint, -1.0f * offsetFactor_forCylinderHandles, scaleFactor_forCylinderHandles * handleSize_unmodified, Handles.CylinderHandleCap, belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, false, false, true); + } + break; + default: + break; + } + } + + void DrawHelperPointsCustomHandles_sphereHandle(int i, int controlID_ofHandle, InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint, float handleSize) + { + Start_handlesChangeCheck(); +#if UNITY_2022_1_OR_NEWER + var fmh_1188_188_639186733279248814 = Quaternion.identity; Vector3 posOfSphereHandle_afterDrag_shifedInsideCamPlane_inUnitsOfGlobalSpace = Handles.FreeMoveHandle(controlID_ofHandle, concernedHelperPoint.GetPos_inUnitsOfGlobalSpace(), handleSize, Vector3.one, Handles.SphereHandleCap); +#else + Vector3 posOfSphereHandle_afterDrag_shifedInsideCamPlane_inUnitsOfGlobalSpace = Handles.FreeMoveHandle(concernedHelperPoint.GetPos_inUnitsOfGlobalSpace(), Quaternion.identity, handleSize, Vector3.one, Handles.SphereHandleCap); +#endif + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (hasChanged) + { + concernedHelperPoint.recalc_handlesPlanesThatShouldntBeRecalcedDuringDrag_duringNextOnSceneGUI = false; + + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_posOfSphereHandleAfterDragShifedInsideCamPlane, posOfSphereHandle_afterDrag_shifedInsideCamPlane_inUnitsOfGlobalSpace, DrawBasics.CameraForAutomaticOrientation.sceneViewCamera); + Vector3 posOfSphereHandle_afterDrag_shifedInsideHandlesPlane_inUnitsOfGlobalSpace = concernedHelperPoint.camPlane_inclinedIntoHandlesDir_inUnitsOfGlobalSpace.Get_projectionOfPointOnPlane_alongCustomDir(posOfSphereHandle_afterDrag_shifedInsideCamPlane_inUnitsOfGlobalSpace, cam_to_posOfSphereHandleAfterDragShifedInsideCamPlane); + concernedHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfSphereHandle_afterDrag_shifedInsideHandlesPlane_inUnitsOfGlobalSpace, true, null); + } + } + + void DrawAnUnidirectionalSubHandle_ofHelperPointsCustomHandle(int i, int controlID_ofHandle, InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint, float handlePosOffsetFactorAlongDir, float handleSize, Handles.CapFunction capFunction, bool belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints, bool tryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint, bool mirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint, bool mirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint) + { + Vector3 dragDirection_inUnitsOfGlobalSpace_normalized = belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints ? concernedHelperPoint.directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized : concernedHelperPoint.directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized; + Vector3 handleOffset = dragDirection_inUnitsOfGlobalSpace_normalized * handleSize * handlePosOffsetFactorAlongDir; + Vector3 posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace = concernedHelperPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 posOfConeHandle_beforeDrag_inUnitsOfGlobalSpace = posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace + handleOffset; + + Start_handlesChangeCheck(); + Vector3 posOfConeHandle_afterDrag_inUnitsOfGlobalSpace = Handles.Slider(controlID_ofHandle, posOfConeHandle_beforeDrag_inUnitsOfGlobalSpace, dragDirection_inUnitsOfGlobalSpace_normalized, handleSize, capFunction, 1.0f); + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + if (hasChanged) + { + if (belongsTo_lineFromAnchor_notTo_lineBetweenNeighboringHelperPoints) + { + concernedHelperPoint.recalc_directionForHandles_alongLineWithMountingAnchor_duringNextOnSceneGUI = false; + } + else + { + concernedHelperPoint.recalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_duringNextOnSceneGUI = false; + } + + Vector3 shiftOffset_throughDragSlider_inUnitsOfGlobalSpace = posOfConeHandle_afterDrag_inUnitsOfGlobalSpace - posOfConeHandle_beforeDrag_inUnitsOfGlobalSpace; + Vector3 posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace = posOfConeHandle_afterDrag_inUnitsOfGlobalSpace - handleOffset; + + TryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint(concernedHelperPoint, tryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint, posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace, posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace); + + float absDistanceToMountingAnchorPoint_beforeDrag_inUnitsOfGlobalSpace = concernedHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + concernedHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace, true, null); + float absDistanceToMountingAnchorPoint_afterDrag_inUnitsOfGlobalSpace = concernedHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + + TryMirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint(concernedHelperPoint, mirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint, absDistanceToMountingAnchorPoint_beforeDrag_inUnitsOfGlobalSpace, absDistanceToMountingAnchorPoint_afterDrag_inUnitsOfGlobalSpace); + TryMirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint(i, concernedHelperPoint, mirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint, shiftOffset_throughDragSlider_inUnitsOfGlobalSpace); + } + } + + void TryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint(InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint, bool tryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint, Vector3 posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace, Vector3 posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace) + { + if (tryChangeStateOf_helperPointsAreOnSameSide_afterPassingTheAnchorPoint) + { + if (concernedHelperPoint.isUsed && concernedHelperPoint.GetOppositeHelperPoint().isUsed) + { + if (concernedHelperPoint.GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned) + { + Vector3 anchor_to_helperPosBeforeDrag = posOfHelperPoint_beforeDrag_inUnitsOfGlobalSpace - concernedHelperPoint.GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace(); + Vector3 anchor_to_helperPosAfterDrag = posOfHelperPoint_afterDrag_inUnitsOfGlobalSpace - concernedHelperPoint.GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace(); + float dotProduct_ofDirectionFromAnchorToConcernedHelper_beforeAndAfterDrag = Vector3.Dot(anchor_to_helperPosBeforeDrag, anchor_to_helperPosAfterDrag); + bool coneSliderPassedTheMountingAnchorPoint = (dotProduct_ofDirectionFromAnchorToConcernedHelper_beforeAndAfterDrag < 0.0f); + if (coneSliderPassedTheMountingAnchorPoint) + { + concernedHelperPoint.Get_controlPointTriplet_thisSubPointIsPartOf().Invert_alignedHelperPoints_areOnTheSameSideOfTheAnchor(); + } + } + } + } + } + + void TryMirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint(InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint, bool mirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint, float absDistanceToMountingAnchorPoint_beforeDrag_inUnitsOfGlobalSpace, float absDistanceToMountingAnchorPoint_afterDrag_inUnitsOfGlobalSpace) + { + if (mirrorDistanceChangeRatio_ontoOtherHelperPointOfSameControlPoint) + { + float absChangeRatio_ofDistance_throughSliderDrag = absDistanceToMountingAnchorPoint_afterDrag_inUnitsOfGlobalSpace / absDistanceToMountingAnchorPoint_beforeDrag_inUnitsOfGlobalSpace; + if (UtilitiesDXXL_Math.FloatIsValid(absChangeRatio_ofDistance_throughSliderDrag)) + { + float newAbsDistanceToAnchorPoint_ofOppositeHelperPoint_inUnitsOfGlobalSpace = concernedHelperPoint.GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace() * absChangeRatio_ofDistance_throughSliderDrag; + concernedHelperPoint.GetOppositeHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistanceToAnchorPoint_ofOppositeHelperPoint_inUnitsOfGlobalSpace, true, null); //-> oppositeHelperPoint is guaranteed "isUsed = true" here + //bool cylinderSliderPassedTheMountingAnchorPoint -> No further action required because "concernedHelperPoint.SetPos_inUnitsOfGlobalSpace()" already executed the "flip" of the other helper side. + } + } + } + + void TryMirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint(int i, InternalDXXL_BezierControlHelperSubPoint concernedHelperPoint, bool mirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint, Vector3 shiftOffset_throughDragSlider_inUnitsOfGlobalSpace) + { + if (mirrorPosChange_ontoNeighboringHelperPointOfNeighboringControlPoint) + { + InternalDXXL_BezierControlHelperSubPoint neighboringHelperPoint_ofNeighboringControlPoint = concernedHelperPoint.Get_neighboringHelperPoint_ofNeighboringControlPoint(false); + if (neighboringHelperPoint_ofNeighboringControlPoint != null) + { + neighboringHelperPoint_ofNeighboringControlPoint.AddPosOffset_inUnitsOfGlobalSpace(-shiftOffset_throughDragSlider_inUnitsOfGlobalSpace, true, null); + } + } + } + + void DrawUnitysBuildInHandlesAtSubPoints(int i) + { + //Cannot draw these handles in "back-to-front"-order as "DrawCustomHandlesAtSubPoints()" does, because the control_ID's of these handles are created automatically by Unity in the order of calling. The control_ID's change if the order of calling changes. + //If during a handle drag one of the handles here "overtakes" another handle in the race for "camera nearness", then the control_ID's change and the handle focus suddenly jumps to another handle, which from then on takes the rest of the mouse drag delta. + //It could be improved in Unity2022, because there are further overloads of "Handles.PositionHandle" and "Handles.RotationHandle" available where the control_ID can be explicitly defined + InternalDXXL_BezierControlPointTriplet concernedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + TryDrawAUnityRotationHandle(i); + TryDrawAUnityPositionHandle(i, concernedControlPoint.backwardHelperPoint); + TryDrawAUnityPositionHandle(i, concernedControlPoint.forwardHelperPoint); + TryDrawAUnityPositionHandle(i, concernedControlPoint.anchorPoint); + } + + void TryDrawAUnityPositionHandle(int i, InternalDXXL_BezierControlSubPoint concernedSubPoint) + { + if (CheckIf_drawPositionHandle(concernedSubPoint)) + { + if (concernedSubPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI) { Recalc_globalRotation_ofPositionHandle(concernedSubPoint); } + + float handleSize = (concernedSubPoint.subPointType == InternalDXXL_BezierControlSubPoint.SubPointType.anchor) ? bezierSplineDrawer_unserializedMonoB.handleSizeFor_position_atAnchors : bezierSplineDrawer_unserializedMonoB.handleSizeFor_position_atHelpers; + Matrix4x4 matrix_identityButScaled = Matrix4x4.Scale(handleSize * Vector3.one); + Handles.matrix = matrix_identityButScaled; + + Start_handlesChangeCheck(); + Vector3 pos_shiftedByPositionHandle_inUnitsOfGlobalSpace = handleSize * Handles.PositionHandle(concernedSubPoint.GetPos_inUnitsOfGlobalSpace() / handleSize, concernedSubPoint.globalRotation_ofPositionHandle); + bool hasChanged = End_handlesChangeCheck("Position of Bezier Point", i, true); + + Handles.matrix = Matrix4x4.identity; + + if (hasChanged) + { + concernedSubPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = false; //Without this there is strange flickering behaviour, maybe due to some internals of how "Handles.PositionHandle()" works. The flickering appears for "Editor.pivotMode=local" when you grab a the position handle that points to the neighboring control point and then get nearer towards this other control point. + concernedSubPoint.SetPos_inUnitsOfGlobalSpace(pos_shiftedByPositionHandle_inUnitsOfGlobalSpace, true, null); + } + } + } + + bool CheckIf_drawPositionHandle(InternalDXXL_BezierControlSubPoint concernedSubPoint) + { + if (concernedSubPoint.subPointType == InternalDXXL_BezierControlSubPoint.SubPointType.anchor) + { + return (bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atAnchors && concernedSubPoint.isUsed); + } + else + { + return (bezierSplineDrawer_unserializedMonoB.showHandleFor_position_atHelpers && concernedSubPoint.isUsed); + } + } + + void Recalc_globalRotation_ofPositionHandle(InternalDXXL_BezierControlSubPoint concernedSubPoint) + { + switch (Tools.pivotRotation) + { + case PivotRotation.Local: + concernedSubPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (concernedSubPoint.boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled && (concernedSubPoint.subPointType == InternalDXXL_BezierControlSubPoint.SubPointType.anchor)) + { + concernedSubPoint.globalRotation_ofPositionHandle = concernedSubPoint.boundGameobject.transform.rotation; + } + else + { + Recalc_globalRotation_ofPositionHandle_caseLocalPivotWithoutBoundGameobject(concernedSubPoint); + } + break; + case PivotRotation.Global: + Recalc_globalRotation_ofPositionHandle_caseGlobalPivot(concernedSubPoint); + break; + default: + break; + } + } + + void Recalc_globalRotation_ofPositionHandle_caseLocalPivotWithoutBoundGameobject(InternalDXXL_BezierControlSubPoint concernedSubPoint) + { + Vector3 posOfConcernedSubPoint_inUnitsOfGlobalSpace = concernedSubPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 posOfNextNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace = posOfConcernedSubPoint_inUnitsOfGlobalSpace; + Vector3 posOfPreviousNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace = posOfConcernedSubPoint_inUnitsOfGlobalSpace; + bool the3MountingPointsLieOnALine_soThePlaneIsUndefined = false; + + InternalDXXL_BezierControlSubPoint nextUsedNonSuperimposedSubPointAlongSplineDir = concernedSubPoint.GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + if (nextUsedNonSuperimposedSubPointAlongSplineDir != null) + { + posOfNextNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace = nextUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace(); + } + else + { + the3MountingPointsLieOnALine_soThePlaneIsUndefined = true; + } + + InternalDXXL_BezierControlSubPoint previousUsedNonSuperimposedSubPointAlongSplineDir = concernedSubPoint.GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + if (previousUsedNonSuperimposedSubPointAlongSplineDir != null) + { + posOfPreviousNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace = previousUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace(); + } + else + { + the3MountingPointsLieOnALine_soThePlaneIsUndefined = true; + } + + Vector3 normalOfPlane_inUnitsOfGlobalSpace_notNormalized = Vector3.forward; + if (the3MountingPointsLieOnALine_soThePlaneIsUndefined == false) + { + Vector3 planeMountingVector1_inUnitsOfGlobalSpace = posOfConcernedSubPoint_inUnitsOfGlobalSpace - posOfNextNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace; + Vector3 planeMountingVector2_inUnitsOfGlobalSpace = posOfConcernedSubPoint_inUnitsOfGlobalSpace - posOfPreviousNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace; + normalOfPlane_inUnitsOfGlobalSpace_notNormalized = Vector3.Cross(planeMountingVector1_inUnitsOfGlobalSpace, planeMountingVector2_inUnitsOfGlobalSpace); + + the3MountingPointsLieOnALine_soThePlaneIsUndefined = (UtilitiesDXXL_Math.GetBiggestAbsComponent(normalOfPlane_inUnitsOfGlobalSpace_notNormalized) < 0.001f); + } + + if (the3MountingPointsLieOnALine_soThePlaneIsUndefined) + { + Vector3 forwardDirectionPreferablyAlongHandleAxis_inUnitsOfGlobalSpace = concernedSubPoint.GetDirectionAlongSplineForwardBasedOnNeighborPoints_inUnitsOfGlobalSpace(); + if (UtilitiesDXXL_Math.ApproximatelyZero(forwardDirectionPreferablyAlongHandleAxis_inUnitsOfGlobalSpace)) + { + Recalc_globalRotation_ofPositionHandle_caseGlobalPivot(concernedSubPoint); + } + else + { + Vector3 up_ofActiveDrawSpace_normalized = bezierSplineDrawer_unserializedMonoB.Get_up_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + Vector3 up_ofCreatedRotation = Vector3.Cross(forwardDirectionPreferablyAlongHandleAxis_inUnitsOfGlobalSpace, up_ofActiveDrawSpace_normalized); + concernedSubPoint.globalRotation_ofPositionHandle = Quaternion.LookRotation(forwardDirectionPreferablyAlongHandleAxis_inUnitsOfGlobalSpace, up_ofCreatedRotation); + } + } + else + { + Vector3 rotation_forward = normalOfPlane_inUnitsOfGlobalSpace_notNormalized; + Vector3 rotation_up = posOfNextNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace - posOfPreviousNonSuperimposedSubPointAlongSpline_inUnitsOfGlobalSpace; + concernedSubPoint.globalRotation_ofPositionHandle = Quaternion.LookRotation(rotation_forward, rotation_up); + } + } + + void Recalc_globalRotation_ofPositionHandle_caseGlobalPivot(InternalDXXL_BezierControlSubPoint concernedSubPoint) + { + switch (bezierSplineDrawer_unserializedMonoB.drawSpace) + { + case BezierSplineDrawer.DrawSpace.global: + concernedSubPoint.globalRotation_ofPositionHandle = Quaternion.identity; + break; + case BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject: + Recalc_globalRotation_ofPositionHandle_caseGlobalPivotButLocalDrawSpace(concernedSubPoint); + break; + default: + break; + } + } + + void Recalc_globalRotation_ofPositionHandle_caseGlobalPivotButLocalDrawSpace(InternalDXXL_BezierControlSubPoint concernedSubPoint) + { + switch (bezierSplineDrawer_unserializedMonoB.positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal) + { + case BezierSplineDrawer.PositionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal.localDrawSpace: + concernedSubPoint.globalRotation_ofPositionHandle = bezierSplineDrawer_unserializedMonoB.transform.rotation; + break; + case BezierSplineDrawer.PositionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal.globalSpace: + concernedSubPoint.globalRotation_ofPositionHandle = Quaternion.identity; + break; + default: + break; + } + } + + void TryDrawAUnityRotationHandle(int i) + { + InternalDXXL_BezierControlPointTriplet concernedControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i]; + if (CheckIf_drawRotationHandle(concernedControlPoint)) + { + //-> In case of "junctureType == kinked" the FORWARD direction is connected to the rotation handle. The BACKWARD direction then can only be set indirectly via positionChange of the backwardHelperSubPoint. (Exception: if the forward helper is not available then it controls the backward direction as fallback) + + InternalDXXL_BezierControlAnchorSubPoint concernedAnchorPoint = concernedControlPoint.anchorPoint; + + if (concernedAnchorPoint.recalc_rotation_ofRotationHandleDuringRotationDragPhases_duringNextOnSceneGUI) { Calc_rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace(concernedAnchorPoint); } + + Matrix4x4 matrix_identityButScaled = Matrix4x4.Scale(bezierSplineDrawer_unserializedMonoB.handleSizeFor_rotation * Vector3.one); + Handles.matrix = matrix_identityButScaled; + + Start_handlesChangeCheck(); + Quaternion rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace = Handles.RotationHandle(concernedAnchorPoint.rotation_ofRotationHandleDuringRotationDragPhases, concernedAnchorPoint.GetPos_inUnitsOfGlobalSpace() / bezierSplineDrawer_unserializedMonoB.handleSizeFor_rotation); + bool hasChanged = End_handlesChangeCheck("Rotation of Bezier Point", i, true); + + Handles.matrix = Matrix4x4.identity; + + if (hasChanged) + { + concernedAnchorPoint.recalc_rotation_ofRotationHandleDuringRotationDragPhases_duringNextOnSceneGUI = false; + Set_rotation_afterChangeThroughRotationHandle(rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, concernedAnchorPoint.rotation_ofRotationHandleDuringRotationDragPhases, concernedAnchorPoint); + concernedAnchorPoint.rotation_ofRotationHandleDuringRotationDragPhases = rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace; + } + } + } + + bool CheckIf_drawRotationHandle(InternalDXXL_BezierControlPointTriplet concernedControlPoint) + { + if (bezierSplineDrawer_unserializedMonoB.showHandleFor_rotation) + { + return (concernedControlPoint.forwardHelperPoint.isUsed || concernedControlPoint.backwardHelperPoint.isUsed); + } + else + { + return false; + } + } + + void Calc_rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace(InternalDXXL_BezierControlAnchorSubPoint concernedAnchorPoint) + { + switch (Tools.pivotRotation) + { + case PivotRotation.Local: + concernedAnchorPoint.rotation_ofRotationHandleDuringRotationDragPhases = Get_rotation_ofRotationHandle_beforeRotate_caseLocalPivot(concernedAnchorPoint); + break; + case PivotRotation.Global: + concernedAnchorPoint.rotation_ofRotationHandleDuringRotationDragPhases = concernedAnchorPoint.rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation; + break; + default: + concernedAnchorPoint.rotation_ofRotationHandleDuringRotationDragPhases = Quaternion.identity; + break; + } + } + + Quaternion Get_rotation_ofRotationHandle_beforeRotate_caseLocalPivot(InternalDXXL_BezierControlAnchorSubPoint concernedAnchorPoint) + { + if (concernedAnchorPoint.CheckIf_boundGameobjectInfluencesRotation()) + { + return concernedAnchorPoint.boundGameobject.transform.rotation; + } + else + { + return Get_rotation_ofRotationHandle_beforeRotate_caseLocalPivotAndIndependenFromBoundGameobject(concernedAnchorPoint); + } + } + + Quaternion Get_rotation_ofRotationHandle_beforeRotate_caseLocalPivotAndIndependenFromBoundGameobject(InternalDXXL_BezierControlAnchorSubPoint concernedAnchorPoint) + { + Vector3 forwardDir_ofCreatedRotation_inUnitsOfGlobalSpace; //-> although the name is similar the "forward" here doesn't have to correspondend with the "forward" in "forwardHelper.direction" + if (concernedAnchorPoint.GetForwardHelperPoint().isUsed) + { + forwardDir_ofCreatedRotation_inUnitsOfGlobalSpace = concernedAnchorPoint.Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + } + else + { + forwardDir_ofCreatedRotation_inUnitsOfGlobalSpace = concernedAnchorPoint.Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + } + return Quaternion.LookRotation(forwardDir_ofCreatedRotation_inUnitsOfGlobalSpace, Vector3.zero); + } + + void Set_rotation_afterChangeThroughRotationHandle(Quaternion rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, Quaternion rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, InternalDXXL_BezierControlAnchorSubPoint concernedAnchorPoint) + { + switch (Tools.pivotRotation) + { + case PivotRotation.Local: + Set_rotation_afterChangeThroughRotationHandle_caseLocalPivot(rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, concernedAnchorPoint); + break; + case PivotRotation.Global: + Set_rotation_afterChangeThroughRotationHandle_caseGlobalPivot(rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, concernedAnchorPoint); + break; + default: + break; + } + } + + void Set_rotation_afterChangeThroughRotationHandle_caseLocalPivot(Quaternion rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, Quaternion rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, InternalDXXL_BezierControlAnchorSubPoint concernedAnchorPoint) + { + if (concernedAnchorPoint.CheckIf_boundGameobjectInfluencesRotation()) + { + Set_rotation_afterChangeThroughRotationHandle_caseLocalPivotAndRotIsDependentFromBoundGameobject(rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, concernedAnchorPoint); + } + else + { + Set_rotation_afterChangeThroughRotationHandle_caseLocalPivotAndIndependenFromBoundGameobject(rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, concernedAnchorPoint); + } + } + + void Set_rotation_afterChangeThroughRotationHandle_caseLocalPivotAndRotIsDependentFromBoundGameobject(Quaternion rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, Quaternion rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, InternalDXXL_BezierControlAnchorSubPoint concernedAnchorPoint) + { + concernedAnchorPoint.boundGameobject.transform.rotation = rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace; + if (concernedAnchorPoint.connectionComponent_onBoundGameobject != null) + { + concernedAnchorPoint.connectionComponent_onBoundGameobject.Transfer_aTransformDirection_fromBoundGameobject_toSpline(); + + //also update helperSides that are independent from a boundGameobject: + if (concernedAnchorPoint.junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + if (concernedAnchorPoint.GetBackwardHelperPoint().isUsed) + { + if (concernedAnchorPoint.GetBackwardHelperPoint().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture == InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject) + { + Quaternion rotationIncrement = GetRotationIncrement(rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace); + concernedAnchorPoint.AddRotation_toBackwardDirection(rotationIncrement, true, null); + } + } + + if (concernedAnchorPoint.GetForwardHelperPoint().isUsed) + { + if (concernedAnchorPoint.GetForwardHelperPoint().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture == InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject) + { + Quaternion rotationIncrement = GetRotationIncrement(rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace); + concernedAnchorPoint.AddRotation_toForwardDirection(rotationIncrement, true, null); + } + } + } + } + else + { + UtilitiesDXXL_Log.PrintErrorCode("49"); + } + } + + void Set_rotation_afterChangeThroughRotationHandle_caseLocalPivotAndIndependenFromBoundGameobject(Quaternion rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, Quaternion rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, InternalDXXL_BezierControlAnchorSubPoint concernedAnchorPoint) + { + Vector3 forwardDirection_ofRotationHandleAfterRotate_inUnitsOfGlobalSpace = rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace * Vector3.forward; //-> see comment inside "Get_rotation_ofRotationHandle_beforeRotate_caseLocalPivotAndIndependenFromBoundGameobject()" -> this doesn't have to be the same as "forwardHelper.direction" + if (concernedAnchorPoint.GetForwardHelperPoint().isUsed) + { + concernedAnchorPoint.Set_direction_toForward_inUnitsOfGlobalSpace_normalized(forwardDirection_ofRotationHandleAfterRotate_inUnitsOfGlobalSpace, true, null); + if (concernedAnchorPoint.junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + if (concernedAnchorPoint.GetBackwardHelperPoint().isUsed) + { + Quaternion rotationIncrement = GetRotationIncrement(rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace); + concernedAnchorPoint.AddRotation_toBackwardDirection(rotationIncrement, true, null); + } + } + } + else + { + if (concernedAnchorPoint.GetBackwardHelperPoint().isUsed) + { + concernedAnchorPoint.Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(forwardDirection_ofRotationHandleAfterRotate_inUnitsOfGlobalSpace, true, null); + } + } + } + + void Set_rotation_afterChangeThroughRotationHandle_caseGlobalPivot(Quaternion rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace, Quaternion rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, InternalDXXL_BezierControlAnchorSubPoint concernedAnchorPoint) + { + concernedAnchorPoint.rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation = rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace; + Quaternion rotationIncrement = GetRotationIncrement(rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace); + + if (concernedAnchorPoint.junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + if (concernedAnchorPoint.GetBackwardHelperPoint().isUsed) + { + concernedAnchorPoint.AddRotation_toBackwardDirection(rotationIncrement, true, null); + } + + if (concernedAnchorPoint.GetForwardHelperPoint().isUsed) + { + concernedAnchorPoint.AddRotation_toForwardDirection(rotationIncrement, true, null); + } + } + else + { + if (concernedAnchorPoint.GetForwardHelperPoint().isUsed) + { + concernedAnchorPoint.AddRotation_toForwardDirection(rotationIncrement, true, null); + } + else + { + if (concernedAnchorPoint.GetBackwardHelperPoint().isUsed) + { + concernedAnchorPoint.AddRotation_toBackwardDirection(rotationIncrement, true, null); + } + } + } + } + + Quaternion GetRotationIncrement(Quaternion rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace, Quaternion rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace) + { + Quaternion rotationIncrement = rotation_ofRotationHandle_afterRotate_inUnitsOfGlobalSpace * Quaternion.Inverse(rotation_ofRotationHandle_beforeRotate_inUnitsOfGlobalSpace); + rotationIncrement.Normalize(); //-> the quaternion difference multiplication seems to introduce non-normalized quaternions somehow, therefore normalizing here. + return rotationIncrement; + } + + void Reset_recalculationFlags_duringNoHandleClickedOrDraggedPhases(int i) + { + if (GUIUtility.hotControl == 0) //-> no handle is selcted or dragged = mouse button is not held down + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_forwardCone_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_directionForHandles_backwardCone_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_rotation_ofRotationHandleDuringRotationDragPhases_duringNextOnSceneGUI = true; + + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.recalc_directionForHandles_alongLineWithMountingAnchor_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.recalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.recalc_handlesPlanesThatShouldntBeRecalcedDuringDrag_duringNextOnSceneGUI = true; + + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.recalc_directionForHandles_alongLineWithMountingAnchor_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.recalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.recalc_handlesPlanesThatShouldntBeRecalcedDuringDrag_duringNextOnSceneGUI = true; + + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = true; + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint.recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = true; + } + } + + void ResetUndoRegistrationFlag_duringNoInteractionPhases() + { + if (GUIUtility.hotControl == 0) //-> no handle is selcted or dragged = mouse button is not held down + { + hasRegisteredUndo_sinceMouseDown = false; + } + } + + void Start_handlesChangeCheck() + { + EditorGUI.BeginChangeCheck(); + } + + bool End_handlesChangeCheck(string nameOfUndoEntry, int i_controlPointWithInteraction, bool markConcernedControlPoint_asSelected) + { + bool hasChanged = EditorGUI.EndChangeCheck(); + if (hasChanged) + { + TryRegisterStateForUndo(nameOfUndoEntry, true, false); + if (markConcernedControlPoint_asSelected) + { + bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i_controlPointWithInteraction); + } + } + return hasChanged; + } + + void TryRegisterStateForUndo(string nameOfUndoEntry, bool includeTransformsOfAllBoundGameobjects, bool includeConnectionComponentsOfAllBoundGameobjects) + { + if (hasRegisteredUndo_sinceMouseDown == false) + { + bezierSplineDrawer_unserializedMonoB.RegisterStateForUndo(nameOfUndoEntry, includeTransformsOfAllBoundGameobjects, includeConnectionComponentsOfAllBoundGameobjects); + hasRegisteredUndo_sinceMouseDown = true; + } + } + + void TrySetSelectedListSlot_dueToHandlesInteraction(int i) + { + InternalDXXL_BezierControlAnchorSubPoint anchorPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].anchorPoint; + InternalDXXL_BezierControlHelperSubPoint forwardHelperPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].forwardHelperPoint; + InternalDXXL_BezierControlHelperSubPoint backwardHelperPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].backwardHelperPoint; + + if (anchorPoint.controlID_ofCustomHandles_sphere == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (anchorPoint.controlID_ofCustomHandles_forwardCone == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (anchorPoint.controlID_ofCustomHandles_backwardCone == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + + if (forwardHelperPoint.controlID_ofCustomHandles_sphere == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (forwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithAnchor == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (forwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (forwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithAnchor == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (forwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + + if (backwardHelperPoint.controlID_ofCustomHandles_sphere == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (backwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithAnchor == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (backwardHelperPoint.controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (backwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithAnchor == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + if (backwardHelperPoint.controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper == GUIUtility.hotControl) { bezierSplineDrawer_unserializedMonoB.SetSelectedListSlot(i); } + } + + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + + serializedObject.Update(); + + float allowedConsumedLines_0to1 = DrawConsumedLines("spline curve"); + TryDrawInfoTextHowToReducedDrawnLines(allowedConsumedLines_0to1); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + + SerializedProperty sP_lineWidth = serializedObject.FindProperty("lineWidth"); + EditorGUILayout.PropertyField(sP_lineWidth, new GUIContent("Width")); + sP_lineWidth.floatValue = Mathf.Max(sP_lineWidth.floatValue, 0.0f); + + SerializedProperty sP_straightSubDivisionsPerSegment = serializedObject.FindProperty("straightSubDivisionsPerSegment"); + EditorGUILayout.PropertyField(sP_straightSubDivisionsPerSegment, new GUIContent("Resolution (=straight lines per bezier segment)")); + sP_straightSubDivisionsPerSegment.intValue = Mathf.Max(sP_straightSubDivisionsPerSegment.intValue, 3); + + DrawCloseRingToggle(); + DrawDrawSpaceSection(); + DrawHandlesSection(); + DrawControlPointsSection(); + DrawTextInputInclMarkupHelper(); + DrawCheckboxFor_drawOnlyIfSelected("Spline curve"); + DrawCheckboxFor_hiddenByNearerObjects("Spline curve"); + + serializedObject.ApplyModifiedProperties(); + ResetUndoRegistrationFlag_duringNoInteractionPhases(); + + EditorGUI.indentLevel = indentLevel_before; + } + + void TryDrawInfoTextHowToReducedDrawnLines(float allowedConsumedLines_0to1) + { + if (GUIUtility.hotControl == 0) //-> no handle is selcted or dragged = mouse button is not held down. Otherwise the warning box would disappear while the user drags the mentioned "Width"- or "Resolution"-field, which results in unconvenient line jumps. + { + if (allowedConsumedLines_0to1 > 0.5f) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(serializedObject.FindProperty("lineWidth").floatValue) == false) + { + if (serializedObject.FindProperty("straightSubDivisionsPerSegment").intValue > 20) + { + manyDrawnLinesWarningState = ManyDrawnLinesWarningState.reduceWidthAndResolution; + } + else + { + manyDrawnLinesWarningState = ManyDrawnLinesWarningState.reduceWidth; + } + } + else + { + if (serializedObject.FindProperty("straightSubDivisionsPerSegment").intValue > 10) + { + manyDrawnLinesWarningState = ManyDrawnLinesWarningState.reduceResolution; + } + else + { + manyDrawnLinesWarningState = ManyDrawnLinesWarningState.noWarning; + } + } + } + else + { + manyDrawnLinesWarningState = ManyDrawnLinesWarningState.noWarning; + } + } + + switch (manyDrawnLinesWarningState) + { + case ManyDrawnLinesWarningState.noWarning: + break; + case ManyDrawnLinesWarningState.reduceWidthAndResolution: + EditorGUILayout.HelpBox("Many drawn lines could be saved if 'Width' would be set to 0. Another option is to decrease the 'Resolution'.", MessageType.Info, true); + break; + case ManyDrawnLinesWarningState.reduceWidth: + EditorGUILayout.HelpBox("Many drawn lines could be saved if 'Width' would be set to 0.", MessageType.Info, true); + break; + case ManyDrawnLinesWarningState.reduceResolution: + EditorGUILayout.HelpBox("To save drawn lines it may help to decrease the 'Resolution'.", MessageType.Info, true); + break; + default: + break; + } + } + + void DrawDrawSpaceSection() //two times "Draw" in the name is in meant this way + { + SerializedProperty sP_drawSpaceSection_isOutfolded = serializedObject.FindProperty("drawSpaceSection_isOutfolded"); + sP_drawSpaceSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_drawSpaceSection_isOutfolded.boolValue, "Draw Space", true); + if (sP_drawSpaceSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + DrawDrawSpaceEnum(); + + SerializedProperty sP_keepWorldPos_duringDrawSpaceChange = serializedObject.FindProperty("keepWorldPos_duringDrawSpaceChange"); + sP_keepWorldPos_duringDrawSpaceChange.boolValue = EditorGUILayout.ToggleLeft(new GUIContent("Keep world position during space change", "If this is selected then the global position and shape of the spline will stay the same when the draw space gets changed." + Environment.NewLine + Environment.NewLine + "If it is unselected then the spline will keep it's shape but will be scaled and rotated to fit the new draw space."), sP_keepWorldPos_duringDrawSpaceChange.boolValue); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + } + + void DrawDrawSpaceEnum() //two times "Draw" in the name is in meant this way + { + serializedObject.ApplyModifiedProperties(); + + if (bezierSplineDrawer_unserializedMonoB.drawSpace == BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject) + { + if (UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(bezierSplineDrawer_unserializedMonoB.transform)) + { + EditorGUILayout.HelpBox("The transform of this gameobject or of a parent has a non-uniform scale. This may lead to wrong or weird results, when drawing in local space.", MessageType.Warning, true); + } + } + + BezierSplineDrawer.DrawSpace drawSpace_after = (BezierSplineDrawer.DrawSpace)EditorGUILayout.EnumPopup(GUIContent.none, bezierSplineDrawer_unserializedMonoB.drawSpace); + if (drawSpace_after != bezierSplineDrawer_unserializedMonoB.drawSpace) + { + bezierSplineDrawer_unserializedMonoB.RegisterStateForUndo("Change Spline Space", true, false); + bezierSplineDrawer_unserializedMonoB.ChangeDrawSpace(drawSpace_after); + } + + serializedObject.Update(); + } + + void DrawCloseRingToggle() + { + serializedObject.ApplyModifiedProperties(); + + bool closeGapState_after = EditorGUILayout.Toggle(new GUIContent("Close ring from end to start"), bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed); + if (closeGapState_after != bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed) + { + bezierSplineDrawer_unserializedMonoB.ChangeCloseGapState(closeGapState_after); + } + + serializedObject.Update(); + } + + void DrawControlPointsSection() + { + SerializedProperty sP_controlPointsList_isOutfolded = serializedObject.FindProperty("controlPointsList_isOutfolded"); + sP_controlPointsList_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_controlPointsList_isOutfolded.boolValue, "Control Points", true); + if (sP_controlPointsList_isOutfolded.boolValue) + { + DrawNonSerializedControlPointsList(); + DrawSectionWithDefaultValuesOfNewlyCreatedPoints(); + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + } + + void DrawNonSerializedControlPointsList() + { + //-> exceptionally: no indent here to have more display space for the list + + serializedObject.ApplyModifiedProperties(); + + bezierSplineDrawer_unserializedMonoB.TryResheduleSceneViewRepaint(); + + Rect firstControlPointRect = default; + bool firstControlPointRect_hasBeenFilled = false; + + for (int i = 0; i < bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count; i++) + { + float height_ofCurrentControlPoint = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].GetPropertyHeightForInspectorList(); + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].inspectorRect_reservedForThisTriplet = EditorGUILayout.GetControlRect(true, height_ofCurrentControlPoint); + + if (firstControlPointRect_hasBeenFilled == false) + { + firstControlPointRect = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].inspectorRect_reservedForThisTriplet; + firstControlPointRect_hasBeenFilled = true; + } + } + + float height_ofEmptyControlPointHoldingOnlyPlusButton = InternalDXXL_BezierControlPointTriplet.GetPropertyHeightForEmptyControlPointHoldingOnlyAPlusButtonAndFoldAllButtons(); + Rect rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons = EditorGUILayout.GetControlRect(true, height_ofEmptyControlPointHoldingOnlyPlusButton); + + if (firstControlPointRect_hasBeenFilled == false) + { + firstControlPointRect = rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons; + } + + float y_ofListsLowerEnd = rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons.y + rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons.height; + float heightOfListBackground = y_ofListsLowerEnd - firstControlPointRect.y; + Rect space_ofBackgroundColorRect = new Rect(firstControlPointRect.x, firstControlPointRect.y, firstControlPointRect.width, heightOfListBackground); + Rect space_ofBackgroundColorRectFrame = new Rect(space_ofBackgroundColorRect.x - 1.0f, space_ofBackgroundColorRect.y - 1.0f, space_ofBackgroundColorRect.width + 2.0f, space_ofBackgroundColorRect.height + 2.0f); + EditorGUI.DrawRect(space_ofBackgroundColorRectFrame, BezierSplineDrawer.color_ofControlPointListBackgroundFrameInInspecor); + EditorGUI.DrawRect(space_ofBackgroundColorRect, BezierSplineDrawer.color_ofControlPointListBackgroundInInspecor); + + for (int i = 0; i < bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count; i++) + { + bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].DrawValuesToInspector(); + } + + for (int i = 0; i < bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count; i++) + { + if (bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].minusButtonAtThisListItem_hasBeenClickedInInspector) + { + bezierSplineDrawer_unserializedMonoB.TryDeleteControlPoint_dueToMinusButtonAtControlPointListItemHasBeenClicked(i); + bezierSplineDrawer_unserializedMonoB.SheduleSceneViewRepaint(); + break; //-> only one change at a time + } + + bool didChangeSomething = bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets[i].TryApplyChangesAfterInspectorInput(); + if (didChangeSomething) + { + bezierSplineDrawer_unserializedMonoB.SheduleSceneViewRepaint(); + break; //-> only one change at a time + } + } + + DrawEmptyControlPointBelowControlPointsList_thatHoldsOnlyAPlusButtonAndFoldAllButtons(rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons); + + serializedObject.Update(); + } + + void DrawEmptyControlPointBelowControlPointsList_thatHoldsOnlyAPlusButtonAndFoldAllButtons(Rect rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons) + { + bool greyOutBothFoldAllButtons = ((bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count == 0) || ((bezierSplineDrawer_unserializedMonoB.listOfControlPointTriplets.Count == 1) && (bezierSplineDrawer_unserializedMonoB.gapFromEndToStart_isClosed == false))); + bool greyOutUnfoldAllButton = greyOutBothFoldAllButtons || bezierSplineDrawer_unserializedMonoB.CheckIf_allFoldableHelperPoints_areUnfolded_inTheInspectorList(); + bool greyOutCollapseAllButton = greyOutBothFoldAllButtons || bezierSplineDrawer_unserializedMonoB.CheckIf_allFoldableHelperPoints_areCollapsed_inTheInspectorList(); + + InternalDXXL_BezierControlPointTriplet.DrawEmptyControlPointHoldingOnlyAPlusButton_forInspector(out bool plusButtonBelowListOfControlPoints_hasBeenClicked, out bool unfoldAllWeightsBelowListOfControlPoints_hasBeenClicked, out bool collapseAllWeightsBelowListOfControlPoints_hasBeenClicked, rect_ofEmptyControlPointHoldingOnlyPlusButtonAndFoldAllButtons, bezierSplineDrawer_unserializedMonoB.color_ofAnchorPoints, plusSymbolIcon, greyOutUnfoldAllButton, greyOutCollapseAllButton); + if (plusButtonBelowListOfControlPoints_hasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CreateNewControlPoint_dueToPlusButtonBelowControlPointsListHasBeenClicked(); + bezierSplineDrawer_unserializedMonoB.SheduleSceneViewRepaint(); + } + + if (unfoldAllWeightsBelowListOfControlPoints_hasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.UnfoldAllHelperPointInTheInspectorList(); + } + + if (collapseAllWeightsBelowListOfControlPoints_hasBeenClicked) + { + bezierSplineDrawer_unserializedMonoB.CollapseAllHelperPointInTheInspectorList(); + } + } + + void DrawSectionWithDefaultValuesOfNewlyCreatedPoints() + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded = serializedObject.FindProperty("defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded"); + sP_defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded.boolValue, "Default values of newly created control points", true); + if (sP_defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + DrawSectionWithDefaultOffsetOfNewlyCreatedPoints(); + DrawSectionWithDefaultOrientationOfNewlyCreatedPoints(); + DrawSectionWithDefaultWeightDistancesOfNewlyCreatedPoints(); + DrawSectionWithDefaultJunctureTypeOfNewlyCreatedPoints(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawSectionWithDefaultOffsetOfNewlyCreatedPoints() + { + SerializedProperty sP_defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded = serializedObject.FindProperty("defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded"); + sP_defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded.boolValue, "Default Position Offset", true); + if (sP_defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_definitionType_ofDefaultPosOffset = serializedObject.FindProperty("definitionType_ofDefaultPosOffset"); + EditorGUILayout.PropertyField(sP_definitionType_ofDefaultPosOffset, new GUIContent("Offset source")); + switch (sP_definitionType_ofDefaultPosOffset.enumValueIndex) + { + case (int)BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.straightExtentionOfCurveEnd: + SerializedProperty sP_distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace = serializedObject.FindProperty("distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace"); + EditorGUILayout.PropertyField(sP_distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace, new GUIContent("Distance")); + sP_distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace.floatValue = Mathf.Max(sP_distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace.floatValue, 0.0f); + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + break; + case (int)BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.customOffset: + DrawSpecificationOf_customVector3_1("Custom offset value", false, null, false, false, true, false); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSectionWithDefaultOrientationOfNewlyCreatedPoints() + { + SerializedProperty sP_defaultRotOfNewlyCreatedPoints_subSection_isOutfolded = serializedObject.FindProperty("defaultRotOfNewlyCreatedPoints_subSection_isOutfolded"); + sP_defaultRotOfNewlyCreatedPoints_subSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_defaultRotOfNewlyCreatedPoints_subSection_isOutfolded.boolValue, "Default Initial Orientation", true); + if (sP_defaultRotOfNewlyCreatedPoints_subSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_definitionType_ofDefaultRot = serializedObject.FindProperty("definitionType_ofDefaultRot"); + EditorGUILayout.PropertyField(sP_definitionType_ofDefaultRot, new GUIContent("Orientation source")); + switch (sP_definitionType_ofDefaultRot.enumValueIndex) + { + case (int)BezierSplineDrawer.DefinitionType_ofDefaultRot.sameAsCurveEnd: + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + break; + case (int)BezierSplineDrawer.DefinitionType_ofDefaultRot.customOrientation: + DrawSpecificationOf_customVector3_2("Custom forward vector that defines the orientation", false, null, true, false, true, false); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSectionWithDefaultWeightDistancesOfNewlyCreatedPoints() + { + SerializedProperty sP_defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded = serializedObject.FindProperty("defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded"); + sP_defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded.boolValue, "Default Initial Weight Distances", true); + if (sP_defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace = serializedObject.FindProperty("forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace"); + EditorGUILayout.PropertyField(sP_forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace, new GUIContent("Forward")); + sP_forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace.floatValue = Mathf.Max(sP_forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace.floatValue, 0.0f); + + SerializedProperty sP_backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace = serializedObject.FindProperty("backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace"); + EditorGUILayout.PropertyField(sP_backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace, new GUIContent("Backward")); + sP_backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace.floatValue = Mathf.Max(sP_backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace.floatValue, 0.0f); + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSectionWithDefaultJunctureTypeOfNewlyCreatedPoints() + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("junctureType_ofNewlyCreatedPoints"), new GUIContent("Default Juncture Type")); + } + + void DrawHandlesSection() + { + SerializedProperty sP_handlesSection_isOutfolded = serializedObject.FindProperty("handlesSection_isOutfolded"); + SerializedProperty sP_hideAllHandles = serializedObject.FindProperty("hideAllHandles"); + + Rect rect_ofHandlesHeadline = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight); + Rect rect_ofHandlesHeadlineFoldout = new Rect(rect_ofHandlesHeadline.x, rect_ofHandlesHeadline.y, EditorGUIUtility.singleLineHeight, rect_ofHandlesHeadline.height); + Rect rect_ofHandlesHeadlineTextWithCheckbox = new Rect(rect_ofHandlesHeadline.x, rect_ofHandlesHeadline.y, rect_ofHandlesHeadline.width, rect_ofHandlesHeadline.height); + + sP_hideAllHandles.boolValue = !EditorGUI.ToggleLeft(rect_ofHandlesHeadlineTextWithCheckbox, new GUIContent("Handles"), !sP_hideAllHandles.boolValue); + sP_handlesSection_isOutfolded.boolValue = EditorGUI.Foldout(rect_ofHandlesHeadlineFoldout, sP_handlesSection_isOutfolded.boolValue, GUIContent.none, true); + + if (sP_handlesSection_isOutfolded.boolValue == true) + { + EditorGUI.BeginDisabledGroup(sP_hideAllHandles.boolValue); + DrawHandlesSection_outfoldedPart(); + EditorGUI.EndDisabledGroup(); + } + } + + void DrawHandlesSection_outfoldedPart() + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + GUIStyle labelStyle_withRichtext = new GUIStyle(); + + DrawPositionHandlesSection(labelStyle_withRichtext); + DrawRotationHandlesSection(labelStyle_withRichtext); + DrawCustomHandlesSection(labelStyle_withRichtext); + DrawPlusButtonHandleSection(labelStyle_withRichtext); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawPositionHandlesSection(GUIStyle labelStyle_withRichtext) + { + EditorGUILayout.LabelField("Move Position Handle (Unity style)", labelStyle_withRichtext); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_showHandleFor_position_atAnchors = serializedObject.FindProperty("showHandleFor_position_atAnchors"); + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_showHandleFor_position_atAnchors, new GUIContent("At Anchor Points (show/size)")); + EditorGUI.BeginDisabledGroup(!sP_showHandleFor_position_atAnchors.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeFor_position_atAnchors"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + SerializedProperty sP_showHandleFor_position_atHelpers = serializedObject.FindProperty("showHandleFor_position_atHelpers"); + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_showHandleFor_position_atHelpers, new GUIContent("At Helper Points (show/size)")); + EditorGUI.BeginDisabledGroup(!sP_showHandleFor_position_atHelpers.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeFor_position_atHelpers"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + bool drawSpaceIsLocal = (serializedObject.FindProperty("drawSpace").enumValueIndex == (int)BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject); + bool positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal_chooserIsAvailable = (Tools.pivotRotation == PivotRotation.Global) && drawSpaceIsLocal; + string positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal_displayName = "Global orientation in local draw space"; + if (positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal_chooserIsAvailable) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal"), new GUIContent(positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal_displayName, "If your Editor tool handle rotation is set to 'global' orientation, but you work in a local draw space for a spline then the question arises which space should be considered as 'global' in den local draw space and accordingly how the position handle should be displayed." + Environment.NewLine + Environment.NewLine + "Chose 'global space' if you want the position handles aligned with the global world space." + Environment.NewLine + Environment.NewLine + "Chose 'local draw space' if you want the position handles aligned with the local draw space.")); + } + else + { + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.PropertyField(serializedObject.FindProperty("positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal"), new GUIContent(positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal_displayName, "Only available if Editor tool handle rotation is set to 'global' and if draw space is 'local'.")); + EditorGUI.EndDisabledGroup(); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + + void DrawRotationHandlesSection(GUIStyle labelStyle_withRichtext) + { + EditorGUILayout.LabelField("Rotate Handle (Unity style)", labelStyle_withRichtext); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_showHandleFor_rotation = serializedObject.FindProperty("showHandleFor_rotation"); + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_showHandleFor_rotation, new GUIContent("Show / Size")); + EditorGUI.BeginDisabledGroup(!sP_showHandleFor_rotation.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeFor_rotation"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + + void DrawCustomHandlesSection(GUIStyle labelStyle_withRichtext) + { + EditorGUILayout.LabelField("Spline Custom Handles", labelStyle_withRichtext); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUILayout.LabelField("At Anchor Points"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + SerializedProperty sP_showCustomHandleFor_anchorPoints = serializedObject.FindProperty("showCustomHandleFor_anchorPoints"); + EditorGUILayout.PropertyField(sP_showCustomHandleFor_anchorPoints, new GUIContent("Show")); + EditorGUI.BeginDisabledGroup(!sP_showCustomHandleFor_anchorPoints.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeOf_customHandle_atAnchors"), new GUIContent("Size")); + EditorGUI.EndDisabledGroup(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_ofAnchorPoints"), new GUIContent("Color")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("At Helper Points"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + SerializedProperty sP_showCustomHandleFor_helperPoints = serializedObject.FindProperty("showCustomHandleFor_helperPoints"); + EditorGUILayout.PropertyField(sP_showCustomHandleFor_helperPoints, new GUIContent("Show")); + EditorGUI.BeginDisabledGroup(!sP_showCustomHandleFor_helperPoints.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeOf_customHandle_atHelpers"), new GUIContent("Size")); + EditorGUI.EndDisabledGroup(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_ofHelperPoints"), new GUIContent("Color")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + + void DrawPlusButtonHandleSection(GUIStyle labelStyle_withRichtext) + { + EditorGUILayout.LabelField("Add Point Buttons ('+')", labelStyle_withRichtext); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_showHandleFor_plusButtons_atSplineStartAndEnd = serializedObject.FindProperty("showHandleFor_plusButtons_atSplineStartAndEnd"); + SerializedProperty sP_showHandleFor_plusButtons_insideSegments = serializedObject.FindProperty("showHandleFor_plusButtons_insideSegments"); + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_showHandleFor_plusButtons_atSplineStartAndEnd, new GUIContent("At Start/End")); + EditorGUILayout.PropertyField(sP_showHandleFor_plusButtons_insideSegments, new GUIContent("Inside Curve")); + GUILayout.EndHorizontal(); + + bool atLeastOnePlusButtonOption_isChecked = (sP_showHandleFor_plusButtons_atSplineStartAndEnd.boolValue || sP_showHandleFor_plusButtons_insideSegments.boolValue); + EditorGUI.BeginDisabledGroup(!atLeastOnePlusButtonOption_isChecked); + EditorGUILayout.PropertyField(serializedObject.FindProperty("handleSizeOf_plusButtons"), new GUIContent("Size")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/BezierSplineDrawerInspector.cs.meta b/Editor/DrawDebugLibrary/BezierSplineDrawerInspector.cs.meta new file mode 100644 index 0000000..27cbe97 --- /dev/null +++ b/Editor/DrawDebugLibrary/BezierSplineDrawerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b691e94b05b382f4f81ba347a6cdc463 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/BoundsVisualizerInspector.cs b/Editor/DrawDebugLibrary/BoundsVisualizerInspector.cs new file mode 100644 index 0000000..42b95cc --- /dev/null +++ b/Editor/DrawDebugLibrary/BoundsVisualizerInspector.cs @@ -0,0 +1,80 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(BoundsVisualizer))] + [CanEditMultipleObjects] + public class BoundsVisualizerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("bounds"); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("global"), new GUIContent("Global")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("local"), new GUIContent("Local")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("includeChildren"), new GUIContent("Include children")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineWidth"), new GUIContent("Line width")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + + DrawTextSpecs(); + DrawCheckboxFor_drawOnlyIfSelected("bounds"); + DrawCheckboxFor_hiddenByNearerObjects("bounds"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + + void DrawTextSpecs() + { + //-> this fakes the appearance of beeing inside the parents text specification foldout + bool emptyLineAtEndIfOutfolded = false; + DrawTextInputInclMarkupHelper(true, false, null, emptyLineAtEndIfOutfolded); + + if (serializedObject.FindProperty("textSection_isOutfolded").boolValue == true) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + DrawTextSizeContentChooser(); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawTextSizeContentChooser() + { + EditorGUILayout.LabelField("Text Size"); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_attachedTextsizeReferenceContext = serializedObject.FindProperty("attachedTextsizeReferenceContext"); + EditorGUILayout.PropertyField(sP_attachedTextsizeReferenceContext, new GUIContent("Relative to")); + + switch (sP_attachedTextsizeReferenceContext.enumValueIndex) + { + case (int)BoundsVisualizer.AttachedTextsizeReferenceContext.extentOfBounds: + break; + case (int)BoundsVisualizer.AttachedTextsizeReferenceContext.globalSpace: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value"), new GUIContent("Size per letter", "Text size in world units")); + break; + case (int)BoundsVisualizer.AttachedTextsizeReferenceContext.sceneViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value_relToScreen"), new GUIContent("Size per letter", "Text size relative to Scene View window size.")); + break; + case (int)BoundsVisualizer.AttachedTextsizeReferenceContext.gameViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value_relToScreen"), new GUIContent("Size per letter", "Text size relative to Game View window size.")); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/BoundsVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/BoundsVisualizerInspector.cs.meta new file mode 100644 index 0000000..02856ad --- /dev/null +++ b/Editor/DrawDebugLibrary/BoundsVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3611eb08e76a83842b6187c3a4685787 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/CameraGridVisualizerInspector.cs b/Editor/DrawDebugLibrary/CameraGridVisualizerInspector.cs new file mode 100644 index 0000000..8728822 --- /dev/null +++ b/Editor/DrawDebugLibrary/CameraGridVisualizerInspector.cs @@ -0,0 +1,35 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(CameraGridVisualizer))] + [CanEditMultipleObjects] + public class CameraGridVisualizerInspector : VisualizerScreenspaceParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("camera grid"); + if (DrawCameraChooser(false)) + { + GUILayout.Space(0.75f * EditorGUIUtility.singleLineHeight); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesWidth_relToViewportHeight"), new GUIContent("Lines width", "This is relative to the viewport height.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawTenthLines"), new GUIContent("Lines at Tenth")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawHundredthLines"), new GUIContent("Lines at Hundredth")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gridScreenspaceMode"), new GUIContent("Mode")); + DrawCheckboxFor_drawOnlyIfSelected("camera grid"); + } + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/CameraGridVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/CameraGridVisualizerInspector.cs.meta new file mode 100644 index 0000000..708e394 --- /dev/null +++ b/Editor/DrawDebugLibrary/CameraGridVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e93c9ee53e4716946ada024cdba5e0bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/CameraVisualizerInspector.cs b/Editor/DrawDebugLibrary/CameraVisualizerInspector.cs new file mode 100644 index 0000000..98c26da --- /dev/null +++ b/Editor/DrawDebugLibrary/CameraVisualizerInspector.cs @@ -0,0 +1,156 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(CameraVisualizer))] + [CanEditMultipleObjects] + public class CameraVisualizerInspector : VisualizerScreenspaceParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("camera"); + if (DrawCameraChooser(false)) + { + GUILayout.Space(0.75f * EditorGUIUtility.singleLineHeight); + + DrawCameraSpecs(); + DrawFrustumSpecs(); + + DrawTextSpecs(); + DrawCheckboxFor_drawOnlyIfSelected("camera"); + DrawCheckboxFor_hiddenByNearerObjects("camera"); + } + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawCameraSpecs() + { + SerializedProperty sP_drawCamera = serializedObject.FindProperty("drawCamera"); + EditorGUILayout.PropertyField(sP_drawCamera, new GUIContent("Draw camera")); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUI.BeginDisabledGroup(!sP_drawCamera.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesWidth_camera"), new GUIContent("Lines width")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_ofCamera_enabledCam"), new GUIContent("Color (enabled)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_ofCamera_disabledCam"), new GUIContent("Color (disabled)")); + EditorGUI.EndDisabledGroup(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.75f * EditorGUIUtility.singleLineHeight); + } + + void DrawFrustumSpecs() + { + SerializedProperty sP_drawFrustum = serializedObject.FindProperty("drawFrustum"); + EditorGUILayout.PropertyField(sP_drawFrustum, new GUIContent("Draw frustum")); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUI.BeginDisabledGroup(!sP_drawFrustum.boolValue); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesWidth_frustum"), new GUIContent("Lines width (edges)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_ofFrustum_enabledCam"), new GUIContent("Color (enabled)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_ofFrustum_disabledCam"), new GUIContent("Color (disabled)")); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Boundary planes:"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("alphaFactor_forBoundarySurfaceLines"), new GUIContent("Alpha factor")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesPerBoundarySurface"), new GUIContent("Thin Lines (per plane)")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + DrawSectionFor_additionalFlexibleHighlighterPlane(); + + EditorGUI.EndDisabledGroup(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.75f * EditorGUIUtility.singleLineHeight); + } + + + void DrawSectionFor_additionalFlexibleHighlighterPlane() + { + EditorGUILayout.LabelField("Additional flexible highlighted Plane:"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_highlightedPlaneDefintionType = serializedObject.FindProperty("highlightedPlaneDefintionType"); + EditorGUILayout.PropertyField(sP_highlightedPlaneDefintionType, GUIContent.none); + + switch (sP_highlightedPlaneDefintionType.enumValueIndex) + { + case (int)CameraVisualizer.HighlightedPlaneDefintionType.disabled: + break; + case (int)CameraVisualizer.HighlightedPlaneDefintionType.definedByDistanceFromCamera: + EditorGUILayout.PropertyField(serializedObject.FindProperty("distanceOfHighlightedPlane"), new GUIContent("Distance", "The additional flexible highlighted plane is only drawn if its 'Distance' is at least the cameras near clip plane distance.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane"), new GUIContent("Draw if farer than far clip plane", "This specifies whether the flexible plane should also be drawn if it is farer than the cameras far clip plane.")); + DrawChooserLineFor_overwriteColorForFrustumsHighlightedPlane(); + break; + case (int)CameraVisualizer.HighlightedPlaneDefintionType.definedByAPosition: + SerializedProperty sP_highlightedPlaneViaPosDefintionType = serializedObject.FindProperty("highlightedPlaneViaPosDefintionType"); + EditorGUILayout.PropertyField(sP_highlightedPlaneViaPosDefintionType, new GUIContent("Plane Anchor Source")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + switch (sP_highlightedPlaneViaPosDefintionType.enumValueIndex) + { + case (int)CameraVisualizer.HighlightedPlaneViaPosDefintionType.fixedPosition: + EditorGUILayout.PropertyField(serializedObject.FindProperty("vector3_thatSpecifiesThePosOfTheAdditionalFrustumPlane"),new GUIContent("Position that the flexible plane should contain", "This doesn't have to be inside the frustum itself, but the flexible plane will only be drawn if this position is not behind the near clip plane of the camera.")); + break; + case (int)CameraVisualizer.HighlightedPlaneViaPosDefintionType.gameobject: + EditorGUILayout.PropertyField(serializedObject.FindProperty("gameobject_thatSpecifiesThePosOfTheAdditionalFrustumPlane"), new GUIContent("Gameobject that the flexible plane should contain", "This doesn't have to be inside the frustum itself, but the flexible plane will only be drawn if this position is not behind the near clip plane of the camera.")); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + EditorGUILayout.PropertyField(serializedObject.FindProperty("distanceOfHighlightedPlane_offsetFromPosition"), new GUIContent("Additional offset along Cameras View Direction", "This shifts the plane to farer or nearer relative to the position. The additional flexible highlighted plane is only drawn if the final distance is at least the cameras near clip plane distance.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane"), new GUIContent("Draw if farer than far clip plane", "This specifies whether the flexible plane should also be drawn if it is farer than the cameras far clip plane.")); + DrawChooserLineFor_overwriteColorForFrustumsHighlightedPlane(); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawChooserLineFor_overwriteColorForFrustumsHighlightedPlane() + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("doOverwriteColorForFrustumsHighlightedPlane"), new GUIContent("Custom Plane Color", "The default color of highlighted planes is the frustum color, but with an adjusted brightness. Though you can overwrite the color here.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColorForFrustumsHighlightedPlane"), GUIContent.none); + EditorGUILayout.EndHorizontal(); + } + + void DrawTextSpecs() + { + //-> this fakes the appearance of beeing inside the parents text specification foldout + bool emptyLineAtEndIfOutfolded = false; + DrawTextInputInclMarkupHelper(true, false, null, emptyLineAtEndIfOutfolded); + + if (serializedObject.FindProperty("textSection_isOutfolded").boolValue == true) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("forceTextOnNearPlaneUnmirroredTowardsCam"), new GUIContent("Force text to be unmirrored towards visualized camera", "This overwrites the global behaviour where text always appear unmirrored in the observer camera, which could e.g. be the Scene view camera instead of the herewith visualized camera.")); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/CameraVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/CameraVisualizerInspector.cs.meta new file mode 100644 index 0000000..299b926 --- /dev/null +++ b/Editor/DrawDebugLibrary/CameraVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c16326d74184b34b99f4bd7b7c16424 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/Charts.meta b/Editor/DrawDebugLibrary/Charts.meta new file mode 100644 index 0000000..5a9d34a --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 35fad28634e0421408fbf6e31f9b06d4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/Charts/DrawXXL-chart-editor.asmref b/Editor/DrawDebugLibrary/Charts/DrawXXL-chart-editor.asmref new file mode 100644 index 0000000..6d1f4ce --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/DrawXXL-chart-editor.asmref @@ -0,0 +1,3 @@ +{ + "reference": "GUID:4cba057b890ab8f49bdbfaa6f02fc72c" +} \ No newline at end of file diff --git a/Editor/DrawDebugLibrary/Charts/DrawXXL-chart-editor.asmref.meta b/Editor/DrawDebugLibrary/Charts/DrawXXL-chart-editor.asmref.meta new file mode 100644 index 0000000..831aec7 --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/DrawXXL-chart-editor.asmref.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: fb976d5e51c5a1f448390889bfdabc47 +AssemblyDefinitionReferenceImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/Charts/DrawXXLChartInspector_Inspector.cs b/Editor/DrawDebugLibrary/Charts/DrawXXLChartInspector_Inspector.cs new file mode 100644 index 0000000..c825646 --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/DrawXXLChartInspector_Inspector.cs @@ -0,0 +1,588 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(DrawXXLChartInspector))] + public class DrawXXLChartInspector_Inspector : Editor + { + DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB; + + GUIContent checkmarkSymbol; + GUIContent crossSymbol; + GUIContent magnifierGlassSymbol_atXAxis; + GUIContent magnifierGlassSymbol_atYAxis; + GUIContent magnifierGlassSymbol_forBothAxes; + GUIContent handSymbol_atXAxis; + GUIContent handSymbol_atYAxis; + GUIContent handSymbol_forBothAxes; + + float travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_zoomXAxisHandle = 0.0f; + float travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_zoomYAxisHandle = 0.0f; + float travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_forZoomBothAxesHandle = 0.0f; + float travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_dragXAxisHandle = 0.0f; + float travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_dragYAxisHandle = 0.0f; + float travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown_for_unifiedDragHandle = 0.0f; + float travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown_for_unifiedDragHandle = 0.0f; + + float sizeFactor_forBacksnappingConeCaps = 1.0f; + float sizeFactor_forBacksnappingCylinderCaps = 0.8f; + float sizeFactor_forBacksnappingSphereCaps = 1.0f; + + float distanceFromAnchorPosFactor_forBacksnappingConeCaps = -0.5f; + float distanceFromAnchorPosFactor_forBacksnappingCylinderCaps = -1.7f; + + float sizeFactor_forCheckmarkIcon = 0.5f; + float sizeFactor_forCrossIcon = 0.5f; + float sizeFactor_forHandIcon_onConesAndSpheres = 0.42f; + float sizeFactor_forMagnifierGlassIcons_onCylinders = 0.5f; + + void OnEnable() + { + theDrawXXLChartInspector_unserializedMonoB = (DrawXXLChartInspector)target; + + //credits to https://github.com/Zxynine/UnityEditorIcons + string tooltip_forCheckbox = "If this is selected then the axis scaling will be automatically updated, so that all active lines are always fully displayed, also if new values are added." + Environment.NewLine + Environment.NewLine + "This setting gets auto-deactivated as soon as you drag one of the manual scale sliders."; + checkmarkSymbol = EditorGUIUtility.IconContent("FilterSelectedOnly@2x", tooltip_forCheckbox); + crossSymbol = EditorGUIUtility.IconContent("winbtn_win_close@2x", tooltip_forCheckbox); + magnifierGlassSymbol_atXAxis = EditorGUIUtility.IconContent("ViewToolZoom@2x", "Drag this to zoom only the X axis."); + magnifierGlassSymbol_atYAxis = EditorGUIUtility.IconContent("ViewToolZoom@2x", "Drag this to zoom only the Y axis."); + magnifierGlassSymbol_forBothAxes = EditorGUIUtility.IconContent("ViewToolZoom@2x", "Drag this to zoom both axes."); + handSymbol_atXAxis = EditorGUIUtility.IconContent("ViewToolMove@2x", "Drag this to scroll only the X axis."); + handSymbol_atYAxis = EditorGUIUtility.IconContent("ViewToolMove@2x", "Drag this to scroll only the Y axis."); + handSymbol_forBothAxes = EditorGUIUtility.IconContent("ViewToolMove@2x", "Drag this to scroll both axes."); + } + + public void OnSceneGUI() + { + if (theDrawXXLChartInspector_unserializedMonoB.hideHandles_andInsteadUseInspectorSlidersForZoomAndScroll == false) + { + theDrawXXLChartInspector_unserializedMonoB.TryNote_chartWorldSpacePosRotScale_beforeChangingItToScreenspace(); + try + { + if (theDrawXXLChartInspector_unserializedMonoB.theChartIsDrawnInScreenspace) { UtilitiesDXXL_ChartDrawing.SetPosRotScaleOfChart_toScreenspace(theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo, theDrawXXLChartInspector_unserializedMonoB.screenSpaceTargetCamera, theDrawXXLChartInspector_unserializedMonoB.chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, true); } + + DrawCursorSliders(); + float sizeOfHandleCaps = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.xAxis.Get_fixedConeLength_forBothAxisVectors(); + DrawScrollSliderAsConeAtXAxis(sizeOfHandleCaps); + DrawScrollSliderAsConeAtYAxis(sizeOfHandleCaps); + DrawScrollSliderAsSphereAtUnifiedAxis(sizeOfHandleCaps); + DrawZoomSliderAsCylinderAtXAxis(sizeOfHandleCaps); + DrawZoomSliderAsCylinderAtYAxis(sizeOfHandleCaps); + DrawZoomSliderAsCylinderAtUnifiedAxis(sizeOfHandleCaps); + DrawCheckboxFor_showAllValues(sizeOfHandleCaps); + } + catch { } + theDrawXXLChartInspector_unserializedMonoB.TrySetBack_chartWorldSpacePosRotScale_afterUsingItInScreenspace(); + } + } + + void DrawCursorSliders() + { + DrawACursorSlider(true, true); + } + + void DrawACursorSlider(bool isAtLowerEndOfCursorsVertLine_notAtUpperEnd, bool tryOtherCursorSlider_ifThisCursorSliderDoesntReportAnyChange) + { + float worldSpaceDistanceAlongXAxis_measuredFromYAxis_beforeDrag = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Width_inWorldSpace * theDrawXXLChartInspector_unserializedMonoB.curr_cursorPosition_as0to1OfChartWidth; + + EditorGUI.BeginChangeCheck(); + float worldSpaceDistanceAlongXAxis_measuredFromYAxis_afterDrag = InternalDXXL_ChartHandles.CursorSlider(isAtLowerEndOfCursorsVertLine_notAtUpperEnd, worldSpaceDistanceAlongXAxis_measuredFromYAxis_beforeDrag, theDrawXXLChartInspector_unserializedMonoB); + bool hasChanged = EditorGUI.EndChangeCheck(); + + if (hasChanged) + { + UpdateCursorPos0to1(worldSpaceDistanceAlongXAxis_measuredFromYAxis_afterDrag); + } + else + { + if (tryOtherCursorSlider_ifThisCursorSliderDoesntReportAnyChange) + { + DrawACursorSlider(!isAtLowerEndOfCursorsVertLine_notAtUpperEnd, false); + } + } + } + + void UpdateCursorPos0to1(float worldSpaceDistanceAlongXAxis_measuredFromYAxis_afterDrag) + { + float new_cursorPosition_as0to1OfChartWidth = worldSpaceDistanceAlongXAxis_measuredFromYAxis_afterDrag / theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Width_inWorldSpace; + theDrawXXLChartInspector_unserializedMonoB.ForceCursorSliders_toFitGiven0to1XPos(new_cursorPosition_as0to1OfChartWidth); + } + + void DrawScrollSliderAsConeAtXAxis(float sizeOfHandleCaps) + { + float distanceFromAnchorPos = distanceFromAnchorPosFactor_forBacksnappingConeCaps * sizeOfHandleCaps; + Vector3 sliderDirection_worldSpace_normalized = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.xAxis.AxisVector_normalized_inWorldSpace; + Vector3 restingPosition = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Position_worldspace + theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.xAxis.AxisVector_inWorldSpace + sliderDirection_worldSpace_normalized * distanceFromAnchorPos; + Handles.CapFunction capFunction = Handles.ConeHandleCap; + float capSizeScaleFactor = sizeFactor_forBacksnappingConeCaps; + GUIContent icon = handSymbol_atXAxis; + float iconSizeFactor = sizeFactor_forHandIcon_onConesAndSpheres; + Vector2 iconPositionOffset_inScreenspace_relToHandleCapSize = new Vector2(-0.45f, 0.2f); //-> manually shifting the icon, so it appears centered over the handle cap. + + EditorGUI.BeginChangeCheck(); + travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_dragXAxisHandle = InternalDXXL_ChartHandles.OneDirectionalBacksnapSlider(travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_dragXAxisHandle, restingPosition, theDrawXXLChartInspector_unserializedMonoB, sliderDirection_worldSpace_normalized, capFunction, capSizeScaleFactor, icon, iconSizeFactor, iconPositionOffset_inScreenspace_relToHandleCapSize, false, false); + bool hasChanged = EditorGUI.EndChangeCheck(); + + if (hasChanged) + { + theDrawXXLChartInspector_unserializedMonoB.alwaysEncapsulateAllValues = false; + theDrawXXLChartInspector_unserializedMonoB.scrollSinceMouseDown_fromOnlyXDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection = travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_dragXAxisHandle; + } + else + { + if (GUIUtility.hotControl == 0) + { + travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_dragXAxisHandle = 0.0f; + theDrawXXLChartInspector_unserializedMonoB.scrollSinceMouseDown_fromOnlyXDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection = 0.0f; + } + } + + } + + void DrawScrollSliderAsConeAtYAxis(float sizeOfHandleCaps) + { + float distanceFromAnchorPos = distanceFromAnchorPosFactor_forBacksnappingConeCaps * sizeOfHandleCaps; + Vector3 sliderDirection_worldSpace_normalized = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.yAxis.AxisVector_normalized_inWorldSpace; + Vector3 restingPosition = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Position_worldspace + theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.yAxis.AxisVector_inWorldSpace + sliderDirection_worldSpace_normalized * distanceFromAnchorPos; + Handles.CapFunction capFunction = Handles.ConeHandleCap; + float capSizeScaleFactor = sizeFactor_forBacksnappingConeCaps; + GUIContent icon = handSymbol_atYAxis; + float iconSizeFactor = sizeFactor_forHandIcon_onConesAndSpheres; + Vector2 iconPositionOffset_inScreenspace_relToHandleCapSize = new Vector2(-0.23f, 0.0f); //-> manually shifting the icon, so it appears centered over the handle cap. + + EditorGUI.BeginChangeCheck(); + travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_dragYAxisHandle = InternalDXXL_ChartHandles.OneDirectionalBacksnapSlider(travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_dragYAxisHandle, restingPosition, theDrawXXLChartInspector_unserializedMonoB, sliderDirection_worldSpace_normalized, capFunction, capSizeScaleFactor, icon, iconSizeFactor, iconPositionOffset_inScreenspace_relToHandleCapSize, false, false); + bool hasChanged = EditorGUI.EndChangeCheck(); + + if (hasChanged) + { + theDrawXXLChartInspector_unserializedMonoB.alwaysEncapsulateAllValues = false; + theDrawXXLChartInspector_unserializedMonoB.scrollSinceMouseDown_fromOnlyYDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection = travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_dragYAxisHandle; + } + else + { + if (GUIUtility.hotControl == 0) + { + travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_dragYAxisHandle = 0.0f; + theDrawXXLChartInspector_unserializedMonoB.scrollSinceMouseDown_fromOnlyYDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection = 0.0f; + } + } + } + + void DrawScrollSliderAsSphereAtUnifiedAxis(float sizeOfHandleCaps) + { + float distanceFromAnchorPos = 2.3f * sizeOfHandleCaps; + Vector3 unified45degAxis_forHandleSliders_normalized = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Get_unified45degAxis_forHandleSliders_normalized(); + Vector3 restingPosition = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Position_worldspace + unified45degAxis_forHandleSliders_normalized * distanceFromAnchorPos; + float capSizeScaleFactor = sizeFactor_forBacksnappingSphereCaps; + GUIContent icon = handSymbol_forBothAxes; + float iconSizeFactor = sizeFactor_forMagnifierGlassIcons_onCylinders; + Vector2 iconPositionOffset_inScreenspace_relToHandleCapSize = new Vector2(-0.25f, 0.25f); //-> manually shifting the icon, so it appears centered over the handle cap. + + EditorGUI.BeginChangeCheck(); + InternalDXXL_ChartHandles.TwoDirectionalBacksnapSlider(ref travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown_for_unifiedDragHandle, ref travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown_for_unifiedDragHandle, restingPosition, theDrawXXLChartInspector_unserializedMonoB, capSizeScaleFactor, icon, iconSizeFactor, iconPositionOffset_inScreenspace_relToHandleCapSize); + bool hasChanged = EditorGUI.EndChangeCheck(); + + if (hasChanged) + { + theDrawXXLChartInspector_unserializedMonoB.alwaysEncapsulateAllValues = false; + theDrawXXLChartInspector_unserializedMonoB.scrollSinceMouseDown_fromUnifiedHandleSlider_asTravelledWorldSpaceDistanceAlongChartsXDirection = travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown_for_unifiedDragHandle; + theDrawXXLChartInspector_unserializedMonoB.scrollSinceMouseDown_fromUnifiedHandleSlider_asTravelledWorldSpaceDistanceAlongChartsYDirection = travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown_for_unifiedDragHandle; + } + else + { + if (GUIUtility.hotControl == 0) + { + travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown_for_unifiedDragHandle = 0.0f; + travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown_for_unifiedDragHandle = 0.0f; + theDrawXXLChartInspector_unserializedMonoB.scrollSinceMouseDown_fromUnifiedHandleSlider_asTravelledWorldSpaceDistanceAlongChartsXDirection = 0.0f; + theDrawXXLChartInspector_unserializedMonoB.scrollSinceMouseDown_fromUnifiedHandleSlider_asTravelledWorldSpaceDistanceAlongChartsYDirection = 0.0f; + } + } + } + + void DrawZoomSliderAsCylinderAtXAxis(float sizeOfHandleCaps) + { + float distanceFromAnchorPos = distanceFromAnchorPosFactor_forBacksnappingCylinderCaps * sizeOfHandleCaps; + Vector3 sliderDirection_worldSpace_normalized = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.xAxis.AxisVector_normalized_inWorldSpace; + Vector3 restingPosition = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Position_worldspace + theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.xAxis.AxisVector_inWorldSpace + sliderDirection_worldSpace_normalized * distanceFromAnchorPos; + Handles.CapFunction capFunction = Handles.CylinderHandleCap; + float capSizeScaleFactor = sizeFactor_forBacksnappingCylinderCaps; + GUIContent icon = magnifierGlassSymbol_atXAxis; + float iconSizeFactor = sizeFactor_forHandIcon_onConesAndSpheres; + Vector2 iconPositionOffset_inScreenspace_relToHandleCapSize = new Vector2(-0.22f, 0.2f); //-> manually shifting the icon, so it appears centered over the handle cap. + + EditorGUI.BeginChangeCheck(); + travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_zoomXAxisHandle = InternalDXXL_ChartHandles.OneDirectionalBacksnapSlider(travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_zoomXAxisHandle, restingPosition, theDrawXXLChartInspector_unserializedMonoB, sliderDirection_worldSpace_normalized, capFunction, capSizeScaleFactor, icon, iconSizeFactor, iconPositionOffset_inScreenspace_relToHandleCapSize, false, true); + bool hasChanged = EditorGUI.EndChangeCheck(); + + if (hasChanged) + { + theDrawXXLChartInspector_unserializedMonoB.alwaysEncapsulateAllValues = false; + float zoomWeight_m1_to_p1 = travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_zoomXAxisHandle / theDrawXXLChartInspector_unserializedMonoB.GetBacksnapSliderReferenceLength_inWorldspaceUnits(); + theDrawXXLChartInspector_unserializedMonoB.xAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = zoomWeight_m1_to_p1; + } + else + { + if (GUIUtility.hotControl == 0) + { + travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_zoomXAxisHandle = 0.0f; + theDrawXXLChartInspector_unserializedMonoB.xAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = 0.0f; + } + } + } + + void DrawZoomSliderAsCylinderAtYAxis(float sizeOfHandleCaps) + { + float distanceFromAnchorPos = distanceFromAnchorPosFactor_forBacksnappingCylinderCaps * sizeOfHandleCaps; + Vector3 sliderDirection_worldSpace_normalized = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.yAxis.AxisVector_normalized_inWorldSpace; + Vector3 restingPosition = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Position_worldspace + theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.yAxis.AxisVector_inWorldSpace + sliderDirection_worldSpace_normalized * distanceFromAnchorPos; + Handles.CapFunction capFunction = Handles.CylinderHandleCap; + float capSizeScaleFactor = sizeFactor_forBacksnappingCylinderCaps; + GUIContent icon = magnifierGlassSymbol_atYAxis; + float iconSizeFactor = sizeFactor_forMagnifierGlassIcons_onCylinders; + Vector2 iconPositionOffset_inScreenspace_relToHandleCapSize = new Vector2(-0.23f, 0.24f); //-> manually shifting the icon, so it appears centered over the handle cap. + + EditorGUI.BeginChangeCheck(); + travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_zoomYAxisHandle = InternalDXXL_ChartHandles.OneDirectionalBacksnapSlider(travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_zoomYAxisHandle, restingPosition, theDrawXXLChartInspector_unserializedMonoB, sliderDirection_worldSpace_normalized, capFunction, capSizeScaleFactor, icon, iconSizeFactor, iconPositionOffset_inScreenspace_relToHandleCapSize, false, true); + bool hasChanged = EditorGUI.EndChangeCheck(); + + if (hasChanged) + { + theDrawXXLChartInspector_unserializedMonoB.alwaysEncapsulateAllValues = false; + float zoomWeight_m1_to_p1 = travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_zoomYAxisHandle / theDrawXXLChartInspector_unserializedMonoB.GetBacksnapSliderReferenceLength_inWorldspaceUnits(); + theDrawXXLChartInspector_unserializedMonoB.yAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = zoomWeight_m1_to_p1; + } + else + { + if (GUIUtility.hotControl == 0) + { + travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_zoomYAxisHandle = 0.0f; + theDrawXXLChartInspector_unserializedMonoB.yAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = 0.0f; + } + } + } + + void DrawZoomSliderAsCylinderAtUnifiedAxis(float sizeOfHandleCaps) + { + float distanceFromAnchorPos = 1.0f * sizeOfHandleCaps; + Vector3 sliderDirection_worldSpace_normalized = -theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Get_unified45degAxis_forHandleSliders_normalized(); + Vector3 restingPosition = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Position_worldspace - sliderDirection_worldSpace_normalized * distanceFromAnchorPos; + Handles.CapFunction capFunction = Handles.CylinderHandleCap; + float capSizeScaleFactor = sizeFactor_forBacksnappingCylinderCaps; + GUIContent icon = magnifierGlassSymbol_forBothAxes; + float iconSizeFactor = sizeFactor_forMagnifierGlassIcons_onCylinders; + Vector2 iconPositionOffset_inScreenspace_relToHandleCapSize = new Vector2(-0.25f, 0.25f); //-> manually shifting the icon, so it appears centered over the handle cap. + + EditorGUI.BeginChangeCheck(); + travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_forZoomBothAxesHandle = InternalDXXL_ChartHandles.OneDirectionalBacksnapSlider(travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_forZoomBothAxesHandle, restingPosition, theDrawXXLChartInspector_unserializedMonoB, sliderDirection_worldSpace_normalized, capFunction, capSizeScaleFactor, icon, iconSizeFactor, iconPositionOffset_inScreenspace_relToHandleCapSize, false, true); + bool hasChanged = EditorGUI.EndChangeCheck(); + + if (hasChanged) + { + theDrawXXLChartInspector_unserializedMonoB.alwaysEncapsulateAllValues = false; + float zoomWeight_m1_to_p1 = travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_forZoomBothAxesHandle / theDrawXXLChartInspector_unserializedMonoB.GetBacksnapSliderReferenceLength_inWorldspaceUnits(); + theDrawXXLChartInspector_unserializedMonoB.bothAxesZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = zoomWeight_m1_to_p1; + } + else + { + if (GUIUtility.hotControl == 0) + { + travelledWorldSpaceDistanceAlongSliderDirection_sinceMouseDown_for_forZoomBothAxesHandle = 0.0f; + theDrawXXLChartInspector_unserializedMonoB.bothAxesZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = 0.0f; + } + } + } + + void DrawCheckboxFor_showAllValues(float sizeOfHandleCaps) + { + float distanceFromAnchorPos = 3.6f * sizeOfHandleCaps; + Vector3 unified45degAxis_forHandleSliders_normalized = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Get_unified45degAxis_forHandleSliders_normalized(); + Vector3 position = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Position_worldspace + unified45degAxis_forHandleSliders_normalized * distanceFromAnchorPos; + Vector2 checkmarkIconPositionOffset_inScreenspace_relToHandleCapSize = new Vector2(-0.25f, 0.25f); //-> manually shifting the icon, so it appears centered over the handle cap. + Vector2 crossIconPositionOffset_inScreenspace_relToHandleCapSize = new Vector2(-0.25f, 0.25f); //-> manually shifting the icon, so it appears centered over the handle cap. + + bool checkmarkState_before = theDrawXXLChartInspector_unserializedMonoB.alwaysEncapsulateAllValues; + bool checkmarkState_after = InternalDXXL_ChartHandles.ShowAllButton(checkmarkState_before, position, theDrawXXLChartInspector_unserializedMonoB, sizeFactor_forBacksnappingSphereCaps, checkmarkSymbol, crossSymbol, sizeFactor_forCheckmarkIcon, sizeFactor_forCrossIcon, checkmarkIconPositionOffset_inScreenspace_relToHandleCapSize, crossIconPositionOffset_inScreenspace_relToHandleCapSize); + theDrawXXLChartInspector_unserializedMonoB.alwaysEncapsulateAllValues = checkmarkState_after; + } + + public override void OnInspectorGUI() + { + if (theDrawXXLChartInspector_unserializedMonoB.CheckIfReferencedChartGotLost()) + { + EditorGUILayout.HelpBox("The ChartDrawing that should be displayed with this component got lost for some reason, which normally leads to the automatic deletion of the whole gameobject." + Environment.NewLine + Environment.NewLine + "This gameobject has not been automatically deleted though, because it seems to host other components or has childs or parents attached." + Environment.NewLine + Environment.NewLine + "You can delete this component if you don't need it anymore. If you want to continue inspecting the chart then create a new chart inspector component via 'chartThatYouWantToInspect.CreateChartInspectionGameobject()'.", MessageType.Info, true); + } + else + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + GUIStyle style_forFoldoutWithBoldText = new GUIStyle(EditorStyles.foldout); + style_forFoldoutWithBoldText.fontStyle = FontStyle.Bold; + + DrawConsumedLines(); + DrawHandles_andOptionallyZoomAndAxisScaling(style_forFoldoutWithBoldText); + DrawSection_sceneViewCamera(style_forFoldoutWithBoldText); + DrawSection_other(style_forFoldoutWithBoldText); + DrawSection_lines(); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + } + + void DrawConsumedLines() + { + SerializedProperty sP_drawnLinesPerPass = serializedObject.FindProperty("drawnSmallStraightLines_duringLastDrawRun"); + GUIStyle style_ofConsumedLinesLabel = new GUIStyle(); + style_ofConsumedLinesLabel.richText = true; + float allowedConsumedLines_0to1 = (float)sP_drawnLinesPerPass.intValue / (float)DrawBasics.MaxAllowedDrawnLinesPerFrame; + float hueValueOfColor = 0.33333f * (1.0f - allowedConsumedLines_0to1); + Color color_visualizingWarningForTooManyLines = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(hueValueOfColor, 0.5f, 1.0f); + string coloredLineNumber = "" + sP_drawnLinesPerPass.intValue + ""; + string tooltipForBoth = "This chart is drawn with single small straight lines (like from 'Debug.DrawLine()'). If too many of these straight lines are drawn it may hit the Editor execution performance." + Environment.NewLine + Environment.NewLine + "The color becomes more red as the number reaches a critical area." + Environment.NewLine + Environment.NewLine + "(see also 'DrawXXL.DrawBasics.MaxAllowedDrawnLinesPerFrame')"; + GUIContent drawnLinesWord = new GUIContent("Drawn small straight lines:", tooltipForBoth); + GUIContent drawnLinesNumber = new GUIContent(coloredLineNumber, tooltipForBoth); + EditorGUILayout.LabelField(drawnLinesWord, drawnLinesNumber, style_ofConsumedLinesLabel); + } + + void DrawSection_sceneViewCamera(GUIStyle style_forFoldoutWithBoldText) + { + SerializedProperty serializedProperty_sceneViewCamSection_isExpanded = serializedObject.FindProperty("sceneViewCamSection_isExpanded"); + serializedProperty_sceneViewCamSection_isExpanded.boolValue = EditorGUILayout.Foldout(serializedProperty_sceneViewCamSection_isExpanded.boolValue, "Scene view camera", true, style_forFoldoutWithBoldText); + if (serializedProperty_sceneViewCamSection_isExpanded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty serializedProperty_forceSceneViewCamToFollowChart = serializedObject.FindProperty("forceSceneViewCamToFollowChart"); + + GUILayout.BeginHorizontal(); + GUILayout.Space(15.0f); + GUIContent guiContent_forbutton_setToChart = new GUIContent("Set to chart", "Set the Scene view camera position so that it looks at the chart."); + EditorGUI.BeginDisabledGroup(serializedProperty_forceSceneViewCamToFollowChart.boolValue); + if (GUILayout.Button(guiContent_forbutton_setToChart)) + { + theDrawXXLChartInspector_unserializedMonoB.TrySetSceneViewCamToChart_dueToButtonClick(); + } + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + //The feature "Checkbox: Stay at chart" is disabled. Reason: + //-> The risk is too high, that a user activates "Scene View Camera - Stay at Chart" + //-> and then changes the GameObject + //-> and then looses track why his SceneView Camera is fixed and he cannot navigate anymore with his camera through the Scene. + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawHandles_andOptionallyZoomAndAxisScaling(GUIStyle style_forFoldoutWithBoldText) + { + SerializedProperty sP_hideHandles_andInsteadUseInspectorSlidersForZoomAndScroll = serializedObject.FindProperty("hideHandles_andInsteadUseInspectorSlidersForZoomAndScroll"); + sP_hideHandles_andInsteadUseInspectorSlidersForZoomAndScroll.boolValue = EditorGUILayout.ToggleLeft(new GUIContent("Hide handles and use inspector sliders instead", "This may be helpful if the handles cover important information." + Environment.NewLine + Environment.NewLine + "When hiding handles you can still zoom and scroll the chart via sliders here in the inspector."), sP_hideHandles_andInsteadUseInspectorSlidersForZoomAndScroll.boolValue); + + if (sP_hideHandles_andInsteadUseInspectorSlidersForZoomAndScroll.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + DrawSection_cursor(style_forFoldoutWithBoldText); + DrawSection_axesScaling(style_forFoldoutWithBoldText); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSection_cursor(GUIStyle style_forFoldoutWithBoldText) + { + SerializedProperty serializedProperty_cursorSection_isExpanded = serializedObject.FindProperty("cursorSection_isExpanded"); + serializedProperty_cursorSection_isExpanded.boolValue = EditorGUILayout.Foldout(serializedProperty_cursorSection_isExpanded.boolValue, "Cursor", true, style_forFoldoutWithBoldText); + + if (serializedProperty_cursorSection_isExpanded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty serializedProperty_curr_cursorPosition_inChartspaceUnits = serializedObject.FindProperty("curr_cursorPosition_inChartspaceUnits"); + EditorGUILayout.PropertyField(serializedProperty_curr_cursorPosition_inChartspaceUnits, new GUIContent("Position")); + + GUILayout.Space(0.3f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("cursorPos0to1_raw"), new GUIContent("Slide 0-1", "Move the cursor between the left end of the chart (0) and the right end of the chart (1).")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("cursorPos0to1_finetune"), new GUIContent("Finetune", "Add fine offset to the cursor slide position.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("cursorPos0to1_superFinetune"), new GUIContent("Super Finetune", "Add very fine offset to the cursor slide position.")); + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSection_axesScaling(GUIStyle style_forFoldoutWithBoldText) + { + SerializedProperty sP_zoomForBothAxesToApply_fromInspectorSlider_m1_to_p1 = serializedObject.FindProperty("zoomForBothAxesToApply_fromInspectorSlider_m1_to_p1"); + SerializedProperty sP_xAxisZoomToApply_fromInspectorSlider_m1_to_p1 = serializedObject.FindProperty("xAxisZoomToApply_fromInspectorSlider_m1_to_p1"); + SerializedProperty sP_xAxisScrollToApply_fromInspectorSlider_m1_to_p1 = serializedObject.FindProperty("xAxisScrollToApply_fromInspectorSlider_m1_to_p1"); + SerializedProperty sP_yAxisZoomToApply_fromInspectorSlider_m1_to_p1 = serializedObject.FindProperty("yAxisZoomToApply_fromInspectorSlider_m1_to_p1"); + SerializedProperty sP_yAxisScrollToApply_fromInspectorSlider_m1_to_p1 = serializedObject.FindProperty("yAxisScrollToApply_fromInspectorSlider_m1_to_p1"); + + SerializedProperty serializedProperty_axesSection_isExpanded = serializedObject.FindProperty("axesSection_isExpanded"); + serializedProperty_axesSection_isExpanded.boolValue = EditorGUILayout.Foldout(serializedProperty_axesSection_isExpanded.boolValue, "Axes Scaling", true, style_forFoldoutWithBoldText); + + if (serializedProperty_axesSection_isExpanded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + GUILayout.Space(0.3f * EditorGUIUtility.singleLineHeight); + + GUILayout.BeginHorizontal(); + GUILayout.Space(15.0f); + GUIContent guiContent_forbutton_showEverything = new GUIContent("Show everything", "Set the axis scaling so that all datapoints of all non-hidden lines are visible."); + if (GUILayout.Button(guiContent_forbutton_showEverything, GUILayout.Width(150))) + { + theDrawXXLChartInspector_unserializedMonoB.ResetAxesScalingTo_encapsulateAllValues(); + } + + SerializedProperty serializedProperty_alwaysEncapsulateAllValues = serializedObject.FindProperty("alwaysEncapsulateAllValues"); + GUIContent guiContent_alwaysEncapsulateAllValues = new GUIContent("Always", "This continuously overwrites the axis scaling so that always all datapoints are visible."); + serializedProperty_alwaysEncapsulateAllValues.boolValue = GUILayout.Toggle(serializedProperty_alwaysEncapsulateAllValues.boolValue, guiContent_alwaysEncapsulateAllValues); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + GUILayout.Space(15.0f); + GUIContent guiContent_forbutton_revertChanges = new GUIContent("Revert changes", "Set the axis scaling to as it was in the moment where the chart was frozen for inspection."); + if (GUILayout.Button(guiContent_forbutton_revertChanges, GUILayout.Width(150))) + { + theDrawXXLChartInspector_unserializedMonoB.ResetAxesScalingTo_stateInMomentOfComponentCreation(); + } + GUILayout.EndHorizontal(); + + EditorGUI.BeginDisabledGroup(serializedProperty_alwaysEncapsulateAllValues.boolValue); + + GUILayout.Space(0.3f * EditorGUIUtility.singleLineHeight); + EditorGUILayout.PropertyField(sP_zoomForBothAxesToApply_fromInspectorSlider_m1_to_p1, new GUIContent("Zoom")); + + GUILayout.Space(0.7f * EditorGUIUtility.singleLineHeight); + EditorGUILayout.PropertyField(sP_xAxisZoomToApply_fromInspectorSlider_m1_to_p1, new GUIContent("Zoom X")); + EditorGUILayout.PropertyField(sP_xAxisScrollToApply_fromInspectorSlider_m1_to_p1, new GUIContent("Scroll X")); + + GUILayout.Space(0.7f * EditorGUIUtility.singleLineHeight); + EditorGUILayout.PropertyField(sP_yAxisZoomToApply_fromInspectorSlider_m1_to_p1, new GUIContent("Zoom Y")); + EditorGUILayout.PropertyField(sP_yAxisScrollToApply_fromInspectorSlider_m1_to_p1, new GUIContent("Scroll Y")); + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + + EditorGUI.EndDisabledGroup(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + if (EditorGUIUtility.hotControl == 0) + { + //This resets the sliders to their zero position in the middle if they are not clicked or dragged + //-> It fakes an "Event.MouseUp" event + sP_zoomForBothAxesToApply_fromInspectorSlider_m1_to_p1.floatValue = 0.0f; + sP_xAxisZoomToApply_fromInspectorSlider_m1_to_p1.floatValue = 0.0f; + sP_xAxisScrollToApply_fromInspectorSlider_m1_to_p1.floatValue = 0.0f; + sP_yAxisZoomToApply_fromInspectorSlider_m1_to_p1.floatValue = 0.0f; + sP_yAxisScrollToApply_fromInspectorSlider_m1_to_p1.floatValue = 0.0f; + } + } + + void DrawSection_other(GUIStyle style_forFoldoutWithBoldText) + { + SerializedProperty serializedProperty_otherSection_isExpanded = serializedObject.FindProperty("otherSection_isExpanded"); + serializedProperty_otherSection_isExpanded.boolValue = EditorGUILayout.Foldout(serializedProperty_otherSection_isExpanded.boolValue, "Other", true, style_forFoldoutWithBoldText); + if (serializedProperty_otherSection_isExpanded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + DrawSection_csvExport(); + DrawSection_clearLineValues(); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("sizeOfDatapointVisualization"), new GUIContent("Size (cursor values)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("curr_luminanceOfLineColors_accordingToSlider"), new GUIContent("Luminance (line colors)", "Changing this can improve the readability of the lines in front of different background brightness.")); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineNamePositions"), new GUIContent("Line names position")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineNames_sizeScaleFactor"), new GUIContent("Size (line names)")); + + int new_maxDisplayedPointOfInterestTextBoxesPerSide = EditorGUILayout.IntField(new GUIContent("Maximum number of Text Boxes (for Points of Interest)", "Some Points of Interest display a text box with explantion text in the top corners of the chart. In some unforeseen situation, for example if many invalid float values are added as data points, the number of text boxes that notify you of these invalid float values can rapidly grow and as a result slow down the Editor performance."), theDrawXXLChartInspector_unserializedMonoB.Get_maxDisplayedPointOfInterestTextBoxesPerSide()); + if (new_maxDisplayedPointOfInterestTextBoxesPerSide != theDrawXXLChartInspector_unserializedMonoB.Get_maxDisplayedPointOfInterestTextBoxesPerSide()) + { + theDrawXXLChartInspector_unserializedMonoB.Set_maxDisplayedPointOfInterestTextBoxesPerSide(new_maxDisplayedPointOfInterestTextBoxesPerSide); + } + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + else + { + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + } + } + + void DrawSection_csvExport() + { + SerializedProperty serializedProperty_csvExportSection_isExpanded = serializedObject.FindProperty("csvExportSection_isExpanded"); + serializedProperty_csvExportSection_isExpanded.boolValue = EditorGUILayout.Foldout(serializedProperty_csvExportSection_isExpanded.boolValue, "CSV file export", true); + if (serializedProperty_csvExportSection_isExpanded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.HelpBox("The file is written into the Assets folder of your project. Existing files with the same name will not be overwritten but a sequential number will be added to the new file name.", MessageType.None, true); + + SerializedProperty serializedProperty_csvFileName = serializedObject.FindProperty("csvFileName"); + serializedProperty_csvFileName.stringValue = EditorGUILayout.TextField("File name", serializedProperty_csvFileName.stringValue); + + GUILayout.BeginHorizontal(); + GUILayout.Space(30.0f); + if (GUILayout.Button("Export")) + { + theDrawXXLChartInspector_unserializedMonoB.ExportCSVFile(serializedProperty_csvFileName.stringValue); + } + GUILayout.EndHorizontal(); + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSection_clearLineValues() + { + SerializedProperty serializedProperty_clearButtonSection_isExpanded = serializedObject.FindProperty("clearButtonSection_isExpanded"); + serializedProperty_clearButtonSection_isExpanded.boolValue = EditorGUILayout.Foldout(serializedProperty_clearButtonSection_isExpanded.boolValue, "Clear Line Data", true); + if (serializedProperty_clearButtonSection_isExpanded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.HelpBox("No 'Undo' possible.", MessageType.Warning, true); + + GUILayout.BeginHorizontal(); + GUILayout.Space(30.0f); + if (GUILayout.Button(new GUIContent("Clear all Line Data Values", "This deletes all data points of all lines of this chart, so you can start with a fresh unfilled chart." + Environment.NewLine + Environment.NewLine + "Be cautious, because this cannot be undone."))) + { + theDrawXXLChartInspector_unserializedMonoB.ClearLineData(); + } + GUILayout.EndHorizontal(); + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSection_lines() + { + GUIStyle boldFontStyle = new GUIStyle(); + boldFontStyle.fontStyle = FontStyle.Bold; + + GUILayout.Label("Lines:", boldFontStyle); + SerializedProperty serializedProperty_specsForInspectorForEachDrawnLine = serializedObject.FindProperty("specsForInspector_forEachDrawnLine"); + for (int i = 0; i < serializedProperty_specsForInspectorForEachDrawnLine.arraySize; i++) + { + EditorGUILayout.PropertyField(serializedProperty_specsForInspectorForEachDrawnLine.GetArrayElementAtIndex(i)); + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/Charts/DrawXXLChartInspector_Inspector.cs.meta b/Editor/DrawDebugLibrary/Charts/DrawXXLChartInspector_Inspector.cs.meta new file mode 100644 index 0000000..b2723b8 --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/DrawXXLChartInspector_Inspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5688d1000cb135347840e17b11efe57b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/Charts/LineSpecsForInspectorDrawer.cs b/Editor/DrawDebugLibrary/Charts/LineSpecsForInspectorDrawer.cs new file mode 100644 index 0000000..5406493 --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/LineSpecsForInspectorDrawer.cs @@ -0,0 +1,196 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomPropertyDrawer(typeof(InternalDXXL_LineSpecsForChartInspector))] + public class LineSpecsForInspectorDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + float currYOffset = 0.0f; + + SerializedProperty serializedProperty_currentHideLineState = property.FindPropertyRelative("currentHideLineState"); + Rect space_ofMainLineHideCheckboxToggle = new Rect(position.x + 0.4f * EditorGUIUtility.singleLineHeight, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + serializedProperty_currentHideLineState.boolValue = !EditorGUI.Toggle(space_ofMainLineHideCheckboxToggle, !serializedProperty_currentHideLineState.boolValue); + + SerializedProperty serializedProperty_lineSection_isExpanded = property.FindPropertyRelative("lineSection_isExpanded"); + Rect space_ofMainFoldout = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + serializedProperty_lineSection_isExpanded.boolValue = EditorGUI.Foldout(space_ofMainFoldout, serializedProperty_lineSection_isExpanded.boolValue, GUIContent.none, true, EditorStyles.foldout); + + SerializedProperty serializedProperty_lineColor = property.FindPropertyRelative("lineColor"); + SerializedProperty serializedProperty_linesCompoundName = property.FindPropertyRelative("linesCompoundName"); + + GUIStyle richtextEnabled_fontStyle = new GUIStyle(); + richtextEnabled_fontStyle.richText = true; + float indent_ofColoredLineName = 50; + Rect space_ofColoredLineName = new Rect(position.x + 1.6f * EditorGUIUtility.singleLineHeight, position.y + currYOffset, position.width - indent_ofColoredLineName, position.height); + EditorGUI.LabelField(space_ofColoredLineName, "Line: " + serializedProperty_linesCompoundName.stringValue + "", richtextEnabled_fontStyle); + + if (serializedProperty_lineSection_isExpanded.boolValue) + { + int previousIndent = EditorGUI.indentLevel; + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + Rect space_ofColorPicker = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_ofColorPicker, serializedProperty_lineColor, new GUIContent("Color")); + + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + SerializedProperty serializedProperty_currentHideCursorXState_duringComponentInspectionPhase = property.FindPropertyRelative("currentHideCursorXState_duringComponentInspectionPhase"); + Rect space_ofHideCursorXToggle = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + serializedProperty_currentHideCursorXState_duringComponentInspectionPhase.boolValue = !EditorGUI.Toggle(space_ofHideCursorXToggle, "Draw X value", !serializedProperty_currentHideCursorXState_duringComponentInspectionPhase.boolValue); + + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + SerializedProperty serializedProperty_currentHideCursorYState_duringComponentInspectionPhase = property.FindPropertyRelative("currentHideCursorYState_duringComponentInspectionPhase"); + Rect space_ofHideCursorYToggle = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + serializedProperty_currentHideCursorYState_duringComponentInspectionPhase.boolValue = !EditorGUI.Toggle(space_ofHideCursorYToggle, "Draw Y value", !serializedProperty_currentHideCursorYState_duringComponentInspectionPhase.boolValue); + + DrawXXLChartInspector theDrawXXLChartInspector = (DrawXXLChartInspector)property.serializedObject.targetObject; + bool thisLineIsTheOnlyOneOfTheChart = theDrawXXLChartInspector.ContainsOnly1Line_hiddenOrUnhidden(); + + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + EditorGUI.BeginDisabledGroup(thisLineIsTheOnlyOneOfTheChart); + SerializedProperty serializedProperty_i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray = property.FindPropertyRelative("i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray"); + Rect space_ofButton_hideAllOtherLines = new Rect(position.x + 15.0f, position.y + currYOffset, 150.0f, EditorGUIUtility.singleLineHeight); + if (theDrawXXLChartInspector.AllOtherLinesAreHidden(serializedProperty_i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray.intValue)) + { + if (GUI.Button(space_ofButton_hideAllOtherLines, "Unhide all lines ")) + { + theDrawXXLChartInspector.UnhideAllLines(); + } + } + else + { + if (GUI.Button(space_ofButton_hideAllOtherLines, "Hide all other lines ")) + { + theDrawXXLChartInspector.HideAllOtherLines(serializedProperty_i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray.intValue); + } + } + + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + Rect space_ofButton_hideAllOtherCursors = new Rect(position.x + 15.0f, position.y + currYOffset, 150.0f, EditorGUIUtility.singleLineHeight); + if (theDrawXXLChartInspector.AllOtherCursorsAreHidden(serializedProperty_i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray.intValue)) + { + if (GUI.Button(space_ofButton_hideAllOtherCursors, "Unhide all cursors")) + { + theDrawXXLChartInspector.UnhideAllCursors(serializedProperty_i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray.intValue); + } + } + else + { + if (GUI.Button(space_ofButton_hideAllOtherCursors, "Hide all other cursors")) + { + theDrawXXLChartInspector.HideAllOtherCursors(serializedProperty_i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray.intValue); + } + } + EditorGUI.EndDisabledGroup(); + + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + SerializedProperty serializedProperty_alpha_ofVertFillLines = property.FindPropertyRelative("alpha_ofVertFillLines"); + GUIContent guiContent_for_alpha_ofVertFillLines = new GUIContent("Fill area (alpha)"); + Rect space_of_alpha_ofVertFillLines = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_of_alpha_ofVertFillLines, serializedProperty_alpha_ofVertFillLines, guiContent_for_alpha_ofVertFillLines); + if (serializedProperty_alpha_ofVertFillLines.floatValue < 0.001f) { serializedProperty_alpha_ofVertFillLines.floatValue = 0.0f; } //-> prenting float calculation uncertainty errors to accidentaly activate the many drawn lines for fillVerticalSpace + + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + SerializedProperty serializedProperty_lineWidth = property.FindPropertyRelative("lineWidth"); + GUIContent guiContent_forWidthSlider = new GUIContent("Width", "This is relative to the chart height." + Environment.NewLine + Environment.NewLine + "Performance warning: Setting this to values other than 0 can significantly increase the number of drawn lines."); + Rect space_ofWidthSlider = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_ofWidthSlider, serializedProperty_lineWidth, guiContent_forWidthSlider); + if (serializedProperty_lineWidth.floatValue < 0.00005f) { serializedProperty_lineWidth.floatValue = 0.0f; } //-> prenting float calculation uncertainty errors to accidentaly activate the many drawn lines for non-zeroWidth-lines + + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + Rect space_of_connectionsType = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_of_connectionsType, property.FindPropertyRelative("connectionsType"), new GUIContent("Connection style")); + + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + Rect space_of_dataPointVisualization = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_of_dataPointVisualization, property.FindPropertyRelative("dataPointVisualization"), new GUIContent("Points style")); + + bool datapointVisualizerOfLineAreInvisible = theDrawXXLChartInspector.DatapointVisualizerOfLineAreInvisible(serializedProperty_i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray.intValue); + EditorGUI.BeginDisabledGroup(datapointVisualizerOfLineAreInvisible); + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + Rect space_of_dataPointVisualization_size = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_of_dataPointVisualization_size, property.FindPropertyRelative("dataPointVisualization_size"), new GUIContent("Points size")); + EditorGUI.EndDisabledGroup(); + + currYOffset = currYOffset + (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + GUIStyle style_forDatapointValuesHeadline = new GUIStyle(EditorStyles.foldout); + style_forDatapointValuesHeadline.richText = true; + SerializedProperty serializedProperty_datapointValuesSection_isExpanded = property.FindPropertyRelative("datapointValuesSection_isExpanded"); + Rect space_ofDatapointArrayFoldout = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + serializedProperty_datapointValuesSection_isExpanded.boolValue = EditorGUI.Foldout(space_ofDatapointArrayFoldout, serializedProperty_datapointValuesSection_isExpanded.boolValue, "Datapoint Values (read only)", true, style_forDatapointValuesHeadline); + + if (serializedProperty_datapointValuesSection_isExpanded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty arrayOfNeighboringDatapoints = property.FindPropertyRelative("neighboringDatapointValues"); + int arraySize = arrayOfNeighboringDatapoints.arraySize; + + currYOffset = currYOffset + 1.5f * EditorGUIUtility.singleLineHeight; + Rect space_ofArrayLengthChooser = new Rect(position.x, position.y + currYOffset, position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_ofArrayLengthChooser, property.FindPropertyRelative("numberOfDisplayedDatapointsInArray"), new GUIContent("Listed values")); + + currYOffset = currYOffset + 1.5f * EditorGUIUtility.singleLineHeight; + int i_insideShortenedForInspectorArray_markingTheValueAtCursor = property.FindPropertyRelative("i_insideShortenedForInspectorArray_markingTheValueAtCursor").intValue; + for (int i = 0; i < arraySize; i++) + { + SerializedProperty datapointValuesOfCurrentSlot = arrayOfNeighboringDatapoints.GetArrayElementAtIndex(i); + string slotName = GetArraySlotName(i, i_insideShortenedForInspectorArray_markingTheValueAtCursor); + Rect space_ofCurrDataPoint = new Rect(position.x, position.y + (currYOffset + (i * (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing))), position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_ofCurrDataPoint, datapointValuesOfCurrentSlot, new GUIContent(slotName)); + } + } + + EditorGUI.indentLevel = previousIndent; + } + + } + + string GetArraySlotName(int i, int i_insideShortenedForInspectorArray_markingTheValueAtCursor) + { + int indexesDistance_toCursor = i - i_insideShortenedForInspectorArray_markingTheValueAtCursor; + if (indexesDistance_toCursor == 0) + { + return ("At Cursor"); + } + else + { + if (indexesDistance_toCursor < 0) + { + return ("Cursor -" + Mathf.Abs(indexesDistance_toCursor)); + } + else + { + return ("Cursor +" + Mathf.Abs(indexesDistance_toCursor)); + } + } + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + if (property.FindPropertyRelative("lineSection_isExpanded").boolValue) + { + if (property.FindPropertyRelative("datapointValuesSection_isExpanded").boolValue) + { + int displayedDatapointValues = property.FindPropertyRelative("neighboringDatapointValues").arraySize; + return (EditorGUIUtility.singleLineHeight) * (15.0f + displayedDatapointValues) + (EditorGUIUtility.standardVerticalSpacing) * (13.0f + displayedDatapointValues); + } + else + { + return (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing) * 13.0f; + } + } + else + { + return EditorGUIUtility.singleLineHeight; + } + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/Charts/LineSpecsForInspectorDrawer.cs.meta b/Editor/DrawDebugLibrary/Charts/LineSpecsForInspectorDrawer.cs.meta new file mode 100644 index 0000000..d0c2cde --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/LineSpecsForInspectorDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9784fcad8f2d38947a80c2a6124dd623 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/Charts/NeighboringDatapointForInspectorDrawer.cs b/Editor/DrawDebugLibrary/Charts/NeighboringDatapointForInspectorDrawer.cs new file mode 100644 index 0000000..c598f13 --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/NeighboringDatapointForInspectorDrawer.cs @@ -0,0 +1,47 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomPropertyDrawer(typeof(InternalDXXL_NeighboringDatapointForChartInspector))] + public class NeighboringDatapointForInspectorDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + GUIStyle labelStyle = new GUIStyle(EditorStyles.label); + labelStyle.richText = true; + EditorGUI.LabelField(position, label, labelStyle); + + float previousLabelWidth = EditorGUIUtility.labelWidth; + + float xStartPos = position.x + 0.25f * position.width; + float width_allThree = position.width - xStartPos + EditorGUIUtility.singleLineHeight; + float xWidth = width_allThree * 0.28f; + EditorGUIUtility.labelWidth = 40.0f; + Rect space_ofX = new Rect(xStartPos, position.y, xWidth + 1.3f * EditorGUIUtility.singleLineHeight, position.height); + EditorGUI.PropertyField(space_ofX, property.FindPropertyRelative("x"), new GUIContent("X")); + + float yStartPos = xStartPos + xWidth; + float yWidth = width_allThree * 0.28f; + EditorGUIUtility.labelWidth = 40.0f; + Rect space_ofY = new Rect(yStartPos, position.y, yWidth + 1.3f * EditorGUIUtility.singleLineHeight, position.height); + EditorGUI.PropertyField(space_ofY, property.FindPropertyRelative("y"), new GUIContent("Y")); + + float dStartPos = yStartPos + yWidth; + float dWidth = width_allThree * 0.44f; + EditorGUIUtility.labelWidth = 72.0f; + Rect space_ofDelta = new Rect(dStartPos, position.y, dWidth, position.height); + EditorGUI.PropertyField(space_ofDelta, property.FindPropertyRelative("deltaSincePrecedingY"), new GUIContent("delta Y")); + + EditorGUIUtility.labelWidth = previousLabelWidth; + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return EditorGUIUtility.singleLineHeight; + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/Charts/NeighboringDatapointForInspectorDrawer.cs.meta b/Editor/DrawDebugLibrary/Charts/NeighboringDatapointForInspectorDrawer.cs.meta new file mode 100644 index 0000000..96d789a --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/NeighboringDatapointForInspectorDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 14f2c736c6c47e84796c3b4ed6761626 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/Charts/line charts.meta b/Editor/DrawDebugLibrary/Charts/line charts.meta new file mode 100644 index 0000000..6442cc9 --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/line charts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ba836645a0c573c4e8f0411c1cc6afad +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/Charts/line charts/internal utilities.meta b/Editor/DrawDebugLibrary/Charts/line charts/internal utilities.meta new file mode 100644 index 0000000..9ecd517 --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/line charts/internal utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7248b4bbde31bdc48bc0544ecf731e81 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/Charts/line charts/internal utilities/InternalDXXL_ChartHandles.cs b/Editor/DrawDebugLibrary/Charts/line charts/internal utilities/InternalDXXL_ChartHandles.cs new file mode 100644 index 0000000..d525137 --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/line charts/internal utilities/InternalDXXL_ChartHandles.cs @@ -0,0 +1,437 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + using DrawXXL; + + public class InternalDXXL_ChartHandles + { + static float valueToSlide_duringMouseDown; + static Vector2 currentMousePosition; + static Vector2 mousePosition_duringMouseDown; + static Vector3 sliderPosition_worldSpace_duringMouseDown; + + public static float CursorSlider(bool isAtLowerEndOfCursorsVertLine_notAtUpperEnd, float valueToSlide, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB) + { + int control_ID = GUIUtility.GetControlID(FocusType.Passive); + Event currentEvent = Event.current; + Vector3 current_sliderPosition_worldSpace = Get_current_cursorSliderPosition_worldSpace(isAtLowerEndOfCursorsVertLine_notAtUpperEnd, theDrawXXLChartInspector_unserializedMonoB); + switch (currentEvent.GetTypeForControl(control_ID)) + { + case EventType.MouseDown: + if ((HandleUtility.nearestControl == control_ID) && (currentEvent.button == 0) && (currentEvent.alt == false)) + { + GUIUtility.hotControl = control_ID; + valueToSlide_duringMouseDown = valueToSlide; + mousePosition_duringMouseDown = currentEvent.mousePosition; + currentMousePosition = currentEvent.mousePosition; + sliderPosition_worldSpace_duringMouseDown = current_sliderPosition_worldSpace; + currentEvent.Use(); + EditorGUIUtility.SetWantsMouseJumping(1); + } + break; + case EventType.MouseUp: + if (GUIUtility.hotControl == control_ID) + { + GUIUtility.hotControl = 0; + currentEvent.Use(); + EditorGUIUtility.SetWantsMouseJumping(0); + } + break; + case EventType.MouseDrag: + if (GUIUtility.hotControl == control_ID) + { + currentMousePosition = currentMousePosition + currentEvent.delta; + Vector3 cursorSlideDirection = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.xAxis.AxisVector_normalized_inWorldSpace; + float travelledDistance_sinceMouseDown = HandleUtility.CalcLineTranslation(mousePosition_duringMouseDown, currentMousePosition, sliderPosition_worldSpace_duringMouseDown, cursorSlideDirection); + valueToSlide = valueToSlide_duringMouseDown + travelledDistance_sinceMouseDown; + GUI.changed = true; + currentEvent.Use(); + } + break; + case EventType.Repaint: + Color color_before = Handles.color; + TrySetColorDuringMouseInteraction(control_ID, theDrawXXLChartInspector_unserializedMonoB, currentEvent); + DrawConeCap(isAtLowerEndOfCursorsVertLine_notAtUpperEnd, control_ID, theDrawXXLChartInspector_unserializedMonoB, EventType.Repaint); + Handles.color = color_before; + break; + case EventType.Layout: + DrawConeCap(isAtLowerEndOfCursorsVertLine_notAtUpperEnd, control_ID, theDrawXXLChartInspector_unserializedMonoB, EventType.Layout); + break; + default: + break; + } + return valueToSlide; + } + + static Vector3 Get_current_cursorSliderPosition_worldSpace(bool isAtLowerEndOfCursorsVertLine_notAtUpperEnd, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB) + { + return (isAtLowerEndOfCursorsVertLine_notAtUpperEnd ? theDrawXXLChartInspector_unserializedMonoB.GetCursorPosOnLowerEndOfChart() : theDrawXXLChartInspector_unserializedMonoB.GetCursorPosOnHigherEndOfChart()); + } + + static void DrawConeCap(bool isAtLowerEndOfCursorsVertLine_notAtUpperEnd, int control_ID, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB, EventType eventType) + { + Matrix4x4 matrix_before = Handles.matrix; + + float sizeOfCursorHandleCone = theDrawXXLChartInspector_unserializedMonoB.GetHeightOfCursorPyramid(); + Vector3 position_ofCustomMatrixSpace = Get_current_cursorSliderPosition_worldSpace(isAtLowerEndOfCursorsVertLine_notAtUpperEnd, theDrawXXLChartInspector_unserializedMonoB); + Vector3 positionOfCone_insideCustomMatrixSpace = Vector3.forward * (0.5f * sizeOfCursorHandleCone);//-> shifting the cone, so that his base it at the "position_ofCustomMatrixSpace", and not his center + Vector3 forwardOfCustomMatrixSpace = isAtLowerEndOfCursorsVertLine_notAtUpperEnd ? (theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.yAxis.AxisVector_normalized_inWorldSpace) : (-theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.yAxis.AxisVector_normalized_inWorldSpace); + Quaternion rotation_ofCustomMatrixSpace = Quaternion.LookRotation(forwardOfCustomMatrixSpace); + Quaternion rotationOfCone_insideCustomMatrixSpace = Quaternion.identity; //-> no rotation inside the custom matrix space. The cone rotation is already done by rotation the whole custom matrix space. + float coneBase_scaleFactor = 3.0f; + Vector3 scale_ofCustomMatrixSpace = new Vector3(coneBase_scaleFactor, coneBase_scaleFactor, 1.0f); //-> This is the reason for the whole custom matrix: Warping the cone shape, so that appears less pointy + Matrix4x4 warpedMatrix_oriniatingAtConeBase = Matrix4x4.TRS(position_ofCustomMatrixSpace, rotation_ofCustomMatrixSpace, scale_ofCustomMatrixSpace); + + Handles.matrix = warpedMatrix_oriniatingAtConeBase; + Handles.ConeHandleCap(control_ID, positionOfCone_insideCustomMatrixSpace, rotationOfCone_insideCustomMatrixSpace, sizeOfCursorHandleCone, eventType); + Handles.matrix = matrix_before; + } + + public static float OneDirectionalBacksnapSlider(float travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, Vector3 restingPosition, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB, Vector3 sliderDirection_worldSpace_normalized, Handles.CapFunction capFunction, float capSizeScaleFactor, GUIContent icon, float iconSizeFactor, Vector2 iconPositionOffset_inScreenspace_relToHandleCapSize, bool clampTravelledDistance_inThePositiveDirection, bool drawSpiralSpring) + { + //-> see "HandlesExamples.AnalogJoystickSlider()" for a more generic version of this function + + int control_ID = GUIUtility.GetControlID(FocusType.Passive); + Event currentEvent = Event.current; + switch (currentEvent.GetTypeForControl(control_ID)) + { + case EventType.MouseDown: + if ((HandleUtility.nearestControl == control_ID) && (currentEvent.button == 0) && (currentEvent.alt == false)) + { + GUIUtility.hotControl = control_ID; + mousePosition_duringMouseDown = currentEvent.mousePosition; + currentMousePosition = currentEvent.mousePosition; + theDrawXXLChartInspector_unserializedMonoB.SaveZoomAndScrollState_onMouseDown(); + currentEvent.Use(); + EditorGUIUtility.SetWantsMouseJumping(1); + } + break; + case EventType.MouseUp: + if (GUIUtility.hotControl == control_ID) + { + travelledWorldSpaceDistanceAlongDirection_sinceMouseDown = 0.0f; + GUIUtility.hotControl = 0; + currentEvent.Use(); + EditorGUIUtility.SetWantsMouseJumping(0); + } + break; + case EventType.MouseDrag: + if (GUIUtility.hotControl == control_ID) + { + currentMousePosition = currentMousePosition + currentEvent.delta; + travelledWorldSpaceDistanceAlongDirection_sinceMouseDown = HandleUtility.CalcLineTranslation(mousePosition_duringMouseDown, currentMousePosition, restingPosition, sliderDirection_worldSpace_normalized); + travelledWorldSpaceDistanceAlongDirection_sinceMouseDown = TryClampTravelledDistanceInThePositiveDirection(clampTravelledDistance_inThePositiveDirection, travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, theDrawXXLChartInspector_unserializedMonoB); + GUI.changed = true; + currentEvent.Use(); + } + break; + case EventType.Repaint: + Color color_before = Handles.color; + TrySetColorDuringMouseInteraction(control_ID, theDrawXXLChartInspector_unserializedMonoB, currentEvent); + TryDrawSpiralSpring(control_ID, drawSpiralSpring, travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, restingPosition, theDrawXXLChartInspector_unserializedMonoB, sliderDirection_worldSpace_normalized); + DrawOneDimensionalBacksnapSliderCap(control_ID, travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, restingPosition, theDrawXXLChartInspector_unserializedMonoB, sliderDirection_worldSpace_normalized, capFunction, capSizeScaleFactor, EventType.Repaint); + Handles.color = color_before; + break; + case EventType.Layout: + DrawOneDimensionalBacksnapSliderCap(control_ID, travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, restingPosition, theDrawXXLChartInspector_unserializedMonoB, sliderDirection_worldSpace_normalized, capFunction, capSizeScaleFactor, EventType.Layout); + break; + default: + break; + } + + DrawIcon_onOneDimensionalBacksnapSlider(travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, restingPosition, theDrawXXLChartInspector_unserializedMonoB, sliderDirection_worldSpace_normalized, icon, iconSizeFactor, iconPositionOffset_inScreenspace_relToHandleCapSize); + return travelledWorldSpaceDistanceAlongDirection_sinceMouseDown; + } + + static float TryClampTravelledDistanceInThePositiveDirection(bool clampTravelledDistance_inThePositiveDirection, float travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB) + { + if (clampTravelledDistance_inThePositiveDirection) + { + if (travelledWorldSpaceDistanceAlongDirection_sinceMouseDown > 0.0f) + { + return Mathf.Min(travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, theDrawXXLChartInspector_unserializedMonoB.GetBacksnapSliderReferenceLength_inWorldspaceUnits()); + } + } + return travelledWorldSpaceDistanceAlongDirection_sinceMouseDown; + } + + static void TryDrawSpiralSpring(int control_ID, bool drawSpiralSpring, float travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, Vector3 restingPosition, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB, Vector3 sliderDirection_worldSpace_normalized) + { + if (drawSpiralSpring) + { + if (GUIUtility.hotControl == control_ID) + { + HandlesExamples.ConfigureDrawXXLsGlobalSettingsForDrawingHandles(); + + //Generated via code snippet/live template: + Vector3 start_of_spiral = restingPosition; + Vector3 end_of_spiral = Get_currentPosition_ofOneDimensionalBacksnapSlider(travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, restingPosition, sliderDirection_worldSpace_normalized); + float relaxedLength_of_spiral = theDrawXXLChartInspector_unserializedMonoB.GetBacksnapSliderReferenceLength_inWorldspaceUnits(); + Color relaxedColor_of_spiral = Handles.color; + DrawBasics.LineStyle style_of_spiral = DrawBasics.LineStyle.spiral; + float stretchFactor_forStretchedTensionColor_of_spiral = 2.0f; + Color color_forStretchedTension_of_spiral = Handles.color; + float stretchFactor_forSqueezedTensionColor_of_spiral = 0.0f; + Color color_forSqueezedTension_of_spiral = Handles.color; + float width_of_spiral = 0.0f; + string text_of_spiral = null; + float alphaOfReferenceLengthDisplay_of_spiral = 0.5f; + float stylePatternScaleFactor_of_spiral = 0.7f * (theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Width_inWorldSpace + theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.Height_inWorldSpace); + Vector3 customAmplitudeAndTextDir_of_spiral = default(Vector3); + bool flattenThickRoundLineIntoAmplitudePlane_of_spiral = false; + float endPlates_size_of_spiral = 0.0f; + float enlargeSmallTextToThisMinTextSize_of_spiral = 0.0f; + float durationInSec_of_spiral = 0.0f; + bool hiddenByNearerObjects_of_spiral = true; + bool skipPatternEnlargementForLongLines_of_spiral = true; + bool skipPatternEnlargementForShortLines_of_spiral = true; + + float stylePatternScaleFactor_alongLineDir_ignoringAmplitude_before = DrawBasics.StylePatternScaleFactor_alongLineDir_ignoringAmplitude; + DrawBasics.StylePatternScaleFactor_alongLineDir_ignoringAmplitude = 0.6f; //-> Instruct Draw XXL how to use this style scaling for all following draw operations + DrawBasics.LineUnderTension(start_of_spiral, end_of_spiral, relaxedLength_of_spiral, relaxedColor_of_spiral, style_of_spiral, stretchFactor_forStretchedTensionColor_of_spiral, color_forStretchedTension_of_spiral, stretchFactor_forSqueezedTensionColor_of_spiral, color_forSqueezedTension_of_spiral, width_of_spiral, text_of_spiral, alphaOfReferenceLengthDisplay_of_spiral, stylePatternScaleFactor_of_spiral, customAmplitudeAndTextDir_of_spiral, flattenThickRoundLineIntoAmplitudePlane_of_spiral, endPlates_size_of_spiral, enlargeSmallTextToThisMinTextSize_of_spiral, durationInSec_of_spiral, hiddenByNearerObjects_of_spiral, skipPatternEnlargementForLongLines_of_spiral, skipPatternEnlargementForShortLines_of_spiral); + DrawBasics.StylePatternScaleFactor_alongLineDir_ignoringAmplitude = stylePatternScaleFactor_alongLineDir_ignoringAmplitude_before; //-> Revert the Draw XXL setting to what it was before + + //Generated via code snippet/live template: + Vector3 position_of_dot = restingPosition; + float radius_of_dot = 0.003f * stylePatternScaleFactor_of_spiral; + Vector3 normal_of_dot = default(Vector3); //-> this will automatically point to the Scene View Camera, because "DrawShapes.automaticOrientationOfFlatShapes" has been set accordingly inside "HandlesExamples.ConfigureDrawXXLsGlobalSettingsForDrawingHandles()" + Color color_of_dot = Handles.color; + string text_of_dot = null; + float density_of_dot = 1.0f; + float durationInSec_of_dot = 0.0f; + bool hiddenByNearerObjects_of_dot = true; + DrawBasics.Dot(position_of_dot, radius_of_dot, normal_of_dot, color_of_dot, text_of_dot, density_of_dot, durationInSec_of_dot, hiddenByNearerObjects_of_dot); + + HandlesExamples.RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore(); + } + } + } + + static void DrawOneDimensionalBacksnapSliderCap(int control_ID, float travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, Vector3 restingPosition, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB, Vector3 sliderDirection_worldSpace_normalized, Handles.CapFunction capFunction, float capSizeScaleFactor, EventType eventType) + { + Vector3 currentPosition_ofBacksnapSlider = Get_currentPosition_ofOneDimensionalBacksnapSlider(travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, restingPosition, sliderDirection_worldSpace_normalized); + float size = GetSizeOfButtonCaps_withoutWeightFactorFromCapTypeApplied(theDrawXXLChartInspector_unserializedMonoB) * capSizeScaleFactor; + Quaternion rotation = Quaternion.LookRotation(sliderDirection_worldSpace_normalized); + capFunction(control_ID, currentPosition_ofBacksnapSlider, rotation, size, eventType); + } + + static void DrawIcon_onOneDimensionalBacksnapSlider(float travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, Vector3 restingPosition, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB, Vector3 sliderDirection_worldSpace_normalized, GUIContent icon, float iconSizeFactor, Vector2 iconPositionOffset_inScreenspace_relToHandleCapSize) + { + if (SceneView.lastActiveSceneView != null) + { + float handleCapSize_inWorldSpace = GetSizeOfButtonCaps_withoutWeightFactorFromCapTypeApplied(theDrawXXLChartInspector_unserializedMonoB); + + Vector3 worldSpaceOffset_thatShiftsTheIconAlongScreenspaceXDir = SceneView.lastActiveSceneView.camera.transform.right * handleCapSize_inWorldSpace * iconPositionOffset_inScreenspace_relToHandleCapSize.x; + Vector3 worldSpaceOffset_thatShiftsTheIconAlongScreenspaceYDir = SceneView.lastActiveSceneView.camera.transform.up * handleCapSize_inWorldSpace * iconPositionOffset_inScreenspace_relToHandleCapSize.y; + Vector3 iconPosition = Get_currentPosition_ofOneDimensionalBacksnapSlider(travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, restingPosition, sliderDirection_worldSpace_normalized) + worldSpaceOffset_thatShiftsTheIconAlongScreenspaceXDir + worldSpaceOffset_thatShiftsTheIconAlongScreenspaceYDir; + float iconSize_asFloat_inWorldSpace = handleCapSize_inWorldSpace * iconSizeFactor; + Vector2 iconSize_inPixels_asVector2 = ConvertIconSize_fromWorldspaceSize_toPixelSize(iconSize_asFloat_inWorldSpace, iconPosition); + + Vector2 iconSize_before = EditorGUIUtility.GetIconSize(); + EditorGUIUtility.SetIconSize(iconSize_inPixels_asVector2); + Handles.Label(iconPosition, icon); + EditorGUIUtility.SetIconSize(iconSize_before); + } + } + + static Vector3 Get_currentPosition_ofOneDimensionalBacksnapSlider(float travelledWorldSpaceDistanceAlongDirection_sinceMouseDown, Vector3 restingPosition, Vector3 sliderDirection_worldSpace_normalized) + { + return (restingPosition + sliderDirection_worldSpace_normalized * travelledWorldSpaceDistanceAlongDirection_sinceMouseDown); + } + + public static void TwoDirectionalBacksnapSlider(ref float travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown, ref float travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown, Vector3 restingPosition, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB, float capSizeScaleFactor, GUIContent icon, float iconSizeFactor, Vector2 iconPositionOffset_inScreenspace_relToHandleCapSize) + { + int control_ID = GUIUtility.GetControlID(FocusType.Passive); + Event currentEvent = Event.current; + switch (currentEvent.GetTypeForControl(control_ID)) + { + case EventType.MouseDown: + if ((HandleUtility.nearestControl == control_ID) && (currentEvent.button == 0) && (currentEvent.alt == false)) + { + GUIUtility.hotControl = control_ID; + mousePosition_duringMouseDown = currentEvent.mousePosition; + currentMousePosition = currentEvent.mousePosition; + theDrawXXLChartInspector_unserializedMonoB.SaveZoomAndScrollState_onMouseDown(); + currentEvent.Use(); + EditorGUIUtility.SetWantsMouseJumping(1); + } + break; + case EventType.MouseUp: + if (GUIUtility.hotControl == control_ID) + { + travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown = 0.0f; + travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown = 0.0f; + GUIUtility.hotControl = 0; + currentEvent.Use(); + EditorGUIUtility.SetWantsMouseJumping(0); + } + break; + case EventType.MouseDrag: + if (GUIUtility.hotControl == control_ID) + { + currentMousePosition = currentMousePosition + currentEvent.delta; + travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown = HandleUtility.CalcLineTranslation(mousePosition_duringMouseDown, currentMousePosition, restingPosition, theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.xAxis.AxisVector_normalized_inWorldSpace); + travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown = HandleUtility.CalcLineTranslation(mousePosition_duringMouseDown, currentMousePosition, restingPosition, theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.yAxis.AxisVector_normalized_inWorldSpace); + GUI.changed = true; + currentEvent.Use(); + } + break; + case EventType.Repaint: + Color color_before = Handles.color; + TrySetColorDuringMouseInteraction(control_ID, theDrawXXLChartInspector_unserializedMonoB, currentEvent); + DrawTwoDimensionalBacksnapSliderCap(control_ID, travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown, travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown, restingPosition, theDrawXXLChartInspector_unserializedMonoB, capSizeScaleFactor, EventType.Repaint); + Handles.color = color_before; + break; + case EventType.Layout: + DrawTwoDimensionalBacksnapSliderCap(control_ID, travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown, travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown, restingPosition, theDrawXXLChartInspector_unserializedMonoB, capSizeScaleFactor, EventType.Layout); + break; + default: + break; + } + + DrawIcon_onTwoDimensionalBacksnapSlider(travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown, travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown, restingPosition, theDrawXXLChartInspector_unserializedMonoB, icon, iconSizeFactor, iconPositionOffset_inScreenspace_relToHandleCapSize); + } + + static void DrawTwoDimensionalBacksnapSliderCap(int control_ID, float travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown, float travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown, Vector3 restingPosition, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB, float capSizeScaleFactor, EventType eventType) + { + Vector3 currentPosition_ofBacksnapSlider = Get_currentPosition_ofTwoDimensionalBacksnapSlider(travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown, travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown, restingPosition, theDrawXXLChartInspector_unserializedMonoB); + float size = GetSizeOfButtonCaps_withoutWeightFactorFromCapTypeApplied(theDrawXXLChartInspector_unserializedMonoB) * capSizeScaleFactor; + Handles.SphereHandleCap(control_ID, currentPosition_ofBacksnapSlider, Quaternion.identity, size, eventType); + } + + static float GetSizeOfButtonCaps_withoutWeightFactorFromCapTypeApplied(DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB) + { + return theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.xAxis.Get_fixedConeLength_forBothAxisVectors(); + } + + static void DrawIcon_onTwoDimensionalBacksnapSlider(float travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown, float travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown, Vector3 restingPosition, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB, GUIContent icon, float iconSizeFactor, Vector2 iconPositionOffset_inScreenspace_relToHandleCapSize) + { + if (SceneView.lastActiveSceneView != null) + { + float handleCapSize_inWorldSpace = GetSizeOfButtonCaps_withoutWeightFactorFromCapTypeApplied(theDrawXXLChartInspector_unserializedMonoB); + + Vector3 worldSpaceOffset_thatShiftsTheIconAlongScreenspaceXDir = SceneView.lastActiveSceneView.camera.transform.right * handleCapSize_inWorldSpace * iconPositionOffset_inScreenspace_relToHandleCapSize.x; + Vector3 worldSpaceOffset_thatShiftsTheIconAlongScreenspaceYDir = SceneView.lastActiveSceneView.camera.transform.up * handleCapSize_inWorldSpace * iconPositionOffset_inScreenspace_relToHandleCapSize.y; + Vector3 iconPosition = Get_currentPosition_ofTwoDimensionalBacksnapSlider(travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown, travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown, restingPosition, theDrawXXLChartInspector_unserializedMonoB) + worldSpaceOffset_thatShiftsTheIconAlongScreenspaceXDir + worldSpaceOffset_thatShiftsTheIconAlongScreenspaceYDir; + float iconSize_asFloat_inWorldSpace = handleCapSize_inWorldSpace * iconSizeFactor; + Vector2 iconSize_inPixels_asVector2 = ConvertIconSize_fromWorldspaceSize_toPixelSize(iconSize_asFloat_inWorldSpace, iconPosition); + + Vector2 iconSize_before = EditorGUIUtility.GetIconSize(); + EditorGUIUtility.SetIconSize(iconSize_inPixels_asVector2); + Handles.Label(iconPosition, icon); + EditorGUIUtility.SetIconSize(iconSize_before); + } + } + + static Vector3 Get_currentPosition_ofTwoDimensionalBacksnapSlider(float travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown, float travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown, Vector3 restingPosition, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB) + { + Vector3 dragOffset_alongXAxis = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.xAxis.AxisVector_normalized_inWorldSpace * travelledWorldSpaceDistanceAlongChartsXDirection_sinceMouseDown; + Vector3 dragOffset_alongYAxis = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.yAxis.AxisVector_normalized_inWorldSpace * travelledWorldSpaceDistanceAlongChartsYDirection_sinceMouseDown; + return (restingPosition + dragOffset_alongXAxis + dragOffset_alongYAxis); + } + + + static Vector2 ConvertIconSize_fromWorldspaceSize_toPixelSize(float iconSize_asFloat_inWorldSpace, Vector3 iconPosition) + { + float iconSize_asFloat_inScreenspace0to1 = UtilitiesDXXL_Screenspace.WorldSpaceExtent_to_viewportSpaceExtentRelToScreenHeight(SceneView.lastActiveSceneView.camera, iconPosition, iconSize_asFloat_inWorldSpace); + float iconSize_inPixels = iconSize_asFloat_inScreenspace0to1 * SceneView.lastActiveSceneView.camera.pixelHeight; + return new Vector2(iconSize_inPixels, iconSize_inPixels); + } + + static void TrySetColorDuringMouseInteraction(int control_ID, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB, Event currentEvent) + { + if (control_ID == GUIUtility.hotControl) + { + Handles.color = Handles.selectedColor; + } + else + { + if (IsHovering(control_ID, currentEvent)) + { + Handles.color = Handles.preselectionColor; + } + else + { + Handles.color = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.color; + } + } + } + + static bool IsHovering(int control_ID, Event currentEvent) + { + return ((GUIUtility.hotControl == 0) && (control_ID == HandleUtility.nearestControl) && (currentEvent.alt == false)); + } + + public static bool ShowAllButton(bool checkmarkState, Vector3 position, DrawXXLChartInspector theDrawXXLChartInspector_unserializedMonoB, float sizeScaleFactor, GUIContent checkmarkSymbol, GUIContent crossSymbol, float sizeFactor_forCheckmarkIcon, float sizeFactor_forCrossIcon, Vector2 checkmarkIconPositionOffset_inScreenspace_relToHandleCapSize, Vector2 crossIconPositionOffset_inScreenspace_relToHandleCapSize) + { + if (SceneView.lastActiveSceneView == null) + { + return checkmarkState; + } + else + { + Color handlesColor_before = Handles.color; + + float size_withoutWeightFactorFromCapTypeApplied = GetSizeOfButtonCaps_withoutWeightFactorFromCapTypeApplied(theDrawXXLChartInspector_unserializedMonoB); + float size_withWeightFactorFromCapTypeAlreadyApplied = size_withoutWeightFactorFromCapTypeApplied * sizeScaleFactor; + float radius_ofButton = 0.5f * size_withWeightFactorFromCapTypeAlreadyApplied;//"0.5f" factor because "Handles.CircleHandleCap" as a 2D cap seems to interpret the specified size as "radius" differently form the 3D caps that interpret it as "diameter". + Handles.color = theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.color; + Vector3 normalOfSolidDisc = (-SceneView.lastActiveSceneView.camera.transform.forward); + Handles.DrawSolidDisc(position, normalOfSolidDisc, radius_ofButton); + + GUIContent displayedIcon; + Vector3 worldSpaceOffset_thatShiftsTheIconAlongScreenspaceXDir; + Vector3 worldSpaceOffset_thatShiftsTheIconAlongScreenspaceYDir; + float iconSize_asFloat_inWorldSpace; + if (checkmarkState == true) + { + worldSpaceOffset_thatShiftsTheIconAlongScreenspaceXDir = SceneView.lastActiveSceneView.camera.transform.right * size_withoutWeightFactorFromCapTypeApplied * checkmarkIconPositionOffset_inScreenspace_relToHandleCapSize.x; + worldSpaceOffset_thatShiftsTheIconAlongScreenspaceYDir = SceneView.lastActiveSceneView.camera.transform.up * size_withoutWeightFactorFromCapTypeApplied * checkmarkIconPositionOffset_inScreenspace_relToHandleCapSize.y; + displayedIcon = checkmarkSymbol; + iconSize_asFloat_inWorldSpace = size_withoutWeightFactorFromCapTypeApplied * sizeFactor_forCheckmarkIcon; + } + else + { + worldSpaceOffset_thatShiftsTheIconAlongScreenspaceXDir = SceneView.lastActiveSceneView.camera.transform.right * size_withoutWeightFactorFromCapTypeApplied * crossIconPositionOffset_inScreenspace_relToHandleCapSize.x; + worldSpaceOffset_thatShiftsTheIconAlongScreenspaceYDir = SceneView.lastActiveSceneView.camera.transform.up * size_withoutWeightFactorFromCapTypeApplied * crossIconPositionOffset_inScreenspace_relToHandleCapSize.y; + displayedIcon = crossSymbol; + iconSize_asFloat_inWorldSpace = size_withoutWeightFactorFromCapTypeApplied * sizeFactor_forCrossIcon; + } + Vector3 posOfDisplayedIcon = position + worldSpaceOffset_thatShiftsTheIconAlongScreenspaceXDir + worldSpaceOffset_thatShiftsTheIconAlongScreenspaceYDir; + Vector2 iconSize_inPixels_asVector2 = ConvertIconSize_fromWorldspaceSize_toPixelSize(iconSize_asFloat_inWorldSpace, posOfDisplayedIcon); + + Vector2 iconSize_before = EditorGUIUtility.GetIconSize(); + EditorGUIUtility.SetIconSize(iconSize_inPixels_asVector2); + Handles.Label(posOfDisplayedIcon, displayedIcon); + EditorGUIUtility.SetIconSize(iconSize_before); + + GUIStyle styleFor_showAllText = new GUIStyle(); + float textSize_asFloat_inScreenspace0to1 = UtilitiesDXXL_Screenspace.WorldSpaceExtent_to_viewportSpaceExtentRelToScreenHeight(SceneView.lastActiveSceneView.camera, position, 0.7f * size_withoutWeightFactorFromCapTypeApplied); + float textSize_inPixels = textSize_asFloat_inScreenspace0to1 * SceneView.lastActiveSceneView.camera.pixelHeight; + styleFor_showAllText.fontSize = (int)textSize_inPixels; + //styleFor_showAllText.alignment = TextAnchor.UpperCenter; //-> is this a bug in Unity? All anchors with "right" behave as it would be "left". Also "Center" is not really the center, but slightly shifted. I place the text at a manually shifted position as a fallback. + string showAll_labelText = DrawText.MarkupColor("Show all", theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.color); + Vector3 positionOfText = position - SceneView.lastActiveSceneView.camera.transform.right * 3.4f * size_withWeightFactorFromCapTypeAlreadyApplied+ SceneView.lastActiveSceneView.camera.transform.up * 0.4f * size_withWeightFactorFromCapTypeAlreadyApplied; + Handles.Label(positionOfText, showAll_labelText, styleFor_showAllText); + + Handles.color = UtilitiesDXXL_Colors.GetSimilarColorWithOtherBrightnessValue(theDrawXXLChartInspector_unserializedMonoB.chart_thisInspectorIsAttachedTo.color); + Quaternion rotation_ofButton = Quaternion.LookRotation(normalOfSolidDisc); + bool buttonHasBeenClicked = Handles.Button(position, rotation_ofButton, radius_ofButton, radius_ofButton, Handles.CircleHandleCap); + if (buttonHasBeenClicked) + { + checkmarkState = !checkmarkState; + } + + Handles.color = handlesColor_before; + + return checkmarkState; + } + } + + } + +#endif +} diff --git a/Editor/DrawDebugLibrary/Charts/line charts/internal utilities/InternalDXXL_ChartHandles.cs.meta b/Editor/DrawDebugLibrary/Charts/line charts/internal utilities/InternalDXXL_ChartHandles.cs.meta new file mode 100644 index 0000000..0a82174 --- /dev/null +++ b/Editor/DrawDebugLibrary/Charts/line charts/internal utilities/InternalDXXL_ChartHandles.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: acd864c428f8f6748ba54e9411c29224 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/CoordinateAxesGizmoVisualizerInspector.cs b/Editor/DrawDebugLibrary/CoordinateAxesGizmoVisualizerInspector.cs new file mode 100644 index 0000000..47c7587 --- /dev/null +++ b/Editor/DrawDebugLibrary/CoordinateAxesGizmoVisualizerInspector.cs @@ -0,0 +1,67 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(CoordinateAxesGizmoVisualizer))] + [CanEditMultipleObjects] + public class CoordinateAxesGizmoVisualizerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("gizmo"); + + SerializedProperty sP_visualizedSpace = serializedObject.FindProperty("visualizedSpace"); + EditorGUILayout.PropertyField(sP_visualizedSpace, new GUIContent("Visualized space")); + bool visualizedSpace_isTheGlobalSpace = sP_visualizedSpace.enumValueIndex == (int)CoordinateAxesGizmoVisualizer.VisualizedSpace.global; + bool isFallback_fromParentSpace_toGlobalSpace = false; + if (sP_visualizedSpace.enumValueIndex == (int)CoordinateAxesGizmoVisualizer.VisualizedSpace.localDefinedByParent) + { + if (transform_onVisualizerObject.parent == null) + { + EditorGUILayout.HelpBox("No parent available. Fallback to visualizing global space.", MessageType.None, true); + isFallback_fromParentSpace_toGlobalSpace = true; + } + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawXYZchars"), new GUIContent("Draw 'X', 'Y' and 'Z' chars")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("skipConeDrawing"), new GUIContent("Hide cones")); + + SerializedProperty sP_forceAllAxesLength = serializedObject.FindProperty("forceAllAxesLength"); + string label_for_forceAllAxesLength = "Force fixed axis length"; + if (visualizedSpace_isTheGlobalSpace || isFallback_fromParentSpace_toGlobalSpace) + { + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.Toggle(new GUIContent(label_for_forceAllAxesLength, "This is only available in local space."), true); + EditorGUI.EndDisabledGroup(); + } + else + { + EditorGUILayout.PropertyField(sP_forceAllAxesLength, new GUIContent(label_for_forceAllAxesLength)); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + bool lengthChooser_isGreyedOut = (visualizedSpace_isTheGlobalSpace == false) && (isFallback_fromParentSpace_toGlobalSpace == false) && (sP_forceAllAxesLength.boolValue == false); + EditorGUI.BeginDisabledGroup(lengthChooser_isGreyedOut); + EditorGUILayout.PropertyField(serializedObject.FindProperty("forceAllAxesLength_lengthValue"), new GUIContent("Forced length (global units)")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineWidth"), new GUIContent("Line width")); + + Draw_DrawPosition3DOffset(); + DrawTextInputInclMarkupHelper(); + DrawCheckboxFor_drawOnlyIfSelected("gizmo"); + DrawCheckboxFor_hiddenByNearerObjects("gizmo"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/CoordinateAxesGizmoVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/CoordinateAxesGizmoVisualizerInspector.cs.meta new file mode 100644 index 0000000..aa5b7ba --- /dev/null +++ b/Editor/DrawDebugLibrary/CoordinateAxesGizmoVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32753fd1601f35a4998ad62d08fdc489 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/CrossProductVisualizerInspector.cs b/Editor/DrawDebugLibrary/CrossProductVisualizerInspector.cs new file mode 100644 index 0000000..e20e10b --- /dev/null +++ b/Editor/DrawDebugLibrary/CrossProductVisualizerInspector.cs @@ -0,0 +1,79 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(CrossProductVisualizer))] + [CanEditMultipleObjects] + public class CrossProductVisualizerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("cross product"); + + SerializedProperty sP_colorOfVector1_forCrossProduct = serializedObject.FindProperty("colorOfVector1_forCrossProduct"); + SerializedProperty sP_colorOfVector2_forCrossProduct = serializedObject.FindProperty("colorOfVector2_forCrossProduct"); + SerializedProperty sP_colorOfResultVector_forCrossProduct = serializedObject.FindProperty("colorOfResultVector_forCrossProduct"); + + DrawSpecificationOf_customVector3_1("Input Vector 1 lhs (thumb of left hand)", false, null, false, false, true, false); + DrawSpecificationOf_customVector3_2("Input Vector 2 rhs (index finger of left hand)", false, null, false, false, true, false); + + GUIStyle style_ofResultHeadline = new GUIStyle(); + style_ofResultHeadline.richText = true; + EditorGUILayout.LabelField("Cross Product Result (middle finger of left hand)", style_ofResultHeadline); + + EditorGUI.indentLevel++; + + Vector3 vector1_lhs_leftThumb = visualizerParentMonoBehaviour_unserialized.Get_customVector3_1_inGlobalSpaceUnits(); + Vector3 vector2_rhs_leftIndexFinger = visualizerParentMonoBehaviour_unserialized.Get_customVector3_2_inGlobalSpaceUnits(); + Vector3 crossProductResult = Vector3.Cross(vector1_lhs_leftThumb, vector2_rhs_leftIndexFinger); + EditorGUILayout.Vector3Field(GUIContent.none, crossProductResult); + + EditorGUI.indentLevel--; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + DrawColorSection(sP_colorOfVector1_forCrossProduct, sP_colorOfVector2_forCrossProduct, sP_colorOfResultVector_forCrossProduct); + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesWidth"), new GUIContent("Lines width")); + + Draw_DrawPosition3DOffset(); + DrawCheckboxFor_drawOnlyIfSelected("cross product"); + DrawCheckboxFor_hiddenByNearerObjects("cross product"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawColorSection(SerializedProperty sP_colorOfVector1_forCrossProduct, SerializedProperty sP_colorOfVector2_forCrossProduct, SerializedProperty sP_colorOfResultVector_forCrossProduct) + { + SerializedProperty sP_colorSection_isOutfolded = serializedObject.FindProperty("colorSection_isOutfolded"); + sP_colorSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_colorSection_isOutfolded.boolValue, "Colors", true); + if (sP_colorSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel++; + + SerializedProperty sP_colorOfAngle_forCrossProduct = serializedObject.FindProperty("colorOfAngle_forCrossProduct"); + SerializedProperty sP_colorOfResultText_forCrossProduct = serializedObject.FindProperty("colorOfResultText_forCrossProduct"); + SerializedProperty sP_colorOfResultPlane_forCrossProduct = serializedObject.FindProperty("colorOfResultPlane_forCrossProduct"); + + EditorGUILayout.PropertyField(sP_colorOfVector1_forCrossProduct, new GUIContent("Input Vector 1 (lhs)")); + EditorGUILayout.PropertyField(sP_colorOfVector2_forCrossProduct, new GUIContent("Input Vector 2 (rhs)")); + EditorGUILayout.PropertyField(sP_colorOfResultVector_forCrossProduct, new GUIContent("Result Vector")); + EditorGUILayout.PropertyField(sP_colorOfResultText_forCrossProduct, new GUIContent("Result Text")); + EditorGUILayout.PropertyField(sP_colorOfResultPlane_forCrossProduct, new GUIContent("Result Plane")); + EditorGUILayout.PropertyField(sP_colorOfAngle_forCrossProduct, new GUIContent("Angle")); + + EditorGUI.indentLevel--; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/CrossProductVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/CrossProductVisualizerInspector.cs.meta new file mode 100644 index 0000000..9459747 --- /dev/null +++ b/Editor/DrawDebugLibrary/CrossProductVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0fded1b9a9789ca4cb83052837eb70cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/DotProductVisualizerInspector.cs b/Editor/DrawDebugLibrary/DotProductVisualizerInspector.cs new file mode 100644 index 0000000..4d11bc5 --- /dev/null +++ b/Editor/DrawDebugLibrary/DotProductVisualizerInspector.cs @@ -0,0 +1,74 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(DotProductVisualizer))] + [CanEditMultipleObjects] + public class DotProductVisualizerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("dot product"); + + SerializedProperty sP_colorOfVector1_forDotProduct = serializedObject.FindProperty("colorOfVector1_forDotProduct"); + SerializedProperty sP_colorOfVector2_forDotProduct = serializedObject.FindProperty("colorOfVector2_forDotProduct"); + + DrawSpecificationOf_customVector3_1("Input Vector 1 lhs", false, null, false, false, true, false); + DrawSpecificationOf_customVector3_2("Input Vector 2 rhs", false, null, false, false, true, false); + + GUIStyle style_ofResultHeadline = new GUIStyle(); + style_ofResultHeadline.fontStyle = FontStyle.Bold; + EditorGUILayout.LabelField("Dot Product Result", style_ofResultHeadline); + + EditorGUI.indentLevel++; + + Vector3 vector1_lhs = visualizerParentMonoBehaviour_unserialized.Get_customVector3_1_inGlobalSpaceUnits(); + Vector3 vector2_rhs = visualizerParentMonoBehaviour_unserialized.Get_customVector3_2_inGlobalSpaceUnits(); + float dotProductResult = Vector3.Dot(vector1_lhs, vector2_rhs); + EditorGUILayout.FloatField(dotProductResult); + + EditorGUI.indentLevel--; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + DrawColorSection(sP_colorOfVector1_forDotProduct, sP_colorOfVector2_forDotProduct); + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesWidth"), new GUIContent("Lines width")); + + Draw_DrawPosition3DOffset(); + DrawCheckboxFor_drawOnlyIfSelected("dot product"); + DrawCheckboxFor_hiddenByNearerObjects("dot product"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawColorSection(SerializedProperty sP_colorOfVector1_forDotProduct, SerializedProperty sP_colorOfVector2_forDotProduct) + { + SerializedProperty sP_colorSection_isOutfolded = serializedObject.FindProperty("colorSection_isOutfolded"); + sP_colorSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_colorSection_isOutfolded.boolValue, "Colors", true); + if (sP_colorSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel++; + + SerializedProperty sP_colorOfAngle_forDotProduct = serializedObject.FindProperty("colorOfAngle_forDotProduct"); + SerializedProperty sP_colorOfResult_forDotProduct = serializedObject.FindProperty("colorOfResult_forDotProduct"); + + EditorGUILayout.PropertyField(sP_colorOfVector1_forDotProduct, new GUIContent("Input Vector 1 (lhs)")); + EditorGUILayout.PropertyField(sP_colorOfVector2_forDotProduct, new GUIContent("Input Vector 2 (rhs)")); + EditorGUILayout.PropertyField(sP_colorOfResult_forDotProduct, new GUIContent("Result Text")); + EditorGUILayout.PropertyField(sP_colorOfAngle_forDotProduct, new GUIContent("Angle")); + + EditorGUI.indentLevel--; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/DotProductVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/DotProductVisualizerInspector.cs.meta new file mode 100644 index 0000000..f57613f --- /dev/null +++ b/Editor/DrawDebugLibrary/DotProductVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f42cc1005d171c459996aa0f929ec3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/DrawXXLSpline2DConnectionInspector.cs b/Editor/DrawDebugLibrary/DrawXXLSpline2DConnectionInspector.cs new file mode 100644 index 0000000..d4e8704 --- /dev/null +++ b/Editor/DrawDebugLibrary/DrawXXLSpline2DConnectionInspector.cs @@ -0,0 +1,34 @@ +namespace DrawXXL +{ + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(DrawXXLSpline2DConnection))] + public class DrawXXLSpline2DConnectionInspector : Editor + { + DrawXXLSpline2DConnection drawXXLSplineConnection_unserializedMonoB; + + void OnEnable() + { + drawXXLSplineConnection_unserializedMonoB = (DrawXXLSpline2DConnection)target; + } + + public override void OnInspectorGUI() + { + string helpBoxString; + if ((drawXXLSplineConnection_unserializedMonoB != null) && (drawXXLSplineConnection_unserializedMonoB.bezierSplineDrawer_thatHasReferencedThisGameobject != null)) + { + helpBoxString = "This component handles the connection of this gameobject to the 2D-spline at " + drawXXLSplineConnection_unserializedMonoB.bezierSplineDrawer_thatHasReferencedThisGameobject.gameObject.name + ", specifically to the " + InternalDXXL_BezierControlSubPoint.GetSubPointTypeAsString(drawXXLSplineConnection_unserializedMonoB.subPointType_whereThisGameobjectIsBoundTo) + " of control point " + drawXXLSplineConnection_unserializedMonoB.i_ofControlPointTriplet_thisGameobjectIsBoundTo + " there." + Environment.NewLine + "It was automatically created and will get automatically deleted if it is not used anymore." + Environment.NewLine + "You can end the assignment in the spline inspector or simply by deleting this component."; + } + else + { + helpBoxString = "This component handles the connection of this gameobject to a 2D-spline, but it seems that the spline reference got lost."; + } + EditorGUILayout.HelpBox(helpBoxString, MessageType.Info, true); + } + } +#endif + +} \ No newline at end of file diff --git a/Editor/DrawDebugLibrary/DrawXXLSpline2DConnectionInspector.cs.meta b/Editor/DrawDebugLibrary/DrawXXLSpline2DConnectionInspector.cs.meta new file mode 100644 index 0000000..16a384c --- /dev/null +++ b/Editor/DrawDebugLibrary/DrawXXLSpline2DConnectionInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 401001f9fd33e2848bd96d4260d9c31b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/DrawXXLSplineConnectionInspector.cs b/Editor/DrawDebugLibrary/DrawXXLSplineConnectionInspector.cs new file mode 100644 index 0000000..b005c30 --- /dev/null +++ b/Editor/DrawDebugLibrary/DrawXXLSplineConnectionInspector.cs @@ -0,0 +1,34 @@ +namespace DrawXXL +{ + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(DrawXXLSplineConnection))] + public class DrawXXLSplineConnectionInspector : Editor + { + DrawXXLSplineConnection drawXXLSplineConnection_unserializedMonoB; + + void OnEnable() + { + drawXXLSplineConnection_unserializedMonoB = (DrawXXLSplineConnection)target; + } + + public override void OnInspectorGUI() + { + string helpBoxString; + if ((drawXXLSplineConnection_unserializedMonoB != null) && (drawXXLSplineConnection_unserializedMonoB.bezierSplineDrawer_thatHasReferencedThisGameobject != null)) + { + helpBoxString = "This component handles the connection of this gameobject to the spline at " + drawXXLSplineConnection_unserializedMonoB.bezierSplineDrawer_thatHasReferencedThisGameobject.gameObject.name + ", specifically to the " + InternalDXXL_BezierControlSubPoint.GetSubPointTypeAsString(drawXXLSplineConnection_unserializedMonoB.subPointType_whereThisGameobjectIsBoundTo) + " of control point " + drawXXLSplineConnection_unserializedMonoB.i_ofControlPointTriplet_thisGameobjectIsBoundTo + " there." + Environment.NewLine + "It was automatically created and will get automatically deleted if it is not used anymore." + Environment.NewLine + "You can end the assignment in the spline inspector or simply by deleting this component."; + } + else + { + helpBoxString = "This component handles the connection of this gameobject to a spline, but it seems that the spline reference got lost."; + } + EditorGUILayout.HelpBox(helpBoxString, MessageType.Info, true); + } + } +#endif + +} \ No newline at end of file diff --git a/Editor/DrawDebugLibrary/DrawXXLSplineConnectionInspector.cs.meta b/Editor/DrawDebugLibrary/DrawXXLSplineConnectionInspector.cs.meta new file mode 100644 index 0000000..1913ae1 --- /dev/null +++ b/Editor/DrawDebugLibrary/DrawXXLSplineConnectionInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 901b6c442d03f8549a094a8cd268a0c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/DrawXXL_LinesManagerInspector.cs b/Editor/DrawDebugLibrary/DrawXXL_LinesManagerInspector.cs new file mode 100644 index 0000000..4601d6d --- /dev/null +++ b/Editor/DrawDebugLibrary/DrawXXL_LinesManagerInspector.cs @@ -0,0 +1,27 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(DrawXXL_LinesManager))] + public class DrawXXL_LinesManagerInspector : Editor + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + EditorGUILayout.HelpBox("The checkbox below has this effect:" + Environment.NewLine + Environment.NewLine + "Outside of Playmode the Scene View window and Game View window do not ongoingly refresh themselfes as they do in playmode. Instead they just repaint on certain occasions, e.g. when a gameobject with a mesh is moved. When drawing in Edit mode from code this creates the problem that what you see on screen in the Scene or Game View doesn't neccessarily represent what you are currently drawing from code. For example if you draw a 'BoolDisplayer' to debug a changing bool value the display on screen may be wrong and still display an old value." + Environment.NewLine + "The Gizmo Line Count Manager Component here can fix this and let the display always show the most current value by continuously repainting the Scene and Game view. The downside of this fix is that it costs performance. Disabling it may make sense if you know that the things you are drawing anyway only change if a visible object in the Scene changes, e.g. when the player model changes its position or rotation." + Environment.NewLine + Environment.NewLine + "A disabled checkbox here may have no effect if other components are already continuously repainting the windows, like 'Draw XXL Chart Inspector' or 'Line Drawer' (with animated lines).", MessageType.None, true); + + SerializedProperty sP_gizmoLineCountManagerAutomaticallyRepaintsRendering = serializedObject.FindProperty("gizmoLineCountManagerAutomaticallyRepaintsRendering"); + sP_gizmoLineCountManagerAutomaticallyRepaintsRendering.boolValue = EditorGUILayout.ToggleLeft(new GUIContent("Continuous Repaint in Edit Mode"), sP_gizmoLineCountManagerAutomaticallyRepaintsRendering.boolValue); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/DrawXXL_LinesManagerInspector.cs.meta b/Editor/DrawDebugLibrary/DrawXXL_LinesManagerInspector.cs.meta new file mode 100644 index 0000000..e874ca3 --- /dev/null +++ b/Editor/DrawDebugLibrary/DrawXXL_LinesManagerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3394f803bdab16d4686e5575563401c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/GridVisualizerInspector.cs b/Editor/DrawDebugLibrary/GridVisualizerInspector.cs new file mode 100644 index 0000000..b77e698 --- /dev/null +++ b/Editor/DrawDebugLibrary/GridVisualizerInspector.cs @@ -0,0 +1,243 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(GridVisualizer))] + [CanEditMultipleObjects] + public class GridVisualizerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("grid"); + + SerializedProperty sP_spaceType = serializedObject.FindProperty("spaceType"); + EditorGUILayout.PropertyField(sP_spaceType, new GUIContent("Visualized space")); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + SerializedProperty sP_xGridType = serializedObject.FindProperty("xGridType"); + SerializedProperty sP_yGridType = serializedObject.FindProperty("yGridType"); + SerializedProperty sP_zGridType = serializedObject.FindProperty("zGridType"); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_xGridType, new GUIContent("X")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForX"), GUIContent.none); + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_yGridType, new GUIContent("Y")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForY"), GUIContent.none); + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_zGridType, new GUIContent("Z")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForZ"), GUIContent.none); + EditorGUILayout.EndHorizontal(); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + GUIStyle style_forFoldoutLine = new GUIStyle(EditorStyles.foldout); + style_forFoldoutLine.fontStyle = FontStyle.Bold; + + GUIStyle style_ofHeadlines = new GUIStyle(); + style_ofHeadlines.fontStyle = FontStyle.Bold; + + DrawOrdersOfMagnitudeSection(style_forFoldoutLine); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + bool noDimensionIsDisplayed_asPlane = ((sP_xGridType.enumValueIndex != (int)GridVisualizer.XGridType.planes) && (sP_yGridType.enumValueIndex != (int)GridVisualizer.YGridType.planes) && (sP_zGridType.enumValueIndex != (int)GridVisualizer.ZGridType.planes)); + bool planesSection_isDisabled = noDimensionIsDisplayed_asPlane; + EditorGUI.BeginDisabledGroup(planesSection_isDisabled); + EditorGUILayout.LabelField(planesSection_isDisabled ? "Planes details (no planes are activated, see above at X, Y and Z)" : "Planes details", style_ofHeadlines); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_coveredGridUnits_rel_forGridPlanes = serializedObject.FindProperty("coveredGridUnits_rel_forGridPlanes"); + sP_coveredGridUnits_rel_forGridPlanes.floatValue = EditorGUILayout.FloatField(new GUIContent("Covered grid units", "This is relative to the biggest drawn order of magnitude." + Environment.NewLine + Environment.NewLine + "The minimum value is 2.5"), sP_coveredGridUnits_rel_forGridPlanes.floatValue); + sP_coveredGridUnits_rel_forGridPlanes.floatValue = Mathf.Max(sP_coveredGridUnits_rel_forGridPlanes.floatValue, 2.5f); + + SerializedProperty sP_extentOfEachGridPlane_rel = serializedObject.FindProperty("extentOfEachGridPlane_rel"); + EditorGUILayout.PropertyField(sP_extentOfEachGridPlane_rel, new GUIContent("Size", "This is relative to the smallest drawn order of magnitude." + Environment.NewLine + Environment.NewLine + "The minimum value is 0.1")); + sP_extentOfEachGridPlane_rel.floatValue = Mathf.Max(sP_extentOfEachGridPlane_rel.floatValue, 0.1f); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawDensity"), new GUIContent("Density")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + EditorGUI.EndDisabledGroup(); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + bool noDimensionIsDisplayed_asLine = ((sP_xGridType.enumValueIndex != (int)GridVisualizer.XGridType.linesAlongY) && (sP_xGridType.enumValueIndex != (int)GridVisualizer.XGridType.linesAlongZ) && (sP_yGridType.enumValueIndex != (int)GridVisualizer.YGridType.linesAlongX) && (sP_yGridType.enumValueIndex != (int)GridVisualizer.YGridType.linesAlongZ) && (sP_zGridType.enumValueIndex != (int)GridVisualizer.ZGridType.linesAlongX) && (sP_zGridType.enumValueIndex != (int)GridVisualizer.ZGridType.linesAlongY)); + EditorGUI.BeginDisabledGroup(noDimensionIsDisplayed_asLine); + EditorGUILayout.LabelField(noDimensionIsDisplayed_asLine ? "Lines details (no lines are activated, see above at X, Y and Z)" : "Lines details", style_ofHeadlines); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_coveredGridUnits_rel = serializedObject.FindProperty("coveredGridUnits_rel"); + EditorGUILayout.PropertyField(sP_coveredGridUnits_rel, new GUIContent("Covered grid units", "This is relative to the biggest drawn order of magnitude." + Environment.NewLine + Environment.NewLine + "The minimum value is 2.5")); + sP_coveredGridUnits_rel.floatValue = Mathf.Max(sP_coveredGridUnits_rel.floatValue, 2.5f); + + SerializedProperty sP_lengthOfEachGridLine_rel = serializedObject.FindProperty("lengthOfEachGridLine_rel"); + EditorGUILayout.PropertyField(sP_lengthOfEachGridLine_rel, new GUIContent("Length", "This is relative to the smallest drawn order of magnitude." + Environment.NewLine + Environment.NewLine + "The minimum value is 0.1")); + sP_lengthOfEachGridLine_rel.floatValue = Mathf.Max(sP_lengthOfEachGridLine_rel.floatValue, 0.1f); + + DrawLineWidth(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + EditorGUI.EndDisabledGroup(); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + DrawCoordinateDisplaySection(sP_spaceType); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("show_positionAroundWhichToDraw_forGrids"), new GUIContent("Visualize Position")); + + SerializedProperty sP_show_distanceDisplay_forGrids = serializedObject.FindProperty("show_distanceDisplay_forGrids"); + EditorGUILayout.PropertyField(sP_show_distanceDisplay_forGrids, new GUIContent("Visualize Distance of Position to Grid")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUI.BeginDisabledGroup(!sP_show_distanceDisplay_forGrids.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("offsetForDistanceDisplays_inGrids"), new GUIContent("Offset for Distance Display")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + Draw_DrawPosition3DOffset(); + DrawCheckboxFor_drawOnlyIfSelected("grid"); + DrawCheckboxFor_hiddenByNearerObjects("grid"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawOrdersOfMagnitudeSection(GUIStyle style_forFoldoutLine) + { + SerializedProperty sP_magnitudeOrderSection_isOutfolded = serializedObject.FindProperty("magnitudeOrderSection_isOutfolded"); + sP_magnitudeOrderSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_magnitudeOrderSection_isOutfolded.boolValue, "Drawn orders of magnitude", true, style_forFoldoutLine); + if (sP_magnitudeOrderSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("draw1000grid"), new GUIContent("1000")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("draw100grid"), new GUIContent("100")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("draw10grid"), new GUIContent("10")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("draw1grid"), new GUIContent("1")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("draw0p1grid"), new GUIContent("0.1")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("draw0p01grid"), new GUIContent("0.01")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("draw0p001grid"), new GUIContent("0.001")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawLineWidth() + { + SerializedProperty sP_lineWidthMode = serializedObject.FindProperty("lineWidthMode"); + SerializedProperty sP_linesWidth_alongVisualizedAxis = serializedObject.FindProperty("linesWidth_alongVisualizedAxis"); + SerializedProperty sP_linesWidth_perpendicularToVisualizedAxis = serializedObject.FindProperty("linesWidth_perpendicularToVisualizedAxis"); + + EditorGUILayout.PropertyField(sP_lineWidthMode, new GUIContent("Line width direction")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + if (sP_lineWidthMode.enumValueIndex == (int)GridVisualizer.LineWidthMode.growAlongVisualizedAxis) + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(sP_linesWidth_alongVisualizedAxis, new GUIContent("Line width", "This is relative to the concerned order of magnitude.")); + bool hasChanged = EditorGUI.EndChangeCheck(); + + if (hasChanged) + { + sP_linesWidth_perpendicularToVisualizedAxis.floatValue = sP_linesWidth_alongVisualizedAxis.floatValue; + } + } + else + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(sP_linesWidth_perpendicularToVisualizedAxis, new GUIContent("Line width", "This is relative to the concerned order of magnitude.")); + sP_linesWidth_perpendicularToVisualizedAxis.floatValue = Mathf.Max(sP_linesWidth_perpendicularToVisualizedAxis.floatValue, 0.0f); + bool hasChanged = EditorGUI.EndChangeCheck(); + + if (hasChanged) + { + sP_linesWidth_alongVisualizedAxis.floatValue = sP_linesWidth_perpendicularToVisualizedAxis.floatValue; + sP_linesWidth_alongVisualizedAxis.floatValue = Mathf.Min(sP_linesWidth_alongVisualizedAxis.floatValue, GridVisualizer.max_linesWidth_alongVisualizedAxis); + } + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawCoordinateDisplaySection(SerializedProperty sP_spaceType) + { + SerializedProperty sP_repeatingCoordsTextVariant = serializedObject.FindProperty("repeatingCoordsTextVariant"); + EditorGUILayout.PropertyField(sP_repeatingCoordsTextVariant, new GUIContent("Coordiantes Display")); + + switch (sP_repeatingCoordsTextVariant.enumValueIndex) + { + case (int)GridVisualizer.RepeatingCoordsTextVariant.repeatAfterDistance: + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_distanceBetweenRepeatingCoordsTexts_relToGridDistance = serializedObject.FindProperty("distanceBetweenRepeatingCoordsTexts_relToGridDistance"); + EditorGUILayout.PropertyField(sP_distanceBetweenRepeatingCoordsTexts_relToGridDistance, new GUIContent("Text distance between repeating coordinates", "This is relative to the grid distance." + Environment.NewLine + "The minimum value is 5." + Environment.NewLine + "You may see changes only if the length/extent of the lines/planes is long enough.")); + sP_distanceBetweenRepeatingCoordsTexts_relToGridDistance.floatValue = Mathf.Max(sP_distanceBetweenRepeatingCoordsTexts_relToGridDistance.floatValue, UtilitiesDXXL_Grid.min_distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawSharedFieldsOfNonDisabledCoordinateTextModes( sP_spaceType); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + case (int)GridVisualizer.RepeatingCoordsTextVariant.displayOnlyOnce: + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + DrawSharedFieldsOfNonDisabledCoordinateTextModes( sP_spaceType); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + break; + case (int)GridVisualizer.RepeatingCoordsTextVariant.noDisplay: + break; + default: + break; + } + } + + void DrawSharedFieldsOfNonDisabledCoordinateTextModes(SerializedProperty sP_spaceType) + { + GUIContent coordinateTextOffset_GUIContent = new GUIContent("Text Position", "This is relative to the containing order of magnitude."); + EditorGUILayout.PropertyField(serializedObject.FindProperty("offsetForCoordinateTextDisplays_inGrids"), coordinateTextOffset_GUIContent); + + GUIContent textSize_GUIContent = new GUIContent("Text Size", "This is relative to the containing order of magnitude."); + EditorGUILayout.PropertyField(serializedObject.FindProperty("sizeScalingForCoordinateTexts_inGrids"), textSize_GUIContent); + + GUIContent skipXYZAxisIdentifier_GUIContent = new GUIContent("Skip 'X/Y/Z =' prefix", "This can save performance for large grid displays." + Environment.NewLine + Environment.NewLine + "The initial value of created components for this can be defined via 'DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes'."); + EditorGUILayout.PropertyField(serializedObject.FindProperty("skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes"), skipXYZAxisIdentifier_GUIContent); + + if (GridDisplaysALocalSpace(sP_spaceType)) + { + GUIContent skipLocalPrefix_GUIContent = new GUIContent("Skip 'local' prefix", "This can save performance for large grid displays." + Environment.NewLine + Environment.NewLine + "The initial value of created components for this can be defined via 'DrawEngineBasics.skipLocalPrefix_inCoordinateTextsOnGridAxes'."); + EditorGUILayout.PropertyField(serializedObject.FindProperty("skipLocalPrefix_inCoordinateTextsOnGridAxes"), skipLocalPrefix_GUIContent); + } + } + + bool GridDisplaysALocalSpace(SerializedProperty sP_spaceType) + { + switch (sP_spaceType.enumValueIndex) + { + case (int)GridVisualizer.SpaceType.global: + return false; + case (int)GridVisualizer.SpaceType.localDefinedByParent: + return true; + case (int)GridVisualizer.SpaceType.localDefinedByThisGameobject: + return true; + default: + return false; + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/GridVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/GridVisualizerInspector.cs.meta new file mode 100644 index 0000000..b6e2b0a --- /dev/null +++ b/Editor/DrawDebugLibrary/GridVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82494d6c58341c1489793e19c128e441 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/HandlesExamples.cs b/Editor/DrawDebugLibrary/HandlesExamples.cs new file mode 100644 index 0000000..a79937d --- /dev/null +++ b/Editor/DrawDebugLibrary/HandlesExamples.cs @@ -0,0 +1,773 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; +#endif + + public class HandlesExamples + { +#if UNITY_EDITOR + //use Draw XXL draw operations only from inside "OnSceneGUI()" after you have set "DrawBasics.usedUnityLineDrawingMethod" to "handlesLines" (as it happens in "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()"). + //-> This also ensures that the function calls will be automatically stripped from the code when building, which prevents build errors, since the functions inside this HandlesExamples-class are not present outside of the Editor. + + //Analyzing the code in this class probably only be useful for you if you are already familiar with using custom Handles/Unitys Handles class. If not, this blog post provides good insights on the way of thinking behind it: https://blog.unity.com/technology/going-deep-with-imgui-and-editor-customization + + static DrawBasics.UsedUnityLineDrawingMethod usedLineDrawingMethod_before; + static DrawText.AutomaticTextOrientation automaticTextOrientation_before; + static DrawBasics.CameraForAutomaticOrientation cameraForAutomaticOrientation_before; + static DrawShapes.AutomaticOrientationOfFlatShapes automaticOrientationOfFlatShapes_before; + public static void ConfigureDrawXXLsGlobalSettingsForDrawingHandles() + { + //-> "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()" is setting some global Draw XXL settings so that drawing with Handles can be done with less thinking. The affected settings are "DrawBasics.usedLineDrawingMethod", "DrawText.automaticTextOrientation" and "DrawBasics.cameraForAutomaticOrientation". Moreover the settings as they were before get saved, so they can be easily restored afterwards by "RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore()". This ensures that these settings don't interfere with other code that draws with Draw XXL, e.g. from within "Update()". + //-> This function is recommended to be used in conjunction with the "RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore()" function, to "encapsulate" everything that Draw XXL draws for Handles. + //-> When drawing with Draw XXL inside "OnSceneGUI()" the recommended pattern is to call "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()", then use the Draw XXL drawing functions to draw whatever you like, and then calling "RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore()" + + //Saving the settings as the were before: + usedLineDrawingMethod_before = DrawBasics.usedUnityLineDrawingMethod; + automaticTextOrientation_before = DrawText.automaticTextOrientation; + cameraForAutomaticOrientation_before = DrawBasics.cameraForAutomaticOrientation; + automaticOrientationOfFlatShapes_before = DrawShapes.automaticOrientationOfFlatShapes; + + //Instructing Draw XXL which configuration to use for the current Handle drawing: + DrawBasics.usedUnityLineDrawingMethod = DrawBasics.UsedUnityLineDrawingMethod.handlesLines; //-> this cannot interfere with the automatic fallback of "usedUnityLineDrawingMethod" to "mesh" in builds, since the whole "HandlesExamples" class is stripped in builds. + DrawText.automaticTextOrientation = DrawText.AutomaticTextOrientation.screen; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + DrawShapes.automaticOrientationOfFlatShapes = DrawShapes.AutomaticOrientationOfFlatShapes.screen; + + } + + public static void RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore() + { + //-> This funciton reverts the global Draw XXL settings which "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()" has adjusted to what they were before. + //-> This function should only be used in conjunction with the "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()" function, to "encapsulate" everything that Draw XXL draws for Handles. + //-> When drawing with Draw XXL inside "OnSceneGUI()" the recommended pattern is to call "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()", then use the Draw XXL drawing functions to draw whatever you like, and then calling "RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore()" + + //Reverting the global configuration values that have been set before by "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()": + DrawBasics.usedUnityLineDrawingMethod = usedLineDrawingMethod_before; //-> this cannot interfere with the automatic fallback of "usedUnityLineDrawingMethod" to "wireMesh" in builds, since the whole "HandlesExamples" class is stripped in builds. + DrawText.automaticTextOrientation = automaticTextOrientation_before; + DrawBasics.cameraForAutomaticOrientation = cameraForAutomaticOrientation_before; + DrawShapes.automaticOrientationOfFlatShapes = automaticOrientationOfFlatShapes_before; + } + + public static void DrawLine(Vector3 start, Vector3 end, float thickness = 0.0f, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, string text = null) + { + //This funcion is like "Handles.DrawLine()" but with two additinal optional parameters that can change the style of the line and add a text along the line. + if (Event.current.type == EventType.Repaint) //-> Draw with Draw XXL only inside the "Repaint"-event, otherwise the "DrawBasics.MaxAllowedDrawnLinesPerFrame"-mechanic will get confused and restricts the drawing earlier than neccessary. + { + Vector3 theMiddleOfTheLine = 0.5f * (start + end); + float screenSizeThatAHandleWouldHaveAtTheLine = HandleUtility.GetHandleSize(theMiddleOfTheLine); + float stylePatternScaleFactor = 5.0f * screenSizeThatAHandleWouldHaveAtTheLine; //-> this lets the line style pattern appear approximately constant in screenspace, no matter how far the line is away from the camera, which may be desired if the line is part of a handle whose size is constant in screenspace. + float width_worldSpace = 0.01f * thickness * screenSizeThatAHandleWouldHaveAtTheLine; //-> converting the width to be constant in screenspace, though here in somehow arbitrary units. + Color color = Handles.color; //-> When Draw XXL draws with Unitys Handles-Lines it doesn't automatically detect the "Handles.color", but instead takes the color that is specified as parameter argument in the draw function, or else falls back to "DrawBasics.defaultColor" + + ConfigureDrawXXLsGlobalSettingsForDrawingHandles(); //-> This function is recommended to be used in conjunction with the "RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore()" function, to "encapsulate" everything that Draw XXL draws for Handles. + DrawBasics.Line(start, end, color, width_worldSpace, text, style, stylePatternScaleFactor); + RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore(); //-> This function should be used in conjunction with the "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()" function, to "encapsulate" everything that Draw XXL draws for Handles. + } + } + + static Vector3 sliderPosition_duringMouseDown; + public static Vector3 SliderWithOffsetDisplay(Vector3 position, Vector3 direction) + { + return SliderWithOffsetDisplay(position, direction, HandleUtility.GetHandleSize(position), Handles.ArrowHandleCap, -1.0f); + } + + public static Vector3 SliderWithOffsetDisplay(Vector3 position, Vector3 direction, float size, Handles.CapFunction capFunction, float snap) + { + //this is like Unitys "Handles.Slider" function, but additionally the dragged offset value is displayed together with a green or red arrow that indicates if the value change is positive or negative + //Sidenote: As can be seen in Unitys Editor source code (link zu https://github.com/Unity-Technologies/UnityCsReference/blob/2022.2/Editor/Mono/Handles.cs ) starting with Unity2022.2 Unitys "Handles" class has an additional overload for the "PositionHandle()" function, that takes the "PositionHandleIds ids"-parameter. This opens the possibility to extend this "SliderWithOffsetDisplay()" function to the whole position handle with all of it's three axes, without having to recreate the whole position handle by yourself. + + Event currentEvent = Event.current; + + if (currentEvent.type == EventType.MouseDown) //-> Detect the "MouseDown"-event BEFORE it gets eaten via "event.Use()" inside "Handles.Slider()". It will not be there anymore if this code is placed BELOW the "Handles.Slider" function call. + { + sliderPosition_duringMouseDown = position; + } + + int controlID = GUIUtility.GetControlID(FocusType.Passive); + Vector3 returnedPositionFromUnitysBuildInSlider = Handles.Slider(controlID, position, direction, size, capFunction, snap); + + if (currentEvent.type == EventType.Repaint) //-> Draw with Draw XXL only inside the "Repaint"-event, otherwise the "DrawBasics.MaxAllowedDrawnLinesPerFrame"-mechanic will get confused and restricts the drawing earlier than neccessary. + { + bool sliderIsCurrentlyGrabbedByTheMouse = (GUIUtility.hotControl == controlID); + if (sliderIsCurrentlyGrabbedByTheMouse) + { + ConfigureDrawXXLsGlobalSettingsForDrawingHandles(); //-> This function is recommended to be used in conjunction with the "RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore()" function, to "encapsulate" everything that Draw XXL draws for Handles. + DrawOffsetValueAsText_viaDrawXXL(returnedPositionFromUnitysBuildInSlider, direction, size, capFunction); + RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore(); //-> This function should be used in conjunction with the "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()" function, to "encapsulate" everything that Draw XXL draws for Handles. + } + } + + return returnedPositionFromUnitysBuildInSlider; + } + + static void DrawOffsetValueAsText_viaDrawXXL(Vector3 currentPositionOfSlider, Vector3 direction, float size, Handles.CapFunction capFunction) + { + string displayedText = GetDisplayedText(currentPositionOfSlider, direction, capFunction); + Vector3 textPosition; + DrawText.TextAnchorDXXL textAnchor; + if (capFunction == Handles.ArrowHandleCap) //-> this is the default handle cap if none is specified + { + textPosition = currentPositionOfSlider + direction.normalized * (1.2f * size); + textAnchor = Direction_goesFromLeftToRight_insideSceneViewScreen(direction) ? DrawText.TextAnchorDXXL.MiddleLeft : DrawText.TextAnchorDXXL.MiddleRight; + } + else + { + textPosition = currentPositionOfSlider; + textAnchor = DrawText.TextAnchorDXXL.LowerLeft; + } + + Color textColor = Handles.selectedColor; //-> When Draw XXL draws with Unitys Handles-Lines it doesn't automatically detect the "Handles.color", but instead takes the color that is specified as parameter argument in the draw function, or else falls back to "DrawBasics.defaultColor" + float textSize = 0.2f * size; + Vector3 textDirection = Direction_goesFromLeftToRight_insideSceneViewScreen(direction) ? direction : (-direction); + bool autoFlipTheTextToPreventMirrorInvertedDisplay = true; + UtilitiesDXXL_Text.WriteFramed(displayedText, textPosition, textColor, textSize, textDirection, default(Vector3), textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipTheTextToPreventMirrorInvertedDisplay, 0.0f, true); + } + + static string GetDisplayedText(Vector3 currentPositionOfSlider, Vector3 direction, Handles.CapFunction capFunction) + { + string displayedText; + + float absoluteDraggedDistancesSinceMouseDown = (sliderPosition_duringMouseDown - currentPositionOfSlider).magnitude; + if (currentPositionOfSlider == sliderPosition_duringMouseDown) + { + displayedText = "" + absoluteDraggedDistancesSinceMouseDown; + } + else + { + Vector3 initialPosition_to_currentPosition = currentPositionOfSlider - sliderPosition_duringMouseDown; + bool valueChangeIsPositive = Vector3.Dot(initialPosition_to_currentPosition, direction) >= 0.0f; + string stringThatWillAppearAsGreenOrRedArrowInTheFinalTextDisplay = DrawText.MarkupBoolArrow(valueChangeIsPositive); + displayedText = stringThatWillAppearAsGreenOrRedArrowInTheFinalTextDisplay + absoluteDraggedDistancesSinceMouseDown; + } + + if (capFunction != Handles.ArrowHandleCap) + { + string emptySpaceBetweenTextAndHandleCap = DrawText.MarkupCustomHeightEmptyLine(2); //-> shifting the text away from the handle cap, so they don't occlude each other + displayedText = displayedText + emptySpaceBetweenTextAndHandleCap; + } + + return displayedText; + } + + static Vector2 mousePositionInScreenspace_duringMouseDown; + static Vector2 current_mousePositionInScreenspace; + static float relativeSizeOfPercentageSliderCap = 0.2f; + static float valueToSlide_duringMouseDown; + + public static float PercentageSlider(float valueToSlide, float valueThatDefines100percent, Vector3 position, Vector3 direction) + { + return PercentageSlider(valueToSlide, valueThatDefines100percent, position, direction, HandleUtility.GetHandleSize(position), Handles.CylinderHandleCap, -1.0f); + } + + public static float PercentageSlider(float valueToSlide, float valueThatDefines100percent, Vector3 position, Vector3 direction, DrawBasics.IconType icon) + { + return PercentageSlider(valueToSlide, valueThatDefines100percent, position, direction, HandleUtility.GetHandleSize(position), Handles.CylinderHandleCap, -1.0f, icon); + } + + public static float PercentageSlider(float valueToSlide, float valueThatDefines100percent, Vector3 position, Vector3 direction, string text) + { + return PercentageSlider(valueToSlide, valueThatDefines100percent, position, direction, HandleUtility.GetHandleSize(position), Handles.CylinderHandleCap, -1.0f, text); + } + + public static float PercentageSlider(float valueToSlide, float valueThatDefines100percent, Vector3 position, Vector3 direction, float size, Handles.CapFunction capFunction, float snap, DrawBasics.IconType icon) + { + float iconSizeScaleFactor = 5.0f; + int boldStrokeWidth_asPPMofSize = 25000; + string textThatConsistsOfOnlyOneLetterWhichIsTheIconItself = DrawText.MarkupIcon(icon); + string textThatConsistsOfOnlyOneLetterWhichIsTheIconItself_withBolderFont = DrawText.MarkupStrokeWidth(textThatConsistsOfOnlyOneLetterWhichIsTheIconItself, boldStrokeWidth_asPPMofSize); + string textThatConsistsOfOnlyOneLetterWhichIsTheIconItself_withBolderFont_andScaledBigger = DrawText.MarkupSize(textThatConsistsOfOnlyOneLetterWhichIsTheIconItself_withBolderFont, iconSizeScaleFactor); + return PercentageSlider(valueToSlide, valueThatDefines100percent, position, direction, size, capFunction, snap, textThatConsistsOfOnlyOneLetterWhichIsTheIconItself_withBolderFont_andScaledBigger); + } + + public static float PercentageSlider(float valueToSlide, float valueThatDefines100percent, Vector3 position, Vector3 direction, float size, Handles.CapFunction capFunction, float snap, string text = null) + { + //This is similar to Unitys "Handles.ScaleSlider" function, but the handle doesn't snap back after the mouse drag ended and it adds a percentage value display. Moreover an optional text can be added. + + if (Mathf.Approximately(valueThatDefines100percent, 0.0f)) + { + Debug.LogError("Cannot display 'PercentageSlider' if 'valueThatDefines100percent' is 0."); + return valueToSlide; + } + + Event currentEvent = Event.current; + + if (currentEvent.type == EventType.MouseDown) //-> Detect the "MouseDown"-event BEFORE it gets eaten via "event.Use()" inside "Handles.Slider()". It will not be there anymore if this code is placed BELOW the "Handles.Slider" function call. + { + valueToSlide_duringMouseDown = valueToSlide; + valueToSlide_duringMouseDown = ForceAwayFromZero(valueToSlide_duringMouseDown, valueThatDefines100percent); //-> Preventing slider deadlock at "valueToSlide == 0" + mousePositionInScreenspace_duringMouseDown = currentEvent.mousePosition; + current_mousePositionInScreenspace = currentEvent.mousePosition; + } + + float valueToSlide_asPercentageFrom0to1 = valueToSlide / valueThatDefines100percent; + float magnifiedSize = 1.5f * size; //-> Displaying the percentage slider bigger than Unitys default display of Handles + Vector3 direction_normalized = direction.normalized; + Vector3 currentOffsetOfHandleCap = direction_normalized * magnifiedSize * valueToSlide_asPercentageFrom0to1; + Vector3 positionOfHandleCap = position + currentOffsetOfHandleCap; + float sizeOfHandleCap = relativeSizeOfPercentageSliderCap * size; + + int controlID = GUIUtility.GetControlID(FocusType.Passive); + bool sliderIsCurrentlyGrabbedByTheMouse = (GUIUtility.hotControl == controlID); + + DrawPercentageElements_viaDrawXXL(valueToSlide, valueThatDefines100percent, position, direction_normalized, size, text, sliderIsCurrentlyGrabbedByTheMouse, positionOfHandleCap, magnifiedSize); + Handles.Slider(controlID, positionOfHandleCap, direction, sizeOfHandleCap, capFunction, snap); //-> Draw the Handle cap with Unitys build-in Handles + + if (sliderIsCurrentlyGrabbedByTheMouse) + { + return GetScaledValue(valueThatDefines100percent, position, direction_normalized, size); + } + else + { + return valueToSlide; + } + } + + static void DrawPercentageElements_viaDrawXXL(float valueToSlide, float valueThatDefines100percent, Vector3 position, Vector3 direction_normalized, float size, string text, bool sliderIsCurrentlyGrabbedByTheMouse, Vector3 positionOfHandleCap, float magnifiedSize) + { + Event currentEvent = Event.current; + if (currentEvent.type == EventType.Repaint) //-> Draw with Draw XXL only inside the "Repaint"-event, otherwise the "DrawBasics.MaxAllowedDrawnLinesPerFrame"-mechanic will get confused and restricts the drawing earlier than neccessary. + { + float worldSpaceLength_of100percentSpan = magnifiedSize; + Vector3 endPosition_of100percentSpan = position + direction_normalized * worldSpaceLength_of100percentSpan; + Color colorOfSpring_independentFromStretchTension = sliderIsCurrentlyGrabbedByTheMouse ? Handles.selectedColor : Handles.color; //-> When Draw XXL draws with Unitys Handles-Lines it doesn't automatically detect the "Handles.color", but instead takes the color that is specified as parameter argument in the draw function, or else falls back to "DrawBasics.defaultColor" + + ConfigureDrawXXLsGlobalSettingsForDrawingHandles(); //-> This function is recommended to be used in conjunction with the "RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore()" function, to "encapsulate" everything that Draw XXL draws for Handles. + Draw100percentReferenceLengthDisplay_viaDrawXXL(position, endPosition_of100percentSpan, colorOfSpring_independentFromStretchTension); //-> This draws the 100percent-stretch-reference-display manually instead of using the "alphaOfReferenceLengthDisplay" parameter of the "DrawBasics.LineUnderTension()" below (inside "DrawPercentageValueSpiral_viaDrawXXL()"), because the "alphaOfReferenceLengthDisplay" parameter is not fit for negative values. + DrawPercentageValueSpiral_viaDrawXXL(position, positionOfHandleCap, worldSpaceLength_of100percentSpan, colorOfSpring_independentFromStretchTension); + DrawPercentageValueDisplayText_viaDrawXXL(valueToSlide, valueThatDefines100percent, endPosition_of100percentSpan, direction_normalized, size, colorOfSpring_independentFromStretchTension, text); + RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore(); //-> This function should be used in conjunction with the "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()" function, to "encapsulate" everything that Draw XXL draws for Handles. + } + } + + static void Draw100percentReferenceLengthDisplay_viaDrawXXL(Vector3 positionOfTheHandle, Vector3 endPosition_of100percentSpan, Color colorOfSpring_independentFromStretchTension) + { + Color color_ofReferenceLengthDisplay = colorOfSpring_independentFromStretchTension; //-> When Draw XXL draws with Unitys Handles-Lines it doesn't automatically detect the "Handles.color", but instead takes the color that is specified as parameter argument in the draw function, or else falls back to "DrawBasics.defaultColor" + float alphaOf100percentReferenceLengthDisplay = 0.5f; + color_ofReferenceLengthDisplay.a = alphaOf100percentReferenceLengthDisplay; + bool flattenThickRoundLineIntoAmplitudePlane = true; + float endPlates_size = 0.1f; + + DrawBasics.LengthInterpretation endPlates_sizeInterpretation_before = DrawBasics.endPlates_sizeInterpretation; + DrawBasics.endPlates_sizeInterpretation = DrawBasics.LengthInterpretation.relativeToLineLength; //-> Instruct Draw XXL how to interpret the "endPlates_size" parameter for all following draw operations + DrawBasics.Line(positionOfTheHandle, endPosition_of100percentSpan, color_ofReferenceLengthDisplay, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, default(Vector3), flattenThickRoundLineIntoAmplitudePlane, endPlates_size); + DrawBasics.endPlates_sizeInterpretation = endPlates_sizeInterpretation_before; //-> Revert the Draw XXL setting to what it was before + } + + static void DrawPercentageValueSpiral_viaDrawXXL(Vector3 positionOfTheHandle, Vector3 positionOfHandleCap, float worldSpaceLength_of100percentSpan, Color colorOfSpring_independentFromStretchTension) + { + DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.spiral; + float relaxedLength = worldSpaceLength_of100percentSpan; + Vector3 theMiddleOfTheLine = 0.5f * (positionOfTheHandle + positionOfHandleCap); + float sizeOfTheHandleInScreenspace = HandleUtility.GetHandleSize(theMiddleOfTheLine); + float stylePatternScaleFactor = 5.0f * sizeOfTheHandleInScreenspace; //-> this lets the line style pattern appear approximately constant in screenspace, no matter how far the line is away from the camera. + float stretchFactor_forStretchedTensionColor = 2.0f; //-> this is unused, since the color does not depend on the stretch tension + float stretchFactor_forSqueezedTensionColor = 0.0f; //-> this is unused, since the color does not depend on the stretch tension + string text_ofStretchedSpring = null; + float width_worldSpace = 0.0f; //-> If a width other than 0 is wanted: The width value is in world space units, in contrast to the "Handles.DrawLine(thickness)" paramter, which is in UI points. For a suggestion how to convert it: See "HandlesExamples.DrawLine()" + float alphaOfReferenceLengthDisplay = 0.0f; //-> this is disabled here, since it already has been drawn separately further up + + float stylePatternScaleFactor_alongLineDir_ignoringAmplitude_before = DrawBasics.StylePatternScaleFactor_alongLineDir_ignoringAmplitude; + DrawBasics.StylePatternScaleFactor_alongLineDir_ignoringAmplitude = 0.5f; //-> Instruct Draw XXL how to use this style scaling for all following draw operations + DrawBasics.LineUnderTension(positionOfTheHandle, positionOfHandleCap, relaxedLength, colorOfSpring_independentFromStretchTension, lineStyle, stretchFactor_forStretchedTensionColor, colorOfSpring_independentFromStretchTension, stretchFactor_forSqueezedTensionColor, colorOfSpring_independentFromStretchTension, width_worldSpace, text_ofStretchedSpring, alphaOfReferenceLengthDisplay, stylePatternScaleFactor); + DrawBasics.StylePatternScaleFactor_alongLineDir_ignoringAmplitude = stylePatternScaleFactor_alongLineDir_ignoringAmplitude_before; //-> Revert the Draw XXL setting to what it was before + } + + static void DrawPercentageValueDisplayText_viaDrawXXL(float valueToSlide, float valueThatDefines100percent, Vector3 endPosition_of100percentSpan, Vector3 direction_normalized, float size, Color colorOfSpring_independentFromStretchTension, string text) + { + float percentageOfCurrentSlidedValue = 100.0f * (valueToSlide / valueThatDefines100percent); + int percentageOfCurrentSlidedValue_rounded = Mathf.RoundToInt(percentageOfCurrentSlidedValue); + string emptyTextSpaceBelowText_soThatTheTextIsNotOccludedByTheHandleCapOrTheSpring = DrawText.MarkupCustomHeightEmptyLine(3); + string displayedText = text + "
" + percentageOfCurrentSlidedValue_rounded + "%" + emptyTextSpaceBelowText_soThatTheTextIsNotOccludedByTheHandleCapOrTheSpring; + Vector3 textPosition = endPosition_of100percentSpan; + float textSize = 0.1f * size; + Vector3 textDirection = Direction_goesFromLeftToRight_insideSceneViewScreen(direction_normalized) ? direction_normalized : (-direction_normalized); + Color textColor = colorOfSpring_independentFromStretchTension; //-> When Draw XXL draws with Unitys Handles-Lines it doesn't automatically detect the "Handles.color", but instead takes the color that is specified as parameter argument in the draw function, or else falls back to "DrawBasics.defaultColor" + DrawText.TextAnchorDXXL textAnchor = DrawText.TextAnchorDXXL.LowerCenter; + UtilitiesDXXL_Text.WriteFramed(displayedText, textPosition, textColor, textSize, textDirection, default(Vector3), textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, true); + } + + static float ForceAwayFromZero(float valueToSlide_duringMouseDown, float valueThatDefines100percent) + { + float smallestAllowedPercentage_duringMouseDown = 0.001f; + float valueToSlide_duringMouseDown_absolute = Mathf.Abs(valueToSlide_duringMouseDown); + float valueThatDefines100percent_absolute = Mathf.Abs(valueThatDefines100percent); + float smallestAllowedValue_absolute = smallestAllowedPercentage_duringMouseDown * valueThatDefines100percent_absolute; + + if (valueToSlide_duringMouseDown_absolute < smallestAllowedValue_absolute) + { + return smallestAllowedValue_absolute; + } + else + { + return valueToSlide_duringMouseDown; + } + } + + static float GetScaledValue(float valueThatDefines100percent, Vector3 position, Vector3 direction_normalized, float size) + { + //calculate the scaled value similar as "Handles.ScaleSlider()" does it: + Event currentEvent = Event.current; + float percentageValueToSlide_duringMouseDown_asPercentageFrom0to1 = valueToSlide_duringMouseDown / valueThatDefines100percent; + current_mousePositionInScreenspace += currentEvent.delta; + float divisor = size * percentageValueToSlide_duringMouseDown_asPercentageFrom0to1; + float distanceHowMuchTheHandleHasBeenDraggedWithTheMouse = relativeSizeOfPercentageSliderCap * HandleUtility.CalcLineTranslation(mousePositionInScreenspace_duringMouseDown, current_mousePositionInScreenspace, position, direction_normalized) / divisor; + float returnedScaleValue = valueToSlide_duringMouseDown * (1.0f + distanceHowMuchTheHandleHasBeenDraggedWithTheMouse); + return returnedScaleValue; + } + + static float valueToShiftInsideRange_duringMouseDown; + + public static float RangeSlider(float value, float lowerEndOfRange, float upperEndOfRange, Vector3 position, Vector3 direction) + { + return RangeSlider(value, lowerEndOfRange, upperEndOfRange, position, direction, HandleUtility.GetHandleSize(position), Handles.SphereHandleCap, -1.0f, null); + } + + public static float RangeSlider(float value, float lowerEndOfRange, float upperEndOfRange, Vector3 position, Vector3 direction, DrawBasics.IconType icon) + { + return RangeSlider(value, lowerEndOfRange, upperEndOfRange, position, direction, HandleUtility.GetHandleSize(position), Handles.SphereHandleCap, -1.0f, icon); + } + + public static float RangeSlider(float value, float lowerEndOfRange, float upperEndOfRange, Vector3 position, Vector3 direction, string text) + { + return RangeSlider(value, lowerEndOfRange, upperEndOfRange, position, direction, HandleUtility.GetHandleSize(position), Handles.SphereHandleCap, -1.0f, text); + } + + public static float RangeSlider(float value, float lowerEndOfRange, float upperEndOfRange, Vector3 position, Vector3 direction, float size, Handles.CapFunction capFunction, float snap, DrawBasics.IconType icon) + { + float iconSizeScaleFactor = 2.8f; + int boldStrokeWidth_asPPMofSize = 25000; + string textThatConsistsOfOnlyOneLetterWhichIsTheIconItself = DrawText.MarkupIcon(icon); + string textThatConsistsOfOnlyOneLetterWhichIsTheIconItself_withBolderFont = DrawText.MarkupStrokeWidth(textThatConsistsOfOnlyOneLetterWhichIsTheIconItself, boldStrokeWidth_asPPMofSize); + string textThatConsistsOfOnlyOneLetterWhichIsTheIconItself_withBolderFont_andScaledBigger = DrawText.MarkupSize(textThatConsistsOfOnlyOneLetterWhichIsTheIconItself_withBolderFont, iconSizeScaleFactor); + float relative_verticalTextPositionOffsetDistance_fromRangeLine = 1.25f; + return RangeSlider(value, lowerEndOfRange, upperEndOfRange, position, direction, size, capFunction, snap, textThatConsistsOfOnlyOneLetterWhichIsTheIconItself_withBolderFont_andScaledBigger, relative_verticalTextPositionOffsetDistance_fromRangeLine); + } + + public static float RangeSlider(float value, float lowerEndOfRange, float upperEndOfRange, Vector3 position, Vector3 direction, float size, Handles.CapFunction capFunction, float snap, string text = null) + { + float relative_verticalTextPositionOffsetDistance_fromRangeLine = 2.0f; + return RangeSlider(value, lowerEndOfRange, upperEndOfRange, position, direction, size, capFunction, snap, text, relative_verticalTextPositionOffsetDistance_fromRangeLine); + } + + static float RangeSlider(float value, float lowerEndOfRange, float upperEndOfRange, Vector3 position, Vector3 direction, float size, Handles.CapFunction capFunction, float snap, string text, float relative_verticalTextPositionOffsetDistance_fromRangeLine) + { + //A slider handle where the value is clamped inside an allowed range, as it is frequently seen in Unitys Inspector Window. + //"position": more precisely: it is the position of the lowerEndOfTheRange + + if (Mathf.Approximately(lowerEndOfRange, upperEndOfRange)) + { + Debug.LogError("Cannot display 'RangeSlider' with range span of 0."); + return value; + } + + TryFlipValues_inCaseLowerEndIsBiggerThanUpperEnd(ref lowerEndOfRange, ref upperEndOfRange); + float value_clamped = Mathf.Clamp(value, lowerEndOfRange, upperEndOfRange); + + Event currentEvent = Event.current; + + if (currentEvent.type == EventType.MouseDown) //-> Detect the "MouseDown"-event BEFORE it gets eaten via "event.Use()" inside "Handles.Slider()". It will not be there anymore if this code is placed BELOW the "Handles.Slider" function call. + { + valueToShiftInsideRange_duringMouseDown = value_clamped; + mousePositionInScreenspace_duringMouseDown = currentEvent.mousePosition; + current_mousePositionInScreenspace = currentEvent.mousePosition; + } + + float rangeSpan = upperEndOfRange - lowerEndOfRange; + float value_portionThatIsBiggerThanLowerEndOfRange = value_clamped - lowerEndOfRange; + float valueToSlide_as0to1insideRange = value_portionThatIsBiggerThanLowerEndOfRange / rangeSpan; + float magnifiedSize = 2.0f * size; //-> Displaying the range slider bigger than Unitys default display of Handles + Vector3 direction_normalized = direction.normalized; + Vector3 rangeStart_to_rangeEnd = direction_normalized * magnifiedSize; + Vector3 currentOffsetOfHandleCap = rangeStart_to_rangeEnd * valueToSlide_as0to1insideRange; + Vector3 positionOfHandleCap = position + currentOffsetOfHandleCap; + Vector3 positionOfRangeEnd = position + rangeStart_to_rangeEnd; + float sizeOfHandleCap = relativeSizeOfPercentageSliderCap * size; + + int controlID = GUIUtility.GetControlID(FocusType.Passive); + bool sliderIsCurrentlyGrabbedByTheMouse = (GUIUtility.hotControl == controlID); + + DrawRangeElements_viaDrawXXL(value_clamped, lowerEndOfRange, upperEndOfRange, positionOfHandleCap, position, positionOfRangeEnd, direction_normalized, size, magnifiedSize, sizeOfHandleCap, sliderIsCurrentlyGrabbedByTheMouse, text, relative_verticalTextPositionOffsetDistance_fromRangeLine); + Handles.Slider(controlID, positionOfHandleCap, direction, sizeOfHandleCap, capFunction, snap); //-> Draw the Handle cap with Unitys build-in Handles + + if (sliderIsCurrentlyGrabbedByTheMouse) + { + return GetScaledValueInsideRange(lowerEndOfRange, upperEndOfRange, position, direction_normalized, size); + } + else + { + return value_clamped; + } + } + + static void TryFlipValues_inCaseLowerEndIsBiggerThanUpperEnd(ref float lowerEndOfRange, ref float upperEndOfRange) + { + if (lowerEndOfRange > upperEndOfRange) + { + float clipboard = lowerEndOfRange; + lowerEndOfRange = upperEndOfRange; + upperEndOfRange = clipboard; + } + } + + static void DrawRangeElements_viaDrawXXL(float value_clamped, float lowerEndOfRange, float upperEndOfRange, Vector3 positionOfHandleCap, Vector3 positionOfRangeStart, Vector3 positionOfRangeEnd, Vector3 direction_normalized, float size, float lenghtOfTheRangeLine, float sizeOfHandleCap, bool sliderIsCurrentlyGrabbedByTheMouse, string textFromUser, float relative_verticalTextPositionOffsetDistance_fromRangeLine) + { + Event currentEvent = Event.current; + if (currentEvent.type == EventType.Repaint) //-> Draw with Draw XXL only inside the "Repaint"-event, otherwise the "DrawBasics.MaxAllowedDrawnLinesPerFrame"-mechanic will get confused and restricts the drawing earlier than neccessary. + { + ConfigureDrawXXLsGlobalSettingsForDrawingHandles(); //-> This function is recommended to be used in conjunction with the "RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore()" function, to "encapsulate" everything that Draw XXL draws for Handles. + + Color color = sliderIsCurrentlyGrabbedByTheMouse ? Handles.selectedColor : Handles.color; //-> When Draw XXL draws with Unitys Handles-Lines it doesn't automatically detect the "Handles.color", but instead takes the color that is specified as parameter argument in the draw function, or else falls back to "DrawBasics.defaultColor" + float half_sizeOfHandleCap = 0.5f * sizeOfHandleCap; + Vector3 position_ofRangeStartPlate = positionOfRangeStart - direction_normalized * half_sizeOfHandleCap; + Vector3 position_ofRangeEndPlate = positionOfRangeEnd + direction_normalized * half_sizeOfHandleCap; + float textSize = 0.15f * size; + + DrawRangeLine_viaDrawXXL(position_ofRangeStartPlate, position_ofRangeEndPlate, color); + Vector3 usedTextDirection = DrawRangeValuesAsText_viaDrawXXL(value_clamped, lowerEndOfRange, upperEndOfRange, positionOfHandleCap, position_ofRangeStartPlate, position_ofRangeEndPlate, direction_normalized, textSize, color); + DrawRangeSliderName_viaDrawXXL(usedTextDirection, positionOfRangeStart, positionOfRangeEnd, direction_normalized, lenghtOfTheRangeLine, textFromUser, textSize, relative_verticalTextPositionOffsetDistance_fromRangeLine, color); + + RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore(); //-> This function should be used in conjunction with the "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()" function, to "encapsulate" everything that Draw XXL draws for Handles. + } + } + + static void DrawRangeLine_viaDrawXXL(Vector3 position_ofRangeStartPlate, Vector3 position_ofRangeEndPlate, Color color) + { + float width_worldSpace = 0.0f; //-> If a width other than 0 is wanted: The width value is in world space units, in contrast to the "Handles.DrawLine(thickness)" paramter, which is in UI points. For a suggestion how to convert it: See "HandlesExamples.DrawLine()" + DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + bool flattenThickRoundLineIntoAmplitudePlane = false; //-> "false" makes the endPlates to round discs, instead as flat lines + float endPlates_size = 0.1f; + + DrawBasics.LengthInterpretation endPlates_sizeInterpretation_before = DrawBasics.endPlates_sizeInterpretation; + DrawBasics.endPlates_sizeInterpretation = DrawBasics.LengthInterpretation.relativeToLineLength; //-> Instruct Draw XXL how to interpret the "endPlates_size" parameter for all following draw operations + DrawBasics.Line(position_ofRangeStartPlate, position_ofRangeEndPlate, color, width_worldSpace, null, style, 1.0f, 0.0f, default(Vector3), flattenThickRoundLineIntoAmplitudePlane, endPlates_size); + DrawBasics.endPlates_sizeInterpretation = endPlates_sizeInterpretation_before; //-> Revert the Draw XXL setting to what it was before + } + + static Vector3 DrawRangeValuesAsText_viaDrawXXL(float value_clamped, float lowerEndOfRange, float upperEndOfRange, Vector3 positionOfHandleCap, Vector3 position_ofRangeStartPlate, Vector3 position_ofRangeEndPlate, Vector3 direction_normalized, float textSize, Color color) + { + //-> Simple trick: Adding blank text space in front of the value to have some distance from the range line, so it doesn't intersect with the range line end plates or the handle cap. This works only if we specify the textAnchor to be on the left side, which we do below. + string lowerRangeEnd_asTextString = " " + lowerEndOfRange; + string upperRangeEnd_asTextString = " " + upperEndOfRange; + string currentValue_asTextString = " " + value_clamped; + + int boldStrokeWidth_asPPMofSize = 60000; + string lowerRangeEnd_asTextString_inBoldText = DrawText.MarkupStrokeWidth(lowerRangeEnd_asTextString, boldStrokeWidth_asPPMofSize); + string upperRangeEnd_asTextString_inBoldText = DrawText.MarkupStrokeWidth(upperRangeEnd_asTextString, boldStrokeWidth_asPPMofSize); + + Vector3 textUpward_forValueTexts = Direction_goesFromLeftToRight_insideSceneViewScreen(direction_normalized) ? (-direction_normalized) : direction_normalized; + Vector3 textDirection_forValueTexts = default(Vector3); //-> If a text orientation vector is not specified then Draw XXL will automatically try to align the text according to static global setting "DrawText.automaticTextOrientation". In this case only "textUp" is specified and constrains the text orientation, so that the text will be perpendicular to the range line. + DrawText.TextAnchorDXXL textAnchor_forValueTexts = DrawText.TextAnchorDXXL.MiddleLeft; + bool autoFlipTheTextToPreventMirrorInvertedDisplay = true; + + UtilitiesDXXL_Text.WriteFramed(lowerRangeEnd_asTextString_inBoldText, position_ofRangeStartPlate, color, textSize, textDirection_forValueTexts, textUpward_forValueTexts, textAnchor_forValueTexts, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipTheTextToPreventMirrorInvertedDisplay, 0.0f, true); + UtilitiesDXXL_Text.WriteFramed(upperRangeEnd_asTextString_inBoldText, position_ofRangeEndPlate, color, textSize, textDirection_forValueTexts, textUpward_forValueTexts, textAnchor_forValueTexts, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipTheTextToPreventMirrorInvertedDisplay, 0.0f, true); + UtilitiesDXXL_Text.WriteFramed(currentValue_asTextString, positionOfHandleCap, color, textSize, textDirection_forValueTexts, textUpward_forValueTexts, textAnchor_forValueTexts, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipTheTextToPreventMirrorInvertedDisplay, 0.0f, true); + + Vector3 textDirectionOfTheValueTexts_thatHasBeenFinallyUsedByTheAutomaticTextOrientation_normalized = DrawText.parsedTextSpecs.used_textDirection_normalized; //-> After each call of "DrawText.Write()" some infos about the most currently written text can be accessed via the global static field "DrawText.parsedTextSpecs". In our case we request the "textDirection_forValueTexts", which we further up didn't specify by ourselfes to make use of Draw XXLs automatic text orientation. With that direction we can conveniently add an offset to the "textFromUser", which gets drawn in "DrawRangeSliderName_viaDrawXXL()". + return textDirectionOfTheValueTexts_thatHasBeenFinallyUsedByTheAutomaticTextOrientation_normalized; + } + + static void DrawRangeSliderName_viaDrawXXL(Vector3 textDirectionOfTheValueTexts_normalized, Vector3 positionOfRangeStart, Vector3 positionOfRangeEnd, Vector3 direction_normalized, float lenghtOfTheRangeLine, string textFromUser, float textSize, float relative_verticalTextPositionOffsetDistance_fromRangeLine, Color color) + { + Vector3 centerPosition_ofTheRangeLine = 0.5f * (positionOfRangeStart + positionOfRangeEnd); + float textPositionOffsetDistance_fromRangeLine = relative_verticalTextPositionOffsetDistance_fromRangeLine * textSize; + Vector3 textPositionOffset_fromRangeLine = (-textDirectionOfTheValueTexts_normalized) * textPositionOffsetDistance_fromRangeLine; + Vector3 position_ofTextFromUser = centerPosition_ofTheRangeLine + textPositionOffset_fromRangeLine; + Vector3 textDirection_forTextFromUser = Direction_goesFromLeftToRight_insideSceneViewScreen(direction_normalized) ? direction_normalized : (-direction_normalized); + Vector3 textUp_forTextFromUser = default(Vector3); //-> If "textUp" is not specified, then it will be automatically aligned according to "DrawText.automaticTextOrientation". In this case only "textDirection_forTextFromUser" constrains the text orientation, while in "DrawRangeValuesAsText_viaDrawXXL()" only "textUp" constrains the text orientation. + DrawText.TextAnchorDXXL textAnchor_forTextFromUser = DrawText.TextAnchorDXXL.UpperCenter; + DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid; + float enclosingBox_lineWidth_relToTextSize = 0.0f; + float enclosingBox_paddingSize_relToTextSize = 0.3f; + float autoLineBreakWidth = lenghtOfTheRangeLine; //-> Ensure that text doesn't get bigger than the range span itself. This could also be achieved with the "forceRestrictTextBlockSizeToThisMaxTextWidth"-parameter, in which case the text doesn't make a line break, but becomes smaller to fit into the wanted size span. + bool autoFlipTheTextToPreventMirrorInvertedDisplay = true; + UtilitiesDXXL_Text.WriteFramed(textFromUser, position_ofTextFromUser, color, textSize, textDirection_forTextFromUser, textUp_forTextFromUser, textAnchor_forTextFromUser, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, 0.0f, 0.0f, autoLineBreakWidth, autoFlipTheTextToPreventMirrorInvertedDisplay, 0.0f, true); + } + + static float GetScaledValueInsideRange(float lowerEndOfRange, float upperEndOfRange, Vector3 position, Vector3 direction_normalized, float size) + { + //calculate the scaled value similar as "Handles.ScaleSlider()" does it: + Event currentEvent = Event.current; + current_mousePositionInScreenspace += currentEvent.delta; + float distanceHowMuchTheHandleHasBeenDraggedWithTheMouse = relativeSizeOfPercentageSliderCap * HandleUtility.CalcLineTranslation(mousePositionInScreenspace_duringMouseDown, current_mousePositionInScreenspace, position, direction_normalized) / size; + float rangeSpan = upperEndOfRange - lowerEndOfRange; + float returnedValue = valueToShiftInsideRange_duringMouseDown + rangeSpan * distanceHowMuchTheHandleHasBeenDraggedWithTheMouse; + float returnedValue_clamped = Mathf.Clamp(returnedValue, lowerEndOfRange, upperEndOfRange); + return returnedValue_clamped; + } + + static Vector3 startPosition_onDiscRadius; + static float discsTurnAngleInDegrees_sinceMouseDown; + public static Quaternion DiscWithAngleDisplay(Quaternion rotation, Vector3 position, Vector3 axis, float size, bool cutoffPlane, float snap) + { + //this is like Unitys "Handles.Disc" function, but additionally displays the changing angle as text. + //Sidenote: As can be seen in Unitys Editor source code(link zu https://github.com/Unity-Technologies/UnityCsReference/blob/2022.2/Editor/Mono/Handles.cs ) starting with Unity2022.2 Unitys "Handles" class has an additional overload for the "RotationHandle()" function, that takes the "RotationHandleIds ids"-parameter. This opens the possibility to extend this "DiscWithAngleDisplay()" function to the whole rotation handle with all of it's circles, without having to recreate the whole rotation handle by yourself. + + Event currentEvent = Event.current; + + if (currentEvent.type == EventType.MouseDown) //-> Detect the "MouseDown"-event BEFORE it gets eaten via "event.Use()" inside "Handles.Disc()". It will not be there anymore if this code is placed BELOW the "Handles.Disc" function call. + { + mousePositionInScreenspace_duringMouseDown = currentEvent.mousePosition; + current_mousePositionInScreenspace = currentEvent.mousePosition; + discsTurnAngleInDegrees_sinceMouseDown = 0.0f; + startPosition_onDiscRadius = Get_startPosition_onDiscRadius(position, axis, size, cutoffPlane); + } + + int controlID = GUIUtility.GetControlID(FocusType.Passive); + bool discIsCurrentlyGrabbedByTheMouse = (GUIUtility.hotControl == controlID); + + if (currentEvent.type == EventType.MouseDrag) //-> Detect the "MouseDrag"-event BEFORE it gets eaten via "event.Use()" inside "Handles.Disc()". It will not be there anymore if this code is placed BELOW the "Handles.Disc" function call. + { + discsTurnAngleInDegrees_sinceMouseDown = Get_discsTurnAngleInDegrees_sinceMouseDown(position, axis, size, discIsCurrentlyGrabbedByTheMouse); + } + + Quaternion returnedQuaternion = Handles.Disc(controlID, rotation, position, axis, size, cutoffPlane, snap); + + if (currentEvent.type == EventType.Repaint) //-> Draw with Draw XXL only inside the "Repaint"-event, otherwise the "DrawBasics.MaxAllowedDrawnLinesPerFrame"-mechanic will get confused and restricts the drawing earlier than neccessary. + { + if (discIsCurrentlyGrabbedByTheMouse) + { + ConfigureDrawXXLsGlobalSettingsForDrawingHandles(); //-> This function is recommended to be used in conjunction with the "RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore()" function, to "encapsulate" everything that Draw XXL draws for Handles. + DrawAngleTextDisplay_viaDrawXXL(position, axis); + RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore(); //-> This function should be used in conjunction with the "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()" function, to "encapsulate" everything that Draw XXL draws for Handles. + } + } + + return returnedQuaternion; + + } + + static Vector3 Get_startPosition_onDiscRadius(Vector3 position, Vector3 axis, float size, bool cutoffPlane) + { + if (cutoffPlane) + { + Vector3 forwardDirection_ofCurrentCamera = Camera.current != null ? Camera.current.transform.forward : Vector3.forward; + Vector3 aVectorInsideTheDiscPlane = Vector3.Cross(axis, forwardDirection_ofCurrentCamera).normalized; + return HandleUtility.ClosestPointToArc(position, axis, aVectorInsideTheDiscPlane, 180.0f, size); + } + else + { + return HandleUtility.ClosestPointToDisc(position, axis, size); + } + } + + static float Get_discsTurnAngleInDegrees_sinceMouseDown(Vector3 position, Vector3 axis, float size, bool discIsCurrentlyGrabbedByTheMouse) + { + if (discIsCurrentlyGrabbedByTheMouse) + { + //calculate the angle in the same way as "Handles.Disc()" does it: + Event currentEvent = Event.current; + Vector3 direction_normalized = Vector3.Cross(axis, position - startPosition_onDiscRadius).normalized; + current_mousePositionInScreenspace += currentEvent.delta; + return HandleUtility.CalcLineTranslation(mousePositionInScreenspace_duringMouseDown, current_mousePositionInScreenspace, startPosition_onDiscRadius, direction_normalized) / size * 30.0f; + } + return 0.0f; + } + + static void DrawAngleTextDisplay_viaDrawXXL(Vector3 position, Vector3 axis) + { + string textOnCircledVector = Mathf.Abs(discsTurnAngleInDegrees_sinceMouseDown) + "°"; + string textOnCircledVector_enlarged = "" + textOnCircledVector + ""; //-> "size=11" is the default size, so this enlarges the text by a factor of 2. + Color colorOfCircledVectorAndText = Handles.selectedColor; //-> When Draw XXL draws with Unitys Handles-Lines it doesn't automatically detect the "Handles.color", but instead takes the color that is specified as parameter argument in the draw function, or else falls back to "DrawBasics.defaultColor" + float coneLength = 0.3f; + bool skipFallbackDisplayOfZeroAngles = true; //-> If this is be "false", then Draw XXL would display a fallback text for angles of zero or nearby. In the use case here this fallback is not wanted. + float minAngleDeg_withoutTextLineBreak = 120.0f; //-> If the angle is small, then the displayed text covers a bigger angle span than the angle itself. This would lead to automatic line breaks in the text display, which are prevented by setting this "minAngleDeg_withoutTextLineBreak" setting to a higher value. + DrawBasics.VectorCircled(startPosition_onDiscRadius, position, axis, -discsTurnAngleInDegrees_sinceMouseDown, colorOfCircledVectorAndText, 0.0f, textOnCircledVector_enlarged, coneLength, false, skipFallbackDisplayOfZeroAngles, true, minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine); + } + + public static float AnalogJoystickSlider(Vector3 position, Vector3 direction) + { + return AnalogJoystickSlider(position, direction, HandleUtility.GetHandleSize(position), Handles.SphereHandleCap); + } + + + static float travelledWorldSpaceDistance_sinceMouseDown; + public static float AnalogJoystickSlider(Vector3 position, Vector3 direction, float size, Handles.CapFunction capFunction) + { + //This simulates the behaviour of an one-dimensional analog joystick. You can click and drag the slider and it will return a value between -1 and 1, depending on how much you protrude it from the center. As soon as you lift the mouse the slider will snap back to the zero position. + + int control_ID = GUIUtility.GetControlID(FocusType.Passive); + Event currentEvent = Event.current; + + if (GUIUtility.hotControl == 0) { travelledWorldSpaceDistance_sinceMouseDown = 0.0f; } + + Vector3 direction_normalized; //-> is only calculated later for some events, to save some performance + size = size * relativeSizeOfPercentageSliderCap; + float maximumProtrusion_inWorldSpaceUnits = 10.0f * size; + + switch (currentEvent.GetTypeForControl(control_ID)) + { + case EventType.MouseDown: + if ((HandleUtility.nearestControl == control_ID) && (currentEvent.button == 0) && (currentEvent.alt == false)) + { + GUIUtility.hotControl = control_ID; + mousePositionInScreenspace_duringMouseDown = currentEvent.mousePosition; + current_mousePositionInScreenspace = currentEvent.mousePosition; + currentEvent.Use(); + EditorGUIUtility.SetWantsMouseJumping(1); + } + break; + case EventType.MouseUp: + if (GUIUtility.hotControl == control_ID) + { + travelledWorldSpaceDistance_sinceMouseDown = 0.0f; + GUIUtility.hotControl = 0; + currentEvent.Use(); + EditorGUIUtility.SetWantsMouseJumping(0); + } + break; + case EventType.MouseDrag: + if (GUIUtility.hotControl == control_ID) + { + current_mousePositionInScreenspace = current_mousePositionInScreenspace + currentEvent.delta; + travelledWorldSpaceDistance_sinceMouseDown = HandleUtility.CalcLineTranslation(mousePositionInScreenspace_duringMouseDown, current_mousePositionInScreenspace, position, direction.normalized); //-> It's undocumented, but "HandleUtility.CalcLineTranslation()" expects a NORMALIZED direction. + travelledWorldSpaceDistance_sinceMouseDown = Mathf.Clamp(travelledWorldSpaceDistance_sinceMouseDown, -maximumProtrusion_inWorldSpaceUnits, maximumProtrusion_inWorldSpaceUnits); + GUI.changed = true; + currentEvent.Use(); + } + break; + case EventType.Repaint: + Color color_before = Handles.color; + TrySetColorDuringMouseInteraction(control_ID, currentEvent); + direction_normalized = CalculateDirectionNormalized_forJoystickSlider(control_ID, direction); + + float radiusOfMountingPointDisc = 0.2f * size; + Handles.DrawSolidDisc(position, GetSceneViewCamerasForwardDirection(), radiusOfMountingPointDisc); + TryDrawJoystickSpiralSpring(control_ID, travelledWorldSpaceDistance_sinceMouseDown, position, direction_normalized, maximumProtrusion_inWorldSpaceUnits); + DrawJoystickSliderCap(control_ID, position, direction_normalized, size, capFunction, EventType.Repaint); + + Handles.color = color_before; + break; + case EventType.Layout: + direction_normalized = CalculateDirectionNormalized_forJoystickSlider(control_ID, direction); + DrawJoystickSliderCap(control_ID, position, direction_normalized, size, capFunction, EventType.Layout); + break; + default: + break; + } + + return (travelledWorldSpaceDistance_sinceMouseDown / maximumProtrusion_inWorldSpaceUnits); + } + + static void TrySetColorDuringMouseInteraction(int control_ID, Event currentEvent) + { + if (control_ID == GUIUtility.hotControl) + { + Handles.color = Handles.selectedColor; + } + else + { + if (IsHovering(control_ID, currentEvent)) + { + Handles.color = Handles.preselectionColor; + } + } + } + + static bool IsHovering(int control_ID, Event currentEvent) + { + return ((GUIUtility.hotControl == 0) && (control_ID == HandleUtility.nearestControl) && (currentEvent.alt == false)); + } + + static Vector3 CalculateDirectionNormalized_forJoystickSlider(int control_ID, Vector3 direction) + { + if (control_ID == GUIUtility.hotControl) + { + return direction.normalized; + } + else + { + return direction; //-> is not required as normalized when the handle is not selected + } + } + + static void DrawJoystickSliderCap(int control_ID, Vector3 position, Vector3 direction_normalized, float size, Handles.CapFunction capFunction, EventType eventType) + { + Vector3 currentPosition_ofJoystickSlider = Get_currentPosition_ofJoystickSlider(travelledWorldSpaceDistance_sinceMouseDown, position, direction_normalized); + Quaternion rotation = Quaternion.LookRotation(direction_normalized); + capFunction(control_ID, currentPosition_ofJoystickSlider, rotation, size, eventType); + } + + static void TryDrawJoystickSpiralSpring(int control_ID, float travelledWorldSpaceDistance_sinceMouseDown, Vector3 position, Vector3 direction_normalized, float maximumProtrusion_inWorldSpaceUnits) + { + if (GUIUtility.hotControl == control_ID) + { + if (Mathf.Approximately(travelledWorldSpaceDistance_sinceMouseDown, 0.0f) == false) + { + DrawJoystickSpiralSpring(travelledWorldSpaceDistance_sinceMouseDown, position, direction_normalized, maximumProtrusion_inWorldSpaceUnits); + } + } + } + + static void DrawJoystickSpiralSpring(float travelledWorldSpaceDistance_sinceMouseDown, Vector3 position, Vector3 direction_normalized, float maximumProtrusion_inWorldSpaceUnits) + { + ConfigureDrawXXLsGlobalSettingsForDrawingHandles(); //-> This function is recommended to be used in conjunction with the "RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore()" function, to "encapsulate" everything that Draw XXL draws for Handles. + + //Generated via code snippet: + Vector3 start_of_spiral = position; + Vector3 end_of_spiral = Get_currentPosition_ofJoystickSlider(travelledWorldSpaceDistance_sinceMouseDown, position, direction_normalized); + float relaxedLength_of_spiral = maximumProtrusion_inWorldSpaceUnits; + Color relaxedColor_of_spiral = Handles.color; + DrawBasics.LineStyle style_of_spiral = DrawBasics.LineStyle.spiral; + float stretchFactor_forStretchedTensionColor_of_spiral = 2.0f; + Color color_forStretchedTension_of_spiral = Handles.color; + float stretchFactor_forSqueezedTensionColor_of_spiral = 0.0f; + Color color_forSqueezedTension_of_spiral = Handles.color; + float width_of_spiral = 0.0f; + string text_of_spiral = null; + float alphaOfReferenceLengthDisplay_of_spiral = 0.5f; + float stylePatternScaleFactor_of_spiral = 3.5f * maximumProtrusion_inWorldSpaceUnits; + Vector3 customAmplitudeAndTextDir_of_spiral = default(Vector3); + bool flattenThickRoundLineIntoAmplitudePlane_of_spiral = false; + float endPlates_size_of_spiral = 0.0f; + float enlargeSmallTextToThisMinTextSize_of_spiral = 0.0f; + float durationInSec_of_spiral = 0.0f; + bool hiddenByNearerObjects_of_spiral = true; + bool skipPatternEnlargementForLongLines_of_spiral = true; + bool skipPatternEnlargementForShortLines_of_spiral = true; + + float stylePatternScaleFactor_alongLineDir_ignoringAmplitude_before = DrawBasics.StylePatternScaleFactor_alongLineDir_ignoringAmplitude; + DrawBasics.StylePatternScaleFactor_alongLineDir_ignoringAmplitude = 0.6f; //-> Instruct Draw XXL how to use this style scaling for all following draw operations + DrawBasics.LineUnderTension(start_of_spiral, end_of_spiral, relaxedLength_of_spiral, relaxedColor_of_spiral, style_of_spiral, stretchFactor_forStretchedTensionColor_of_spiral, color_forStretchedTension_of_spiral, stretchFactor_forSqueezedTensionColor_of_spiral, color_forSqueezedTension_of_spiral, width_of_spiral, text_of_spiral, alphaOfReferenceLengthDisplay_of_spiral, stylePatternScaleFactor_of_spiral, customAmplitudeAndTextDir_of_spiral, flattenThickRoundLineIntoAmplitudePlane_of_spiral, endPlates_size_of_spiral, enlargeSmallTextToThisMinTextSize_of_spiral, durationInSec_of_spiral, hiddenByNearerObjects_of_spiral, skipPatternEnlargementForLongLines_of_spiral, skipPatternEnlargementForShortLines_of_spiral); + DrawBasics.StylePatternScaleFactor_alongLineDir_ignoringAmplitude = stylePatternScaleFactor_alongLineDir_ignoringAmplitude_before; //-> Revert the Draw XXL setting to what it was before + + RevertDrawXXLsGlobalHandleSettingsToWhatTheyWereBefore(); //-> This function should be used in conjunction with the "ConfigureDrawXXLsGlobalSettingsForDrawingHandles()" function, to "encapsulate" everything that Draw XXL draws for Handles. + } + + static Vector3 Get_currentPosition_ofJoystickSlider(float travelledWorldSpaceDistance_sinceMouseDown, Vector3 position, Vector3 direction_normalized) + { + return (position + direction_normalized * travelledWorldSpaceDistance_sinceMouseDown); + } + + static Vector3 GetSceneViewCamerasForwardDirection() + { + if (SceneView.lastActiveSceneView == null) + { + return Vector3.forward; + } + else + { + return SceneView.lastActiveSceneView.camera.transform.forward; + } + } + + static bool Direction_goesFromLeftToRight_insideSceneViewScreen(Vector3 direction) + { + if (SceneView.lastActiveSceneView == null) + { + return false; + } + else + { + return (Vector3.Dot(direction, SceneView.lastActiveSceneView.camera.transform.right) > 0.0f); + } + } + +#endif + + } + +} diff --git a/Editor/DrawDebugLibrary/HandlesExamples.cs.meta b/Editor/DrawDebugLibrary/HandlesExamples.cs.meta new file mode 100644 index 0000000..a4466e3 --- /dev/null +++ b/Editor/DrawDebugLibrary/HandlesExamples.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ecf32ddad5758149b7a2a98d2e09d1f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/InternalDXXL_TaggedScreenspaceObjectDrawer.cs b/Editor/DrawDebugLibrary/InternalDXXL_TaggedScreenspaceObjectDrawer.cs new file mode 100644 index 0000000..6aba319 --- /dev/null +++ b/Editor/DrawDebugLibrary/InternalDXXL_TaggedScreenspaceObjectDrawer.cs @@ -0,0 +1,35 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomPropertyDrawer(typeof(InternalDXXL_TaggedScreenspaceObject))] + public class InternalDXXL_TaggedScreenspaceObjectDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + SerializedProperty sP_gameobject = property.FindPropertyRelative("gameobject"); + Rect space_ofGameobject = new Rect(position.x, position.y, 0.4f * position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_ofGameobject, sP_gameobject, GUIContent.none); + + Rect space_ofTextLabel = new Rect(position.x + 0.4f * position.width, position.y, 0.2f * position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.LabelField(space_ofTextLabel, new GUIContent("Text:", "You can insert insert line breaks by typing
inside the text.")); + + SerializedProperty sP_text = property.FindPropertyRelative("text"); + Rect space_ofText = new Rect(position.x + 0.50f * position.width, position.y, 0.3f * position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_ofText, sP_text, GUIContent.none); + + SerializedProperty sP_color = property.FindPropertyRelative("color"); + Rect space_ofColor = new Rect(position.x + 0.8f * position.width, position.y, 0.2f * position.width, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(space_ofColor, sP_color, GUIContent.none); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return EditorGUIUtility.singleLineHeight; + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/InternalDXXL_TaggedScreenspaceObjectDrawer.cs.meta b/Editor/DrawDebugLibrary/InternalDXXL_TaggedScreenspaceObjectDrawer.cs.meta new file mode 100644 index 0000000..ef0cdcb --- /dev/null +++ b/Editor/DrawDebugLibrary/InternalDXXL_TaggedScreenspaceObjectDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4dab1b285fe724498fe779c8b261dac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/LineDrawer2DInspector.cs b/Editor/DrawDebugLibrary/LineDrawer2DInspector.cs new file mode 100644 index 0000000..c029b80 --- /dev/null +++ b/Editor/DrawDebugLibrary/LineDrawer2DInspector.cs @@ -0,0 +1,139 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(LineDrawer2D))] + [CanEditMultipleObjects] + public class LineDrawer2DInspector : LineDrawerInspector + { + void OnEnable() + { + OnEnable_base(); + OnEnable_base_atLineDrawer(); + } + + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("line2D"); + + SerializedProperty sP_lineType = serializedObject.FindProperty("lineType"); + EditorGUILayout.PropertyField(sP_lineType, new GUIContent("Line type")); + + SerializedProperty sP_lineDefinitionMode = serializedObject.FindProperty("lineDefinitionMode"); + EditorGUILayout.PropertyField(sP_lineDefinitionMode, new GUIContent("Line definition mode")); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + Draw_startPos_endPos_lineDirection_definingSection(sP_lineDefinitionMode); + TryDrawTensionSpecs(sP_lineType); + DrawColors(sP_lineType); + DrawWidthAndDependentParameters(sP_lineType); + TryDrawExtentionLength(sP_lineType); + TryDrawLineStyleAndDependentParameters(sP_lineType); + TryDrawAnimationSection(sP_lineType); + + if (sP_lineType.enumValueIndex != (int)LineDrawer.LineType.vectorWithExtention) + { + TryDrawConeConfig(sP_lineType); + Draw_endPlatesConfig(); + TryDrawAlphaFadeOut(sP_lineType); + } + + TryDrawNormalizedMarkerCheckBox(sP_lineType); + + DrawZPosChooserFor2D(); + DrawTextSpecs(sP_lineType, true); + DrawCheckboxFor_drawOnlyIfSelected("line"); + DrawCheckboxFor_hiddenByNearerObjects("line"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + public override void Draw_startPositionSection(SerializedProperty sP_lineDefinitionSection1_isOutfolded, GUIStyle style_ofFoldoutWithRichtext) + { + sP_lineDefinitionSection1_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_lineDefinitionSection1_isOutfolded.boolValue, "Start Position", true, style_ofFoldoutWithRichtext); + if (sP_lineDefinitionSection1_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_positionDefinitionOption_ofStartPos = serializedObject.FindProperty("positionDefinitionOption_ofStartPos"); + EditorGUILayout.PropertyField(sP_positionDefinitionOption_ofStartPos, new GUIContent("Position Definition")); + switch (sP_positionDefinitionOption_ofStartPos.enumValueIndex) + { + case (int)LineDrawer.PositionDefinitionOption.positionOfThisGameobjectPlusOffset: + Draw_DrawPosition2DOffset(false, null, "Global Offset", "Local Offset", true); + break; + case (int)LineDrawer.PositionDefinitionOption.positionOfOtherGameobjectPlusOffset: + EditorGUILayout.PropertyField(serializedObject.FindProperty("partnerGameobject"), new GUIContent("Other Gameobject")); + Draw_DrawPosition2DOffset_ofPartnerGameobject(false, null, "Global Offset", "Local Offset", true); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("coordinateSpaceForLocalOffsetOnOtherGameobject_forStartPos"), new GUIContent("Local Offset Space")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + case (int)LineDrawer.PositionDefinitionOption.chooseFree: + DrawSpecificationOf_customVector2_3(null, false, null, false, false, false, false, true, false); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + public override void Draw_endPositionSection(SerializedProperty sP_lineDefinitionSection2_isOutfolded, GUIStyle style_ofFoldoutWithRichtext) + { + sP_lineDefinitionSection2_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_lineDefinitionSection2_isOutfolded.boolValue, "End Position", true, style_ofFoldoutWithRichtext); + if (sP_lineDefinitionSection2_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_positionDefinitionOption_ofEndPos = serializedObject.FindProperty("positionDefinitionOption_ofEndPos"); + EditorGUILayout.PropertyField(sP_positionDefinitionOption_ofEndPos, new GUIContent("Position Definition")); + switch (sP_positionDefinitionOption_ofEndPos.enumValueIndex) + { + case (int)LineDrawer.PositionDefinitionOption.positionOfThisGameobjectPlusOffset: + Draw_DrawPosition2DOffset_independentAlternativeValue(false, null, "Global Offset", "Local Offset", true); + break; + case (int)LineDrawer.PositionDefinitionOption.positionOfOtherGameobjectPlusOffset: + EditorGUILayout.PropertyField(serializedObject.FindProperty("partnerGameobject_independentAlternativeValue"), new GUIContent("Other Gameobject")); + Draw_DrawPosition2DOffset_ofPartnerGameobject_independentAlternativeValue(false, null, "Global Offset", "Local Offset", true); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("coordinateSpaceForLocalOffsetOnOtherGameobject_forEndPos"), new GUIContent("Local Offset Space")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + case (int)LineDrawer.PositionDefinitionOption.chooseFree: + DrawSpecificationOf_customVector2_4(null, false, null, false, false, false, false, true, false); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + public override void Draw_lineVectorSection(SerializedProperty sP_lineDefinitionSection_isOutfolded, string headline, GUIStyle style_ofFoldoutWithRichtext) + { + sP_lineDefinitionSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_lineDefinitionSection_isOutfolded.boolValue, headline, true, style_ofFoldoutWithRichtext); + if (sP_lineDefinitionSection_isOutfolded.boolValue) + { + DrawSpecificationOf_customVector2_1(null, false, null, false, false, false, false, true); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/LineDrawer2DInspector.cs.meta b/Editor/DrawDebugLibrary/LineDrawer2DInspector.cs.meta new file mode 100644 index 0000000..8e9ff61 --- /dev/null +++ b/Editor/DrawDebugLibrary/LineDrawer2DInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a39f78e0e4bdf2543a7639d1b1308787 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/LineDrawerInspector.cs b/Editor/DrawDebugLibrary/LineDrawerInspector.cs new file mode 100644 index 0000000..79ab939 --- /dev/null +++ b/Editor/DrawDebugLibrary/LineDrawerInspector.cs @@ -0,0 +1,536 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(LineDrawer))] + [CanEditMultipleObjects] + public class LineDrawerInspector : VisualizerParentInspector + { + LineDrawer lineDrawerMonoBehaviour_unserialized; + + void OnEnable() + { + OnEnable_base(); + OnEnable_base_atLineDrawer(); + } + + public void OnEnable_base_atLineDrawer() + { + lineDrawerMonoBehaviour_unserialized = (LineDrawer)target; + } + + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("line"); + + SerializedProperty sP_lineType = serializedObject.FindProperty("lineType"); + EditorGUILayout.PropertyField(sP_lineType, new GUIContent("Line type")); + + SerializedProperty sP_lineDefinitionMode = serializedObject.FindProperty("lineDefinitionMode"); + EditorGUILayout.PropertyField(sP_lineDefinitionMode, new GUIContent("Line definition mode")); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + Draw_startPos_endPos_lineDirection_definingSection(sP_lineDefinitionMode); + TryDrawTensionSpecs(sP_lineType); + DrawColors(sP_lineType); + DrawWidthAndDependentParameters(sP_lineType); + TryDrawExtentionLength(sP_lineType); + TryDrawLineStyleAndDependentParameters(sP_lineType); + TryDrawAnimationSection(sP_lineType); + + if (sP_lineType.enumValueIndex != (int)LineDrawer.LineType.vectorWithExtention) + { + TryDrawFlatLineSection(sP_lineType); + TryDrawConeConfig(sP_lineType); + Draw_endPlatesConfig(); + TryDrawAlphaFadeOut(sP_lineType); + } + + TryDrawNormalizedMarkerCheckBox(sP_lineType); + + DrawTextSpecs(sP_lineType, false); + DrawCheckboxFor_drawOnlyIfSelected("line"); + DrawCheckboxFor_hiddenByNearerObjects("line"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + public void Draw_startPos_endPos_lineDirection_definingSection(SerializedProperty sP_lineDefinitionMode) + { + SerializedProperty sP_lineDefinitionSection1_isOutfolded = serializedObject.FindProperty("lineDefinitionSection1_isOutfolded"); + SerializedProperty sP_lineDefinitionSection2_isOutfolded = serializedObject.FindProperty("lineDefinitionSection2_isOutfolded"); + + GUIStyle style_ofFoldoutWithRichtext = new GUIStyle(EditorStyles.foldout); + style_ofFoldoutWithRichtext.richText = true; + string headline_of_directionVectorChooserSections = "Vector to End Position"; + switch (sP_lineDefinitionMode.enumValueIndex) + { + case (int)LineDrawer.LineDefinitionMode.startPositionAndEndPosition: + Draw_startPositionSection(sP_lineDefinitionSection1_isOutfolded, style_ofFoldoutWithRichtext); + Draw_endPositionSection(sP_lineDefinitionSection2_isOutfolded, style_ofFoldoutWithRichtext); + break; + case (int)LineDrawer.LineDefinitionMode.startPositionAndDirectionVectorToEndPosition: + Draw_startPositionSection(sP_lineDefinitionSection1_isOutfolded, style_ofFoldoutWithRichtext); + Draw_lineVectorSection(sP_lineDefinitionSection2_isOutfolded, headline_of_directionVectorChooserSections, style_ofFoldoutWithRichtext); + break; + case (int)LineDrawer.LineDefinitionMode.endPositionAndDirectionVectorToIt: + Draw_lineVectorSection(sP_lineDefinitionSection1_isOutfolded, headline_of_directionVectorChooserSections, style_ofFoldoutWithRichtext); + Draw_endPositionSection(sP_lineDefinitionSection2_isOutfolded, style_ofFoldoutWithRichtext); + break; + default: + break; + } + + if (sP_lineDefinitionSection2_isOutfolded.boolValue == false) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + public virtual void Draw_startPositionSection(SerializedProperty sP_lineDefinitionSection1_isOutfolded, GUIStyle style_ofFoldoutWithRichtext) + { + sP_lineDefinitionSection1_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_lineDefinitionSection1_isOutfolded.boolValue, "Start Position", true, style_ofFoldoutWithRichtext); + if (sP_lineDefinitionSection1_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_positionDefinitionOption_ofStartPos = serializedObject.FindProperty("positionDefinitionOption_ofStartPos"); + EditorGUILayout.PropertyField(sP_positionDefinitionOption_ofStartPos, new GUIContent("Position Definition")); + switch (sP_positionDefinitionOption_ofStartPos.enumValueIndex) + { + case (int)LineDrawer.PositionDefinitionOption.positionOfThisGameobjectPlusOffset: + Draw_DrawPosition3DOffset(false, null, "Global Offset", "Local Offset", true); + break; + case (int)LineDrawer.PositionDefinitionOption.positionOfOtherGameobjectPlusOffset: + EditorGUILayout.PropertyField(serializedObject.FindProperty("partnerGameobject"), new GUIContent("Other Gameobject")); + Draw_DrawPosition3DOffset_ofPartnerGameobject(false, null, "Global Offset", "Local Offset", true); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("coordinateSpaceForLocalOffsetOnOtherGameobject_forStartPos"), new GUIContent("Local Offset Space")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + case (int)LineDrawer.PositionDefinitionOption.chooseFree: + DrawSpecificationOf_customVector3_3(null, false, null, false, false, false, false, true, false); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + public virtual void Draw_endPositionSection(SerializedProperty sP_lineDefinitionSection2_isOutfolded, GUIStyle style_ofFoldoutWithRichtext) + { + sP_lineDefinitionSection2_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_lineDefinitionSection2_isOutfolded.boolValue, "End Position", true, style_ofFoldoutWithRichtext); + if (sP_lineDefinitionSection2_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_positionDefinitionOption_ofEndPos = serializedObject.FindProperty("positionDefinitionOption_ofEndPos"); + EditorGUILayout.PropertyField(sP_positionDefinitionOption_ofEndPos, new GUIContent("Position Definition")); + switch (sP_positionDefinitionOption_ofEndPos.enumValueIndex) + { + case (int)LineDrawer.PositionDefinitionOption.positionOfThisGameobjectPlusOffset: + Draw_DrawPosition3DOffset_independentAlternativeValue(false, null, "Global Offset", "Local Offset", true); + break; + case (int)LineDrawer.PositionDefinitionOption.positionOfOtherGameobjectPlusOffset: + EditorGUILayout.PropertyField(serializedObject.FindProperty("partnerGameobject_independentAlternativeValue"), new GUIContent("Other Gameobject")); + Draw_DrawPosition3DOffset_ofPartnerGameobject_independentAlternativeValue(false, null, "Global Offset", "Local Offset", true); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("coordinateSpaceForLocalOffsetOnOtherGameobject_forEndPos"), new GUIContent("Local Offset Space")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + case (int)LineDrawer.PositionDefinitionOption.chooseFree: + DrawSpecificationOf_customVector3_4(null, false, null, false, false, false, false, true, false); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + public virtual void Draw_lineVectorSection(SerializedProperty sP_lineDefinitionSection_isOutfolded, string headline, GUIStyle style_ofFoldoutWithRichtext) + { + sP_lineDefinitionSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_lineDefinitionSection_isOutfolded.boolValue, headline, true, style_ofFoldoutWithRichtext); + if (sP_lineDefinitionSection_isOutfolded.boolValue) + { + DrawSpecificationOf_customVector3_1(null, false, null, false, false, false, false, true); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + public void TryDrawTensionSpecs(SerializedProperty sP_lineType) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineUnderTension) + { + SerializedProperty sP_relaxedLength = serializedObject.FindProperty("relaxedLength"); + float lineLength = lineDrawerMonoBehaviour_unserialized.GetLineLength(); + + EditorGUILayout.PropertyField(sP_relaxedLength, new GUIContent("Relaxed Length", "This is the reference length for how the tension appears. If the line has a length of this value, then it appears with its relaxed color and the line style isn't stretched or squeezed. Other line lengths will stretch and squeeze the line style and change the color, as if the line is under tension like a spring.")); + sP_relaxedLength.floatValue = Mathf.Max(sP_relaxedLength.floatValue, 0.001f); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.FloatField(new GUIContent("Current Line Length"), lineLength); + EditorGUILayout.FloatField(new GUIContent("Current Stretch Factor"), lineLength / sP_relaxedLength.floatValue); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("alphaOfReferenceLengthDisplay"), new GUIContent("Alpha of reference length display")); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + public void DrawColors(SerializedProperty sP_lineType) + { + if (sP_lineType.enumValueIndex != (int)LineDrawer.LineType.lineUnderTension) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("startColor"), new GUIContent("Color")); + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.standardLine) + { + GUILayout.BeginHorizontal(); + SerializedProperty sP_useDifferentEndColor = serializedObject.FindProperty("useDifferentEndColor"); + EditorGUILayout.PropertyField(sP_useDifferentEndColor, new GUIContent("End Color")); + EditorGUI.BeginDisabledGroup(!sP_useDifferentEndColor.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("endColor"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.blinkingLine) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("blinkColor"), new GUIContent("Blink Color")); + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineUnderTension) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("relaxedColor"), new GUIContent("Relaxed Color")); + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_forStretchedTension"), new GUIContent("Stretched Color")); + SerializedProperty sP_stretchFactor_forStretchedTensionColor = serializedObject.FindProperty("stretchFactor_forStretchedTensionColor"); + EditorGUILayout.PropertyField(sP_stretchFactor_forStretchedTensionColor, new GUIContent("appearing at stretch factor of")); + sP_stretchFactor_forStretchedTensionColor.floatValue = Mathf.Max(sP_stretchFactor_forStretchedTensionColor.floatValue, 1.001f); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_forSqueezedTension"), new GUIContent("Squeezed Color")); + SerializedProperty sP_stretchFactor_forSqueezedTensionColor = serializedObject.FindProperty("stretchFactor_forSqueezedTensionColor"); + EditorGUILayout.PropertyField(sP_stretchFactor_forSqueezedTensionColor, new GUIContent("appearing at stretch factor of")); + sP_stretchFactor_forSqueezedTensionColor.floatValue = Mathf.Max(sP_stretchFactor_forSqueezedTensionColor.floatValue, 0.0f); + sP_stretchFactor_forSqueezedTensionColor.floatValue = Mathf.Min(sP_stretchFactor_forSqueezedTensionColor.floatValue, 0.999f); + GUILayout.EndHorizontal(); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineWithAlternatingColors) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("alternatingColor"), new GUIContent("Alternating Color")); + } + } + + public void DrawWidthAndDependentParameters(SerializedProperty sP_lineType) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.movingArrowsLine) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineWidth_ofMovingArrowsLine"), new GUIContent("Width")); + + string autoRoundingExplanationTooltip = "Very small (or very big) values may get rounded up (down) internally to prevent an explosive raise of drawn lines, see also 'DrawXXL.DrawBasics.MaxAllowedDrawnLinesPerFrame'." + Environment.NewLine + Environment.NewLine + "This automatic rounding has interdepency with 'Width' and "; + + SerializedProperty sP_distanceBetweenArrows = serializedObject.FindProperty("distanceBetweenArrows"); + SerializedProperty sP_lengthOfArrows = serializedObject.FindProperty("lengthOfArrows"); + + EditorGUILayout.PropertyField(sP_distanceBetweenArrows, new GUIContent("Distance between arrows", autoRoundingExplanationTooltip + "'Length of Arrows'.")); + sP_distanceBetweenArrows.floatValue = Mathf.Max(sP_distanceBetweenArrows.floatValue, 0.002f); + + EditorGUILayout.PropertyField(sP_lengthOfArrows, new GUIContent("Length of Arrows", autoRoundingExplanationTooltip + "'Distance between arrows'.")); + sP_lengthOfArrows.floatValue = Mathf.Max(sP_lengthOfArrows.floatValue, 0.001f); + } + else + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineWidth"), new GUIContent("Width")); + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineWithAlternatingColors) + { + SerializedProperty sP_lengthOfStripes = serializedObject.FindProperty("lengthOfStripes"); + EditorGUILayout.PropertyField(sP_lengthOfStripes, new GUIContent("Length of Stripes", "This may get rounded internally to prevent an explosive raise of drawn lines, see also 'DrawXXL.DrawBasics.MaxAllowedDrawnLinesPerFrame'." + Environment.NewLine + "It also may get raised automatically for larger line widths.")); + sP_lengthOfStripes.floatValue = Mathf.Max(sP_lengthOfStripes.floatValue, UtilitiesDXXL_DrawBasics.min_lengthOfStripes_ofAlternatingColorLine); + } + } + } + + public void TryDrawExtentionLength(SerializedProperty sP_lineType) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.vectorWithExtention) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("extentionLength"), new GUIContent("Extention length")); + + GUILayout.BeginHorizontal(); + SerializedProperty sP_forceFixedConeLength = serializedObject.FindProperty("forceFixedConeLength"); + EditorGUILayout.PropertyField(sP_forceFixedConeLength, new GUIContent("Fixed cone length (in world units)", "Makes the cone length independent from the vector length.")); + EditorGUI.BeginDisabledGroup(!sP_forceFixedConeLength.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("forceFixedConeLength_value"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + } + } + + public void TryDrawLineStyleAndDependentParameters(SerializedProperty sP_lineType) + { + if ((sP_lineType.enumValueIndex == (int)LineDrawer.LineType.standardLine) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.blinkingLine) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineUnderTension)) + { + SerializedProperty sP_lineStyle; + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineUnderTension) + { + sP_lineStyle = serializedObject.FindProperty("lineStyle_underTension"); + } + else + { + sP_lineStyle = serializedObject.FindProperty("lineStyle"); + } + + EditorGUILayout.PropertyField(sP_lineStyle, new GUIContent("Style")); + + bool lineStyle_usesPatternScaling = UtilitiesDXXL_LineStyles.CheckIfLineStyleUsesPatternScaling((DrawBasics.LineStyle)sP_lineStyle.enumValueIndex); + if (lineStyle_usesPatternScaling) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_stylePatternScaleFactor = serializedObject.FindProperty("stylePatternScaleFactor"); + EditorGUILayout.PropertyField(sP_stylePatternScaleFactor, new GUIContent("Style Pattern Scaling", "This may sometimes get automatically rounded up for line widths that are bigger than 0. See also the 'Skip automatic pattern enlargement for * lines'-fields.")); + sP_stylePatternScaleFactor.floatValue = Mathf.Max(sP_stylePatternScaleFactor.floatValue, UtilitiesDXXL_LineStyles.minStylePatternScaleFactor); + + DrawSkipPatternEnlargementCheckBoxes(); + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineWithAlternatingColors) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + DrawSkipPatternEnlargementCheckBoxes(); + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawSkipPatternEnlargementCheckBoxes() + { + SerializedProperty sP_skipPatternEnlargementForLongLines = serializedObject.FindProperty("skipPatternEnlargementForLongLines"); + sP_skipPatternEnlargementForLongLines.boolValue = EditorGUILayout.ToggleLeft(new GUIContent("Skip automatic pattern enlargement for long lines", "For long lines the style pattern is automatically enlarged. Otherwise there would be a higher risk of Editor performance slowdown, because a single long styled line could accidentally use up many small straight lines, from which it is composed." + Environment.NewLine + Environment.NewLine + "You can skip this automatic enlargement at your own risk. 'DrawXXL.DrawBasics.MaxAllowedDrawnLinesPerFrame' will still protect you from Editor freeze."), sP_skipPatternEnlargementForLongLines.boolValue); + + SerializedProperty sP_skipPatternEnlargementForShortLines = serializedObject.FindProperty("skipPatternEnlargementForShortLines"); + sP_skipPatternEnlargementForShortLines.boolValue = EditorGUILayout.ToggleLeft(new GUIContent("Skip automatic pattern enlargement for short lines", "The style pattern of some lines gets automatically enlarged when the line becomes very short or for large line widths. This reduces the risk of Editor performance slowdown, because a single styled line could accidentally use up many small straight lines, from which it is composed, mainly when 'Style Pattern Scaling' has a very small value." + Environment.NewLine + "It also keeps the style patterns recognizable when a large line width would let 'dashes' appear as 'dots'." + Environment.NewLine + Environment.NewLine + "This enlargement only affects line styles with gaps, like 'dotted' or 'dashed'. It also only affects lines whose width is bigger than zero." + Environment.NewLine + Environment.NewLine + "You can skip this automatic enlargement at your own risk. 'DrawXXL.DrawBasics.MaxAllowedDrawnLinesPerFrame' will still protect you from Editor freeze."), sP_skipPatternEnlargementForShortLines.boolValue); + } + + public void TryDrawAnimationSection(SerializedProperty sP_lineType) + { + bool lineIsAnimatable = lineDrawerMonoBehaviour_unserialized.DrawnLineUsesAnimation(false); + if (lineIsAnimatable) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.movingArrowsLine) + { + DrawAnimationSpeed(serializedObject.FindProperty("animationSpeed_ofMovingArrowsLine"), new GUIContent("Animation speed")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("backwardAnimationFlipsArrowDirection"), new GUIContent("Flip arrows during backward animation", "This has only effect if 'Animation speed' is negative. If it is disabled then the arrows are always forced to point towards the line end and they appear to move backwards.")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + if ((sP_lineType.enumValueIndex == (int)LineDrawer.LineType.standardLine) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineWithAlternatingColors)) + { + DrawAnimationSpeed(serializedObject.FindProperty("animationSpeed"), new GUIContent("Animation speed")); + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.blinkingLine) + { + SerializedProperty sP_blinkDurationInSec = serializedObject.FindProperty("blinkDurationInSec"); + DrawAnimationSpeed(sP_blinkDurationInSec, new GUIContent("Blink duration", "In seconds")); + sP_blinkDurationInSec.floatValue = Mathf.Max(sP_blinkDurationInSec.floatValue, UtilitiesDXXL_DrawBasics.min_blinkDurationInSec); + } + } + } + + void DrawAnimationSpeed(SerializedProperty sP_used_animationSpeedField, GUIContent displayName) + { + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_used_animationSpeedField, displayName); + if (Application.isPlaying == false) + { + SerializedProperty sP_animationDuringEditMode = serializedObject.FindProperty("animationDuringEditMode"); + sP_animationDuringEditMode.boolValue = EditorGUILayout.ToggleLeft(new GUIContent("Also in Edit Mode", "Animation ouside playmode is convenient, but forces the Editor Windows to continuously redraw, which may have a negative effect on the Editor performance." + Environment.NewLine + Environment.NewLine + "Note: The setting here may be without effect if a 'Draw XXL Gizmo Line Count Manager' component already redraws the Scene and Game view."), sP_animationDuringEditMode.boolValue); + } + GUILayout.EndHorizontal(); + } + + void TryDrawFlatLineSection(SerializedProperty sP_lineType) + { + bool lineCanBeAffectedByFlattenBool = lineDrawerMonoBehaviour_unserialized.CheckIf_lineCanBeAffectedByFlattenBool(); + GUIContent guiContent_ofFlatToggle; + if (lineCanBeAffectedByFlattenBool) + { + guiContent_ofFlatToggle = new GUIContent("Flat", "This makes the line flat instead of round. It only affects lines with a width that is bigger than zero, or if 'end plates' or 'end cones' are used."); + } + else + { + guiContent_ofFlatToggle = new GUIContent("Flat", "This only has effect if the line width is bigger than zero, or if 'end plates' or 'end cones' are used."); + } + + bool lineIsFlat; + EditorGUI.BeginDisabledGroup(!lineCanBeAffectedByFlattenBool); + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.movingArrowsLine) + { + SerializedProperty sP_flattenThickRoundLineIntoAmplitudePlane_ofMovingArrowsLine = serializedObject.FindProperty("flattenThickRoundLineIntoAmplitudePlane_ofMovingArrowsLine"); + EditorGUILayout.PropertyField(sP_flattenThickRoundLineIntoAmplitudePlane_ofMovingArrowsLine, guiContent_ofFlatToggle); + lineIsFlat = sP_flattenThickRoundLineIntoAmplitudePlane_ofMovingArrowsLine.boolValue; + } + else + { + SerializedProperty sP_flattenThickRoundLineIntoAmplitudePlane = serializedObject.FindProperty("flattenThickRoundLineIntoAmplitudePlane"); + EditorGUILayout.PropertyField(sP_flattenThickRoundLineIntoAmplitudePlane, guiContent_ofFlatToggle); + lineIsFlat = sP_flattenThickRoundLineIntoAmplitudePlane.boolValue; + } + EditorGUI.EndDisabledGroup(); + + if (lineCanBeAffectedByFlattenBool) + { + if (lineIsFlat) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + DrawAmplitudeChooser("Alignment of flat line in 3D space", "Custom Flat Amplitude Direction"); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + } + + public void TryDrawConeConfig(SerializedProperty sP_lineType) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.vector) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("conesConfig"), new GUIContent("Cones")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + Draw_coneLengthInclSpaceInterpretation_forStraightVectors(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + } + } + + public void Draw_endPlatesConfig() + { + SerializedProperty sP_endPlatesConfig = serializedObject.FindProperty("endPlatesConfig"); + EditorGUILayout.PropertyField(sP_endPlatesConfig, new GUIContent("End Plates")); + + if (sP_endPlatesConfig.enumValueIndex != (int)LineDrawer.EndPlatesConfig.disabled) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + Draw_endPlatesSizeInclSpaceInterpretation(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + } + } + + public void TryDrawAlphaFadeOut(SerializedProperty sP_lineType) + { + if ((sP_lineType.enumValueIndex == (int)LineDrawer.LineType.standardLine) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.blinkingLine) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineWithAlternatingColors)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("alphaFadeOutLength_0to1"), new GUIContent("Fade Out Ends")); + } + } + + public void TryDrawNormalizedMarkerCheckBox(SerializedProperty sP_lineType) + { + if ((sP_lineType.enumValueIndex == (int)LineDrawer.LineType.vector) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.vectorWithExtention)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("addNormalizedMarkingText"), new GUIContent("Normalization Marker", "This adds the the text 'normalized' to the vector at the position where it is 1 unit long measured from the start position.")); + } + } + + public void DrawTextSpecs(SerializedProperty sP_lineType, bool is2D) + { + //-> this fakes the appearance of beeing inside the parents text specification foldout + bool emptyLineAtEndIfOutfolded = false; + bool displaySizeScalingStyleOption = false; //-> the text size markups don't work well for text on lines, since the text size anyway gets forced to a portion of the line length + DrawTextInputInclMarkupHelper(true, false, null, emptyLineAtEndIfOutfolded, displaySizeScalingStyleOption); + + if (serializedObject.FindProperty("textSection_isOutfolded").boolValue == true) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUILayout.PropertyField(serializedObject.FindProperty("relSizeOfTextOnLines"), new GUIContent("Text Area Size", "This is relative to the line length.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("shiftTextPosOnLines_toNonIntersecting"), new GUIContent("Shift text upward till non-intersecting", "This only has effect if the text contains line breaks. In such cases it will force all text lines to be on the same side of the drawn line.")); + + GUILayout.BeginHorizontal(); + SerializedProperty sP_enlargeSmallTextToThisMinTextSize = serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"); + EditorGUILayout.PropertyField(sP_enlargeSmallTextToThisMinTextSize, new GUIContent("Minimum Text Size", "Width per letter in world units." + Environment.NewLine + Environment.NewLine + "This is intended for cases where the line is so short that the text isn't well readable any more.")); + EditorGUI.BeginDisabledGroup(!sP_enlargeSmallTextToThisMinTextSize.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize_value"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + if (sP_lineType.enumValueIndex != (int)LineDrawer.LineType.vectorWithExtention) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.vector) + { + string displayName_of_writeComponentValuesAsText = is2D ? "Add x/y length to text" : "Add x/y/z length to text"; + EditorGUILayout.PropertyField(serializedObject.FindProperty("writeComponentValuesAsText"), new GUIContent(displayName_of_writeComponentValuesAsText)); + } + + if (is2D) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + else + { + DrawAmplitudeChooser("Alignment of text in 3D space", "Custom Text Upward Direction"); + if (serializedObject.FindProperty("customVector3Configs.Array.data[1].picker_isOutfolded").boolValue == false) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + } + else + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawAmplitudeChooser(string alignmentSourceEnum_displayName, string vectorPicker_displayName) + { + SerializedProperty sP_amplitudeAndTextAlignment = serializedObject.FindProperty("amplitudeAndTextAlignment"); + EditorGUILayout.PropertyField(sP_amplitudeAndTextAlignment, new GUIContent(alignmentSourceEnum_displayName)); + + if (sP_amplitudeAndTextAlignment.enumValueIndex == (int)LineDrawer.AmplitudeAndTextAlignment.customAmplitudeDirection) + { + DrawSpecificationOf_customVector3_2(vectorPicker_displayName, false, null, false, false, true, false); + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/LineDrawerInspector.cs.meta b/Editor/DrawDebugLibrary/LineDrawerInspector.cs.meta new file mode 100644 index 0000000..323b4c3 --- /dev/null +++ b/Editor/DrawDebugLibrary/LineDrawerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2392ea6e9e0aa8e4eab96afe1299a97e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/LineDrawerScreenspaceInspector.cs b/Editor/DrawDebugLibrary/LineDrawerScreenspaceInspector.cs new file mode 100644 index 0000000..fbf2474 --- /dev/null +++ b/Editor/DrawDebugLibrary/LineDrawerScreenspaceInspector.cs @@ -0,0 +1,381 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(LineDrawerScreenspace))] + [CanEditMultipleObjects] + public class LineDrawerScreenspaceInspector : VisualizerScreenspaceParentInspector + { + LineDrawerScreenspace lineDrawerScreenspaceMonoBehaviour_unserialized; + void OnEnable() + { + OnEnable_base(); + OnEnable_ofScreenspaceParent(); + OnEnable_ofLineDrawerScreenspaceInspector(); + } + + void OnEnable_ofLineDrawerScreenspaceInspector() + { + lineDrawerScreenspaceMonoBehaviour_unserialized = (LineDrawerScreenspace)target; + } + + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("screenspace line"); + if (DrawCameraChooser(true)) + { + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + SerializedProperty sP_lineType = serializedObject.FindProperty("lineType"); + EditorGUILayout.PropertyField(sP_lineType, new GUIContent("Line type")); + + SerializedProperty sP_lineDefinitionMode = serializedObject.FindProperty("lineDefinitionMode"); + EditorGUILayout.PropertyField(sP_lineDefinitionMode, new GUIContent("Line definition mode")); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + Draw_startPos_endPos_lineDirection_definingSection(sP_lineDefinitionMode); + TryDrawTensionSpecs(sP_lineType); + DrawColors(sP_lineType); + DrawWidthAndDependentParameters(sP_lineType); + TryDrawExtendedLines_checkBoxForDistanceOutsideScreen(sP_lineType); + TryDrawLineStyleAndDependentParameters(sP_lineType); + TryDrawAnimationSection(sP_lineType); + + if (sP_lineType.enumValueIndex != (int)LineDrawer.LineType.vectorWithExtention) + { + TryDrawConeConfig(sP_lineType); + Draw_endPlatesConfig(); + TryDrawAlphaFadeOut(sP_lineType); + } + + DrawTextSpecs(sP_lineType); + DrawCheckboxFor_drawOnlyIfSelected("screenspace line"); + } + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void Draw_startPos_endPos_lineDirection_definingSection(SerializedProperty sP_lineDefinitionMode) + { + SerializedProperty sP_lineDefinitionSection1_isOutfolded = serializedObject.FindProperty("lineDefinitionSection1_isOutfolded"); + SerializedProperty sP_lineDefinitionSection2_isOutfolded = serializedObject.FindProperty("lineDefinitionSection2_isOutfolded"); + + GUIStyle style_ofFoldoutWithRichtext = new GUIStyle(EditorStyles.foldout); + style_ofFoldoutWithRichtext.richText = true; + string headline_of_directionVectorChooserSections = "Vector to End Position"; + switch (sP_lineDefinitionMode.enumValueIndex) + { + case (int)LineDrawer.LineDefinitionMode.startPositionAndEndPosition: + Draw_startPositionSection(sP_lineDefinitionSection1_isOutfolded, style_ofFoldoutWithRichtext); + Draw_endPositionSection(sP_lineDefinitionSection2_isOutfolded, style_ofFoldoutWithRichtext); + break; + case (int)LineDrawer.LineDefinitionMode.startPositionAndDirectionVectorToEndPosition: + Draw_startPositionSection(sP_lineDefinitionSection1_isOutfolded, style_ofFoldoutWithRichtext); + Draw_lineVectorSection(sP_lineDefinitionSection2_isOutfolded, headline_of_directionVectorChooserSections, style_ofFoldoutWithRichtext); + break; + case (int)LineDrawer.LineDefinitionMode.endPositionAndDirectionVectorToIt: + Draw_lineVectorSection(sP_lineDefinitionSection1_isOutfolded, headline_of_directionVectorChooserSections, style_ofFoldoutWithRichtext); + Draw_endPositionSection(sP_lineDefinitionSection2_isOutfolded, style_ofFoldoutWithRichtext); + break; + default: + break; + } + + if (sP_lineDefinitionSection2_isOutfolded.boolValue == false) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + void Draw_startPositionSection(SerializedProperty sP_lineDefinitionSection1_isOutfolded, GUIStyle style_ofFoldoutWithRichtext) + { + sP_lineDefinitionSection1_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_lineDefinitionSection1_isOutfolded.boolValue, "Start Position", true, style_ofFoldoutWithRichtext); + if (sP_lineDefinitionSection1_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("positionInsideViewport0to1"), new GUIContent("Position (inside viewport)")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + } + } + + void Draw_endPositionSection(SerializedProperty sP_lineDefinitionSection2_isOutfolded, GUIStyle style_ofFoldoutWithRichtext) + { + sP_lineDefinitionSection2_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_lineDefinitionSection2_isOutfolded.boolValue, "End Position", true, style_ofFoldoutWithRichtext); + if (sP_lineDefinitionSection2_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("positionInsideViewport0to1_v2"), new GUIContent("Position (inside viewport)")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + } + } + + void Draw_lineVectorSection(SerializedProperty sP_lineDefinitionSection_isOutfolded, string headline, GUIStyle style_ofFoldoutWithRichtext) + { + sP_lineDefinitionSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_lineDefinitionSection_isOutfolded.boolValue, headline, true, style_ofFoldoutWithRichtext); + if (sP_lineDefinitionSection_isOutfolded.boolValue) + { + if (serializedObject.FindProperty("customVector2Configs.Array.data[0].source").enumValueIndex != (int)VisualizerParent.CustomVector2Source.rotationAroundZStartingFromRight) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("interpretDirectionAsUnwarped"), new GUIContent("Unwarped direction interpretation", "In most cases the viewport space from 0 to 1 is not a square but a rectangle with an uneven aspect ratio (since the display itself is mostly not a square). That means a vector like ( x=1 / y=1 ) does not raise with 45° but appears somehow warped to a different angle." + Environment.NewLine + Environment.NewLine + "You can activate this if you want the values here to be interpreted as if they would be in a square space, so the ( x=1 / y=1 ) vector will appear as a 45° line.")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + DrawSpecificationOf_customVector2_1(null, false, null, false, false, false, false, true, true, true); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + void TryDrawTensionSpecs(SerializedProperty sP_lineType) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineUnderTension) + { + SerializedProperty sP_relaxedLength_relToViewportHeight = serializedObject.FindProperty("relaxedLength_relToViewportHeight"); + float lineLength_relToViewportHeight = lineDrawerScreenspaceMonoBehaviour_unserialized.GetLineLength_relToViewportHeight(); + + EditorGUILayout.PropertyField(sP_relaxedLength_relToViewportHeight, new GUIContent("Relaxed Length", tooltip_explaining_relativeToViewPortHeight + Environment.NewLine + Environment.NewLine + "This is the reference length for how the tension appears. If the line has a length of this value, then it appears with its relaxed color and the line style isn't stretched or squeezed. Other line lengths will stretch and squeeze the line style and change the color, as if the line is under tension like a spring.")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.FloatField(new GUIContent("Current Line Length", tooltip_explaining_relativeToViewPortHeight), lineLength_relToViewportHeight); + EditorGUILayout.FloatField(new GUIContent("Current Stretch Factor"), lineLength_relToViewportHeight / sP_relaxedLength_relToViewportHeight.floatValue); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("alphaOfReferenceLengthDisplay"), new GUIContent("Alpha of reference length display")); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawColors(SerializedProperty sP_lineType) + { + if (sP_lineType.enumValueIndex != (int)LineDrawer.LineType.lineUnderTension) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("startColor"), new GUIContent("Color")); + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.standardLine) + { + GUILayout.BeginHorizontal(); + SerializedProperty sP_useDifferentEndColor = serializedObject.FindProperty("useDifferentEndColor"); + EditorGUILayout.PropertyField(sP_useDifferentEndColor, new GUIContent("End Color")); + EditorGUI.BeginDisabledGroup(!sP_useDifferentEndColor.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("endColor"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.blinkingLine) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("blinkColor"), new GUIContent("Blink Color")); + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineUnderTension) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("relaxedColor"), new GUIContent("Relaxed Color")); + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_forStretchedTension"), new GUIContent("Stretched Color")); + SerializedProperty sP_stretchFactor_forStretchedTensionColor = serializedObject.FindProperty("stretchFactor_forStretchedTensionColor"); + EditorGUILayout.PropertyField(sP_stretchFactor_forStretchedTensionColor, new GUIContent("appearing at stretch factor of")); + sP_stretchFactor_forStretchedTensionColor.floatValue = Mathf.Max(sP_stretchFactor_forStretchedTensionColor.floatValue, 1.001f); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_forSqueezedTension"), new GUIContent("Squeezed Color")); + SerializedProperty sP_stretchFactor_forSqueezedTensionColor = serializedObject.FindProperty("stretchFactor_forSqueezedTensionColor"); + EditorGUILayout.PropertyField(sP_stretchFactor_forSqueezedTensionColor, new GUIContent("appearing at stretch factor of")); + sP_stretchFactor_forSqueezedTensionColor.floatValue = Mathf.Max(sP_stretchFactor_forSqueezedTensionColor.floatValue, 0.0f); + sP_stretchFactor_forSqueezedTensionColor.floatValue = Mathf.Min(sP_stretchFactor_forSqueezedTensionColor.floatValue, 0.999f); + GUILayout.EndHorizontal(); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineWithAlternatingColors) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("alternatingColor"), new GUIContent("Alternating Color")); + } + } + + void DrawWidthAndDependentParameters(SerializedProperty sP_lineType) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.movingArrowsLine) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineWidth_ofMovingArrowsLine_relToViewportHeight"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + + string autoRoundingExplanationTooltip = "Very small (or very big) values may get rounded up (down) internally to prevent an explosive raise of drawn lines, see also 'DrawXXL.DrawBasics.MaxAllowedDrawnLinesPerFrame'." + Environment.NewLine + Environment.NewLine + "This automatic rounding has interdepency with 'Width' and "; + + SerializedProperty sP_distanceBetweenArrows_relToViewportHeight = serializedObject.FindProperty("distanceBetweenArrows_relToViewportHeight"); + SerializedProperty sP_lengthOfArrows_relToViewportHeight = serializedObject.FindProperty("lengthOfArrows_relToViewportHeight"); + + EditorGUILayout.PropertyField(sP_distanceBetweenArrows_relToViewportHeight, new GUIContent("Distance between arrows", tooltip_explaining_relativeToViewPortHeight + Environment.NewLine + Environment.NewLine + autoRoundingExplanationTooltip + "'Length of Arrows'.")); + EditorGUILayout.PropertyField(sP_lengthOfArrows_relToViewportHeight, new GUIContent("Length of Arrows", tooltip_explaining_relativeToViewPortHeight + Environment.NewLine + Environment.NewLine + autoRoundingExplanationTooltip + "'Distance between arrows'.")); + } + else + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineWidth_relToViewportHeight"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineWithAlternatingColors) + { + SerializedProperty sP_lengthOfStripes_relToViewportHeight = serializedObject.FindProperty("lengthOfStripes_relToViewportHeight"); + EditorGUILayout.PropertyField(sP_lengthOfStripes_relToViewportHeight, new GUIContent("Length of Stripes", tooltip_explaining_relativeToViewPortHeight + Environment.NewLine + Environment.NewLine + "This may get rounded internally to prevent an explosive raise of drawn lines, see also 'DrawXXL.DrawBasics.MaxAllowedDrawnLinesPerFrame'." + Environment.NewLine + "It also may get raised automatically for larger line widths.")); + sP_lengthOfStripes_relToViewportHeight.floatValue = Mathf.Max(sP_lengthOfStripes_relToViewportHeight.floatValue, UtilitiesDXXL_DrawBasics.min_lengthOfStripes_ofAlternatingColorLine); + } + } + } + + void TryDrawExtendedLines_checkBoxForDistanceOutsideScreen(SerializedProperty sP_lineType) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.vectorWithExtention) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("displayDistanceOutsideScreenBorder"), new GUIContent("Display distance if outside screen")); + } + } + + void TryDrawLineStyleAndDependentParameters(SerializedProperty sP_lineType) + { + if ((sP_lineType.enumValueIndex == (int)LineDrawer.LineType.standardLine) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.blinkingLine)) + { + SerializedProperty sP_lineStyle = serializedObject.FindProperty("lineStyle"); + EditorGUILayout.PropertyField(sP_lineStyle, new GUIContent("Style")); + + bool lineStyle_usesPatternScaling = UtilitiesDXXL_LineStyles.CheckIfLineStyleUsesPatternScaling((DrawBasics.LineStyle)sP_lineStyle.enumValueIndex); + if (lineStyle_usesPatternScaling) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("stylePatternScaleFactor"), new GUIContent("Style Pattern Scaling", "This may sometimes get automatically rounded up for line widths that are bigger than 0.")); + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + } + + void TryDrawAnimationSection(SerializedProperty sP_lineType) + { + bool lineIsAnimatable = lineDrawerScreenspaceMonoBehaviour_unserialized.DrawnLineUsesAnimation(false); + if (lineIsAnimatable) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.movingArrowsLine) + { + DrawAnimationSpeed(serializedObject.FindProperty("animationSpeed_ofMovingArrowsLine"), new GUIContent("Animation speed")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("backwardAnimationFlipsArrowDirection"), new GUIContent("Flip arrows during backward animation", "This has only effect if 'Animation speed' is negative. If it is disabled then the arrows are always forced to point towards the line end and they appear to move backwards.")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + if ((sP_lineType.enumValueIndex == (int)LineDrawer.LineType.standardLine) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineWithAlternatingColors)) + { + DrawAnimationSpeed(serializedObject.FindProperty("animationSpeed"), new GUIContent("Animation speed")); + } + + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.blinkingLine) + { + SerializedProperty sP_blinkDurationInSec = serializedObject.FindProperty("blinkDurationInSec"); + DrawAnimationSpeed(sP_blinkDurationInSec, new GUIContent("Blink duration", "In seconds")); + sP_blinkDurationInSec.floatValue = Mathf.Max(sP_blinkDurationInSec.floatValue, UtilitiesDXXL_DrawBasics.min_blinkDurationInSec); + } + } + } + + void DrawAnimationSpeed(SerializedProperty sP_used_animationSpeedField, GUIContent displayName) + { + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_used_animationSpeedField, displayName); + if (Application.isPlaying == false) + { + SerializedProperty sP_animationDuringEditMode = serializedObject.FindProperty("animationDuringEditMode"); + sP_animationDuringEditMode.boolValue = EditorGUILayout.ToggleLeft(new GUIContent("Also in Edit Mode", "Animation ouside playmode is convenient, but forces the Editor Windows to continuously redraw, which may have a negative effect on the Editor performance." + Environment.NewLine + Environment.NewLine + "Note: The setting here may be without effect if a 'Draw XXL Gizmo Line Count Manager' component already redraws the Scene and Game view."), sP_animationDuringEditMode.boolValue); + } + GUILayout.EndHorizontal(); + } + + void TryDrawConeConfig(SerializedProperty sP_lineType) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.vector) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("conesConfig"), new GUIContent("Cones")); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("coneLength_relToViewportHeight"), new GUIContent("Cone Length", tooltip_explaining_relativeToViewPortHeight)); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void Draw_endPlatesConfig() + { + SerializedProperty sP_endPlatesConfig = serializedObject.FindProperty("endPlatesConfig"); + EditorGUILayout.PropertyField(sP_endPlatesConfig, new GUIContent("End Plates")); + + if (sP_endPlatesConfig.enumValueIndex != (int)LineDrawer.EndPlatesConfig.disabled) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("endPlatesSize_relToViewportHeight"), new GUIContent("End Plates Size", tooltip_explaining_relativeToViewPortHeight)); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void TryDrawAlphaFadeOut(SerializedProperty sP_lineType) + { + if ((sP_lineType.enumValueIndex == (int)LineDrawer.LineType.standardLine) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.blinkingLine) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.lineWithAlternatingColors)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("alphaFadeOutLength_0to1"), new GUIContent("Fade Out Ends")); + } + } + + void DrawTextSpecs(SerializedProperty sP_lineType) + { + //-> this fakes the appearance of beeing inside the parents text specification foldout + bool emptyLineAtEndIfOutfolded = false; + bool displaySizeScalingStyleOption = false; //-> the text size markups don't work well for text on lines, since the text size anyway gets forced to a portion of the line length + DrawTextInputInclMarkupHelper(true, false, null, emptyLineAtEndIfOutfolded, displaySizeScalingStyleOption); + + if (serializedObject.FindProperty("textSection_isOutfolded").boolValue == true) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUILayout.PropertyField(serializedObject.FindProperty("relSizeOfTextOnLines"), new GUIContent("Text Area Size", "This is relative to the line length.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("shiftTextPosOnLines_toNonIntersecting"), new GUIContent("Shift text upward till non-intersecting", "This only has effect if the text contains line breaks. In such cases it will force all text lines to be on the same side of the drawn line.")); + + if ((sP_lineType.enumValueIndex == (int)LineDrawer.LineType.standardLine) || (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.blinkingLine)) + { + GUILayout.BeginHorizontal(); + SerializedProperty sP_enlargeSmallTextToThisMinTextSize = serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"); + EditorGUILayout.PropertyField(sP_enlargeSmallTextToThisMinTextSize, new GUIContent("Minimum Text Size", "Width per letter in world units." + Environment.NewLine + Environment.NewLine + tooltip_explaining_relativeToViewPortHeight)); + EditorGUI.BeginDisabledGroup(!sP_enlargeSmallTextToThisMinTextSize.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinRelTextSize_value"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + } + + if (sP_lineType.enumValueIndex != (int)LineDrawer.LineType.vectorWithExtention) + { + if (sP_lineType.enumValueIndex == (int)LineDrawer.LineType.vector) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("writeComponentValuesAsText"), new GUIContent("Add x/y length to text")); + } + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/LineDrawerScreenspaceInspector.cs.meta b/Editor/DrawDebugLibrary/LineDrawerScreenspaceInspector.cs.meta new file mode 100644 index 0000000..44408e1 --- /dev/null +++ b/Editor/DrawDebugLibrary/LineDrawerScreenspaceInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f8c5e5b2bacc2e44945e5291b94e07e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/MeasurementVisualizer2DInspector.cs b/Editor/DrawDebugLibrary/MeasurementVisualizer2DInspector.cs new file mode 100644 index 0000000..a5e68b8 --- /dev/null +++ b/Editor/DrawDebugLibrary/MeasurementVisualizer2DInspector.cs @@ -0,0 +1,326 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(MeasurementVisualizer2D))] + [CanEditMultipleObjects] + public class MeasurementVisualizer2DInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("measurement2D"); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + SerializedProperty sP_measurementType = serializedObject.FindProperty("measurementType"); + SerializedProperty sP_angleUnitToDisplay = serializedObject.FindProperty("angleUnitToDisplay"); + SerializedProperty sP_distanceThresholdType = serializedObject.FindProperty("distanceThresholdType"); + + EditorGUILayout.PropertyField(sP_measurementType, new GUIContent("Measured quantity")); + DrawResult(sP_measurementType, sP_angleUnitToDisplay); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + Draw_geometrySpecification(sP_measurementType, sP_distanceThresholdType, sP_angleUnitToDisplay); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + DrawAppearanceSection(sP_measurementType, sP_distanceThresholdType); + + DrawZPosChooserFor2D(); + DrawTextInputInclMarkupHelper(); + DrawCheckboxFor_drawOnlyIfSelected("measurement2D"); + DrawCheckboxFor_hiddenByNearerObjects("measurement2D"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawResult(SerializedProperty sP_measurementType, SerializedProperty sP_angleUnitToDisplay) + { + SerializedProperty sP_measuredResultValue = serializedObject.FindProperty("measuredResultValue"); + string result_nameString = ""; + switch (sP_measurementType.enumValueIndex) + { + case (int)MeasurementVisualizer2D.MeasurementType.distanceBetweenPoints: + result_nameString = MeasurementVisualizerInspector.Get_resultNameString_forDistance(); + break; + case (int)MeasurementVisualizer2D.MeasurementType.distanceThresholdBetweenPoints: + break; + case (int)MeasurementVisualizer2D.MeasurementType.distanceFromPointToLine: + result_nameString = MeasurementVisualizerInspector.Get_resultNameString_forDistance(); + break; + case (int)MeasurementVisualizer2D.MeasurementType.angleBetweenVectors: + result_nameString = MeasurementVisualizerInspector.Get_resultNameString_forAngle(sP_angleUnitToDisplay); + break; + case (int)MeasurementVisualizer2D.MeasurementType.angleFromLineToLine: + result_nameString = MeasurementVisualizerInspector.Get_resultNameString_forAngle(sP_angleUnitToDisplay); + break; + default: + break; + } + + if (sP_measurementType.enumValueIndex != (int)MeasurementVisualizer2D.MeasurementType.distanceThresholdBetweenPoints) + { + EditorGUILayout.FloatField(new GUIContent(result_nameString, "read only"), sP_measuredResultValue.floatValue); + } + } + + void Draw_geometrySpecification(SerializedProperty sP_measurementType, SerializedProperty sP_distanceThresholdType, SerializedProperty sP_angleUnitToDisplay) + { + switch (sP_measurementType.enumValueIndex) + { + case (int)MeasurementVisualizer2D.MeasurementType.distanceBetweenPoints: + Draw_specificationForTwoPoints("Start", "End", true, true); + break; + case (int)MeasurementVisualizer2D.MeasurementType.distanceThresholdBetweenPoints: + Draw_specificationForTwoPoints("Start", "End", false, false); + EditorGUILayout.PropertyField(sP_distanceThresholdType, new GUIContent("Number of threshold distances")); + switch (sP_distanceThresholdType.enumValueIndex) + { + case (int)MeasurementVisualizer.DistanceThresholdType.one: + EditorGUILayout.PropertyField(serializedObject.FindProperty("smallerThresholdDistance"), new GUIContent("Threshold distance")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("exactlyOnThresholdBehaviour"), new GUIContent("Distances exactly on the threshold")); + break; + case (int)MeasurementVisualizer.DistanceThresholdType.two: + EditorGUILayout.PropertyField(serializedObject.FindProperty("smallerThresholdDistance"), new GUIContent("Small threshold distance")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("biggerThresholdDistance"), new GUIContent("Big threshold distance")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("exactlyOnThresholdBehaviour"), new GUIContent("Distances exactly on the threshold")); + break; + default: + break; + } + + break; + case (int)MeasurementVisualizer2D.MeasurementType.distanceFromPointToLine: + Draw_positionSpecificationForPointAtThisGameobject("Point", true); + Draw_lineAsGeoObject2_definedByPartnerGameobject("Line", true, serializedObject.FindProperty("minimumLineLength_forDistancePointToLine")); + break; + case (int)MeasurementVisualizer2D.MeasurementType.angleBetweenVectors: + DrawAngleVectorsWithColor(); + EditorGUILayout.PropertyField(sP_angleUnitToDisplay, new GUIContent("Unit")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("addTextForAlternativeAngleUnit"), new GUIContent("Show also other angle unit (rad/deg)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("useReflexAngleOver180deg"), new GUIContent("Draw reflex angle over 180°")); + Draw_DrawPosition2DOffset_independentAlternativeValue(true, null, null, null, false); + break; + case (int)MeasurementVisualizer2D.MeasurementType.angleFromLineToLine: + Draw_lineAsGeoObject1_definedByThisGameobject("Line 1", serializedObject.FindProperty("minimumLineLength_forAngleLineToLine")); + Draw_lineAsGeoObject2_definedByPartnerGameobject("Line 2", false, serializedObject.FindProperty("minimumLineLength_forAngleLineToLine")); + EditorGUILayout.PropertyField(sP_angleUnitToDisplay, new GUIContent("Unit")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("addTextForAlternativeAngleUnit"), new GUIContent("Show also other angle unit (rad/deg)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("returnObtuseAngleOver90deg"), new GUIContent("Draw obtuse angle over 90°")); + break; + default: + break; + } + } + + void GeoSpecsBlock_start(string name) + { + GUIStyle style_ofHeadline = new GUIStyle(); + style_ofHeadline.fontStyle = FontStyle.Bold; + EditorGUILayout.LabelField(name, style_ofHeadline); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + } + + void GeoSpecsBlock_end(bool skipEmptyLineAtEnd) + { + if (skipEmptyLineAtEnd == false) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void Draw_specificationForTwoPoints(string nameOfFirstPoint, string nameOfSecondPoint, bool skipEmptyLineAtEnd, bool drawColorOfPoints) + { + Draw_positionSpecificationForPointAtThisGameobject(nameOfFirstPoint, drawColorOfPoints); + Draw_positionSpecificationForEndPointDefinedByPartnerGameobject(nameOfSecondPoint, skipEmptyLineAtEnd, drawColorOfPoints); + } + + void Draw_positionSpecificationForPointAtThisGameobject(string blockHeadline, bool drawColorOfPoint) + { + GeoSpecsBlock_start(blockHeadline); + if (drawColorOfPoint) { EditorGUILayout.PropertyField(serializedObject.FindProperty("color1"), new GUIContent("Color")); } + EditorGUILayout.LabelField("Position: This gameobject plus offset"); + Draw_DrawPosition2DOffset(true, "Additional offset"); + GeoSpecsBlock_end(false); + } + + void Draw_positionSpecificationForEndPointDefinedByPartnerGameobject(string blockHeadline, bool skipEmptyLineAtEnd, bool drawColorOfPoint) + { + GeoSpecsBlock_start(blockHeadline); + if (drawColorOfPoint) { EditorGUILayout.PropertyField(serializedObject.FindProperty("color2"), new GUIContent("Color")); } + EditorGUILayout.PropertyField(serializedObject.FindProperty("partnerGameobject"), new GUIContent("Position")); + Draw_DrawPosition2DOffset_ofPartnerGameobject(true, "Additional offset"); + GeoSpecsBlock_end(skipEmptyLineAtEnd); + } + + void Draw_lineAsGeoObject1_definedByThisGameobject(string blockHeadline, SerializedProperty optionalLineLengthField) + { + GeoSpecsBlock_start(blockHeadline); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color1"), new GUIContent("Color")); + EditorGUILayout.LabelField("Origin: This gameobject plus offset"); + Draw_DrawPosition2DOffset(true, "Additional offset for origin"); + DrawSpecificationOf_customVector2_3("Direction", false, null, true, false, false, false); + EditorGUILayout.PropertyField(serializedObject.FindProperty("name_ofGeoObject1"), new GUIContent("Drawn name tag")); + TryDrawLineLength(optionalLineLengthField); + GeoSpecsBlock_end(false); + } + + void Draw_lineAsGeoObject2_definedByPartnerGameobject(string blockHeadline, bool skipEmptyLineAtEnd, SerializedProperty optionalLineLengthField) + { + GeoSpecsBlock_start(blockHeadline); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color2"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("partnerGameobject"), new GUIContent("Origin position")); + EditorGUI.BeginDisabledGroup(visualizerParentMonoBehaviour_unserialized.partnerGameobject == null); + Draw_DrawPosition2DOffset_ofPartnerGameobject(true, "Additional offset for origin"); + DrawSpecificationOf_customVector2ofPartnerGameobject("Direction", false, null, true, false, false, false); + EditorGUILayout.PropertyField(serializedObject.FindProperty("name_ofGeoObject2"), new GUIContent("Drawn name tag")); + TryDrawLineLength(optionalLineLengthField); + EditorGUI.EndDisabledGroup(); + GeoSpecsBlock_end(skipEmptyLineAtEnd); + } + + void TryDrawLineLength(SerializedProperty optionalLineLengthField) + { + if (optionalLineLengthField != null) + { + EditorGUILayout.PropertyField(optionalLineLengthField, new GUIContent("Line Length", "The length of the line is at least so big that it spans to all measurement participants. It can be further prolonged via this field here.")); + } + } + + void DrawAngleVectorsWithColor() + { + DrawSpecificationOf_customVector2_1("Vector 1", false, null, true, false, false, false); + if (serializedObject.FindProperty("customVector2Configs.Array.data[0].picker_isOutfolded").boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("color1"), new GUIContent("Color")); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + DrawSpecificationOf_customVector2_2("Vector 2", false, null, true, false, false, true); + if (serializedObject.FindProperty("customVector2Configs.Array.data[1].picker_isOutfolded").boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("color2"), new GUIContent("Color")); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawAppearanceSection(SerializedProperty sP_measurementType, SerializedProperty sP_distanceThresholdType) + { + SerializedProperty sP_appearanceBlock_isOutfolded = serializedObject.FindProperty("appearanceBlock_isOutfolded"); + sP_appearanceBlock_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_appearanceBlock_isOutfolded.boolValue, "Appearance", true); + if (sP_appearanceBlock_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + string descriptionFor_enlargeSmallTextToThisMinTextSize = "Enlarge small text to this minimum textsize"; + switch (sP_measurementType.enumValueIndex) + { + case (int)MeasurementVisualizer2D.MeasurementType.distanceBetweenPoints: + Draw_coneConfig_insideFoldout_forStraightVectors(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"), new GUIContent(descriptionFor_enlargeSmallTextToThisMinTextSize)); + break; + case (int)MeasurementVisualizer2D.MeasurementType.distanceThresholdBetweenPoints: + switch (sP_distanceThresholdType.enumValueIndex) + { + case (int)MeasurementVisualizer.DistanceThresholdType.one: + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Short lines"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor_forNear_oneThresholdVersion"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteStyle_forNear"), new GUIContent("Style")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Long lines"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor_forFar_oneThresholdVersion"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteStyle_forFar"), new GUIContent("Style")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + break; + case (int)MeasurementVisualizer.DistanceThresholdType.two: + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Short lines"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor_forNear_twoThresholdsVersion"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteStyle_forNear"), new GUIContent("Style")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Middle lines"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor_forMiddle_twoThresholdsVersion"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteStyle_forMiddle"), new GUIContent("Style")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Long lines"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor_forFar_twoThresholdsVersion"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteStyle_forFar"), new GUIContent("Style")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + break; + default: + break; + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("displayDistanceAlsoAsText"), new GUIContent("Draw distance value")); + Draw_endPlatesConfig_insideFoldout(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"), new GUIContent(descriptionFor_enlargeSmallTextToThisMinTextSize)); + break; + case (int)MeasurementVisualizer2D.MeasurementType.distanceFromPointToLine: + Draw_coneConfig_insideFoldout_forStraightVectors(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"), new GUIContent(descriptionFor_enlargeSmallTextToThisMinTextSize)); + break; + case (int)MeasurementVisualizer2D.MeasurementType.angleBetweenVectors: + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawBoundaryLines"), new GUIContent("Draw boundary lines")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("forceRadius_value"), new GUIContent("Radius")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("pointerConfigOfAngleBetweenVectors"), new GUIContent("Pointers")); + Draw_coneLength_forCircledVectors(); + break; + case (int)MeasurementVisualizer2D.MeasurementType.angleFromLineToLine: + Draw_coneLength_forCircledVectors(); + break; + default: + break; + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesWidth"), new GUIContent("Lines width")); + if (sP_measurementType.enumValueIndex != (int)MeasurementVisualizer2D.MeasurementType.distanceThresholdBetweenPoints) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + } + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/MeasurementVisualizer2DInspector.cs.meta b/Editor/DrawDebugLibrary/MeasurementVisualizer2DInspector.cs.meta new file mode 100644 index 0000000..695e0fc --- /dev/null +++ b/Editor/DrawDebugLibrary/MeasurementVisualizer2DInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 994094d2c65cab14194c0282d3ae1263 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/MeasurementVisualizerInspector.cs b/Editor/DrawDebugLibrary/MeasurementVisualizerInspector.cs new file mode 100644 index 0000000..214fbbb --- /dev/null +++ b/Editor/DrawDebugLibrary/MeasurementVisualizerInspector.cs @@ -0,0 +1,423 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(MeasurementVisualizer))] + [CanEditMultipleObjects] + public class MeasurementVisualizerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("measurement"); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + SerializedProperty sP_measurementType = serializedObject.FindProperty("measurementType"); + SerializedProperty sP_angleUnitToDisplay = serializedObject.FindProperty("angleUnitToDisplay"); + SerializedProperty sP_distanceThresholdType = serializedObject.FindProperty("distanceThresholdType"); + + EditorGUILayout.PropertyField(sP_measurementType, new GUIContent("Measured quantity")); + DrawResult(sP_measurementType, sP_angleUnitToDisplay); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + Draw_geometrySpecification(sP_measurementType, sP_distanceThresholdType, sP_angleUnitToDisplay); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + DrawAppearanceSection(sP_measurementType, sP_distanceThresholdType); + DrawTextInputInclMarkupHelper(); + DrawCheckboxFor_drawOnlyIfSelected("measurement"); + DrawCheckboxFor_hiddenByNearerObjects("measurement"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawResult(SerializedProperty sP_measurementType, SerializedProperty sP_angleUnitToDisplay) + { + SerializedProperty sP_measuredResultValue = serializedObject.FindProperty("measuredResultValue"); + string result_nameString = ""; + switch (sP_measurementType.enumValueIndex) + { + case (int)MeasurementVisualizer.MeasurementType.distanceBetweenPoints: + result_nameString = Get_resultNameString_forDistance(); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceThresholdBetweenPoints: + break; + case (int)MeasurementVisualizer.MeasurementType.distanceFromPointToLine: + result_nameString = Get_resultNameString_forDistance(); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceFromLineToLine: + result_nameString = Get_resultNameString_forDistance(); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceFromPointToPlane: + result_nameString = Get_resultNameString_forDistance(); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceAlongOrthographicViewDir: + result_nameString = Get_resultNameString_forDistance(); + break; + case (int)MeasurementVisualizer.MeasurementType.distancePerpendicularToOrthographicViewDir: + result_nameString = Get_resultNameString_forDistance(); + break; + case (int)MeasurementVisualizer.MeasurementType.angleBetweenVectors: + result_nameString = Get_resultNameString_forAngle(sP_angleUnitToDisplay); + break; + case (int)MeasurementVisualizer.MeasurementType.angleFromLineToPlane: + result_nameString = Get_resultNameString_forAngle(sP_angleUnitToDisplay); + break; + case (int)MeasurementVisualizer.MeasurementType.angleFromPlaneToPlane: + result_nameString = Get_resultNameString_forAngle(sP_angleUnitToDisplay); + break; + default: + break; + } + + if (sP_measurementType.enumValueIndex != (int)MeasurementVisualizer.MeasurementType.distanceThresholdBetweenPoints) + { + EditorGUILayout.FloatField(new GUIContent(result_nameString, "read only"), sP_measuredResultValue.floatValue); + } + } + + public static string Get_resultNameString_forDistance() + { + return "Result (distance)"; + } + + public static string Get_resultNameString_forAngle(SerializedProperty sP_angleUnitToDisplay) + { + if (sP_angleUnitToDisplay.enumValueIndex == (int)MeasurementVisualizer.AngleUnit.degree) + { + return "Result (angle [deg])"; + } + else + { + return "Result (angle [rad])"; + } + } + + void Draw_geometrySpecification(SerializedProperty sP_measurementType, SerializedProperty sP_distanceThresholdType, SerializedProperty sP_angleUnitToDisplay) + { + switch (sP_measurementType.enumValueIndex) + { + case (int)MeasurementVisualizer.MeasurementType.distanceBetweenPoints: + Draw_specificationForTwoPoints("Start", "End", true, true); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceThresholdBetweenPoints: + Draw_specificationForTwoPoints("Start", "End", false, false); + EditorGUILayout.PropertyField(sP_distanceThresholdType, new GUIContent("Number of threshold distances")); + switch (sP_distanceThresholdType.enumValueIndex) + { + case (int)MeasurementVisualizer.DistanceThresholdType.one: + EditorGUILayout.PropertyField(serializedObject.FindProperty("smallerThresholdDistance"), new GUIContent("Threshold distance")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("exactlyOnThresholdBehaviour"), new GUIContent("Distances exactly on the threshold")); + break; + case (int)MeasurementVisualizer.DistanceThresholdType.two: + EditorGUILayout.PropertyField(serializedObject.FindProperty("smallerThresholdDistance"), new GUIContent("Small threshold distance")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("biggerThresholdDistance"), new GUIContent("Big threshold distance")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("exactlyOnThresholdBehaviour"), new GUIContent("Distances exactly on the threshold")); + break; + default: + break; + } + + break; + case (int)MeasurementVisualizer.MeasurementType.distanceFromPointToLine: + Draw_positionSpecificationForPointAtThisGameobject("Point", true); + Draw_lineAsGeoObject2_definedByPartnerGameobject("Line", true, serializedObject.FindProperty("minimumLineLength_forDistancePointToLine")); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceFromLineToLine: + Draw_lineAsGeoObject1_definedByThisGameobject("Line 1", serializedObject.FindProperty("minimumLineLength_forDistanceLineToLine")); + Draw_lineAsGeoObject2_definedByPartnerGameobject("Line 2", true, serializedObject.FindProperty("minimumLineLength_forDistanceLineToLine")); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceFromPointToPlane: + Draw_positionSpecificationForPointAtThisGameobject("Point", true); + Draw_planeAsGeoObject2_definedByPartnerGameobject("Plane", true); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceAlongOrthographicViewDir: + DrawSpecificationOf_customVector3_1_forDistanceInOrthogrphicViewDir(); + Draw_specificationForTwoPoints("Point 1", "Point 2", true, true); + break; + case (int)MeasurementVisualizer.MeasurementType.distancePerpendicularToOrthographicViewDir: + DrawSpecificationOf_customVector3_1_forDistanceInOrthogrphicViewDir(); + Draw_specificationForTwoPoints("Point 1", "Point 2", true, true); + break; + case (int)MeasurementVisualizer.MeasurementType.angleBetweenVectors: + DrawAngleVectorsWithColor(); + EditorGUILayout.PropertyField(sP_angleUnitToDisplay, new GUIContent("Unit")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("addTextForAlternativeAngleUnit"), new GUIContent("Show also other angle unit (rad/deg)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("useReflexAngleOver180deg"), new GUIContent("Draw reflex angle over 180°")); + Draw_DrawPosition3DOffset_independentAlternativeValue(true, null, null, null, false); + break; + case (int)MeasurementVisualizer.MeasurementType.angleFromLineToPlane: + Draw_lineAsGeoObject1_definedByThisGameobject("Line", serializedObject.FindProperty("minimumLineLength_forAngleLineToPlane")); + Draw_planeAsGeoObject2_definedByPartnerGameobject("Plane", false); + EditorGUILayout.PropertyField(sP_angleUnitToDisplay, new GUIContent("Unit")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("addTextForAlternativeAngleUnit"), new GUIContent("Show also other angle unit (rad/deg)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("returnObtuseAngleOver90deg"), new GUIContent("Draw obtuse angle over 90°")); + break; + case (int)MeasurementVisualizer.MeasurementType.angleFromPlaneToPlane: + Draw_planeAsGeoObject1_definedByThisGameobject("Plane 1"); + Draw_planeAsGeoObject2_definedByPartnerGameobject("Plane 2", false); + EditorGUILayout.PropertyField(sP_angleUnitToDisplay, new GUIContent("Unit")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("addTextForAlternativeAngleUnit"), new GUIContent("Show also other angle unit (rad/deg)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("returnObtuseAngleOver90deg"), new GUIContent("Draw obtuse angle over 90°")); + break; + default: + break; + } + } + + void GeoSpecsBlock_start(string name) + { + GUIStyle style_ofHeadline = new GUIStyle(); + style_ofHeadline.fontStyle = FontStyle.Bold; + EditorGUILayout.LabelField(name, style_ofHeadline); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + } + + void GeoSpecsBlock_end(bool skipEmptyLineAtEnd) + { + if (skipEmptyLineAtEnd == false) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void Draw_specificationForTwoPoints(string nameOfFirstPoint, string nameOfSecondPoint, bool skipEmptyLineAtEnd, bool drawColorOfPoints) + { + Draw_positionSpecificationForPointAtThisGameobject(nameOfFirstPoint, drawColorOfPoints); + Draw_positionSpecificationForEndPointDefinedByPartnerGameobject(nameOfSecondPoint, skipEmptyLineAtEnd, drawColorOfPoints); + } + + void Draw_positionSpecificationForPointAtThisGameobject(string blockHeadline, bool drawColorOfPoint) + { + GeoSpecsBlock_start(blockHeadline); + if (drawColorOfPoint) { EditorGUILayout.PropertyField(serializedObject.FindProperty("color1"), new GUIContent("Color")); } + EditorGUILayout.LabelField("Position: This gameobject plus offset"); + Draw_DrawPosition3DOffset(true, "Additional offset"); + GeoSpecsBlock_end(false); + } + + void Draw_positionSpecificationForEndPointDefinedByPartnerGameobject(string blockHeadline, bool skipEmptyLineAtEnd, bool drawColorOfPoint) + { + GeoSpecsBlock_start(blockHeadline); + if (drawColorOfPoint) { EditorGUILayout.PropertyField(serializedObject.FindProperty("color2"), new GUIContent("Color")); } + EditorGUILayout.PropertyField(serializedObject.FindProperty("partnerGameobject"), new GUIContent("Position")); + Draw_DrawPosition3DOffset_ofPartnerGameobject(true, "Additional offset"); + GeoSpecsBlock_end(skipEmptyLineAtEnd); + } + + void Draw_lineAsGeoObject1_definedByThisGameobject(string blockHeadline, SerializedProperty optionalLineLengthField) + { + Draw_lineOrPlaneAsGeoObject1_definedByThisGameobject(blockHeadline, "Direction", optionalLineLengthField); + } + + void Draw_planeAsGeoObject1_definedByThisGameobject(string blockHeadline) + { + Draw_lineOrPlaneAsGeoObject1_definedByThisGameobject(blockHeadline, "Normal", null); + } + + void Draw_lineOrPlaneAsGeoObject1_definedByThisGameobject(string blockHeadline, string meaningOfVector, SerializedProperty optionalLineLengthField) + { + GeoSpecsBlock_start(blockHeadline); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color1"), new GUIContent("Color")); + EditorGUILayout.LabelField("Origin: This gameobject plus offset"); + Draw_DrawPosition3DOffset(true, "Additional offset for origin"); + DrawSpecificationOf_customVector3_4(meaningOfVector, false, null, true, false, false, false); + EditorGUILayout.PropertyField(serializedObject.FindProperty("name_ofGeoObject1"), new GUIContent("Drawn name tag")); + TryDrawLineLength(optionalLineLengthField); + GeoSpecsBlock_end(false); + } + + void Draw_lineAsGeoObject2_definedByPartnerGameobject(string blockHeadline, bool skipEmptyLineAtEnd, SerializedProperty optionalLineLengthField) + { + Draw_lineOrPlaneAsGeoObject2_definedByPartnerGameobject(blockHeadline, "Direction", skipEmptyLineAtEnd, optionalLineLengthField); + } + + void Draw_planeAsGeoObject2_definedByPartnerGameobject(string blockHeadline, bool skipEmptyLineAtEnd) + { + Draw_lineOrPlaneAsGeoObject2_definedByPartnerGameobject(blockHeadline, "Normal", skipEmptyLineAtEnd, null); + } + + void Draw_lineOrPlaneAsGeoObject2_definedByPartnerGameobject(string blockHeadline, string meaningOfVector, bool skipEmptyLineAtEnd, SerializedProperty optionalLineLengthField) + { + GeoSpecsBlock_start(blockHeadline); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color2"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("partnerGameobject"), new GUIContent("Origin position")); + EditorGUI.BeginDisabledGroup(visualizerParentMonoBehaviour_unserialized.partnerGameobject == null); + Draw_DrawPosition3DOffset_ofPartnerGameobject(true, "Additional offset for origin"); + DrawSpecificationOf_customVector3ofPartnerGameobject(meaningOfVector, false, null, true, false, false, false); + EditorGUILayout.PropertyField(serializedObject.FindProperty("name_ofGeoObject2"), new GUIContent("Drawn name tag")); + TryDrawLineLength(optionalLineLengthField); + EditorGUI.EndDisabledGroup(); + GeoSpecsBlock_end(skipEmptyLineAtEnd); + } + + void TryDrawLineLength(SerializedProperty optionalLineLengthField) + { + if (optionalLineLengthField != null) + { + EditorGUILayout.PropertyField(optionalLineLengthField, new GUIContent("Line Length", "The length of the line is at least so big that it spans to all measurement participants. It can be further prolonged via this field here.")); + } + } + + void DrawSpecificationOf_customVector3_1_forDistanceInOrthogrphicViewDir() + { + DrawSpecificationOf_customVector3_1("View direction", false, null, true, false, true, false); + } + + void DrawAngleVectorsWithColor() + { + DrawSpecificationOf_customVector3_2("Vector 1", false, null, true, false, false, false); + if (serializedObject.FindProperty("customVector3Configs.Array.data[1].picker_isOutfolded").boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("color1"), new GUIContent("Color")); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + DrawSpecificationOf_customVector3_3("Vector 2", false, null, true, false, false, true); + if (serializedObject.FindProperty("customVector3Configs.Array.data[2].picker_isOutfolded").boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("color2"), new GUIContent("Color")); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawAppearanceSection(SerializedProperty sP_measurementType, SerializedProperty sP_distanceThresholdType) + { + SerializedProperty sP_appearanceBlock_isOutfolded = serializedObject.FindProperty("appearanceBlock_isOutfolded"); + sP_appearanceBlock_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_appearanceBlock_isOutfolded.boolValue, "Appearance", true); + if (sP_appearanceBlock_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + string descriptionFor_enlargeSmallTextToThisMinTextSize = "Enlarge small text to this minimum textsize"; + switch (sP_measurementType.enumValueIndex) + { + case (int)MeasurementVisualizer.MeasurementType.distanceBetweenPoints: + Draw_coneConfig_insideFoldout_forStraightVectors(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"), new GUIContent(descriptionFor_enlargeSmallTextToThisMinTextSize)); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceThresholdBetweenPoints: + switch (sP_distanceThresholdType.enumValueIndex) + { + case (int)MeasurementVisualizer.DistanceThresholdType.one: + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Short lines"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor_forNear_oneThresholdVersion"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteStyle_forNear"), new GUIContent("Style")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Long lines"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor_forFar_oneThresholdVersion"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteStyle_forFar"), new GUIContent("Style")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + break; + case (int)MeasurementVisualizer.DistanceThresholdType.two: + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Short lines"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor_forNear_twoThresholdsVersion"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteStyle_forNear"), new GUIContent("Style")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Middle lines"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor_forMiddle_twoThresholdsVersion"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteStyle_forMiddle"), new GUIContent("Style")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.LabelField("Long lines"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor_forFar_twoThresholdsVersion"), new GUIContent("Color")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteStyle_forFar"), new GUIContent("Style")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + break; + default: + break; + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("displayDistanceAlsoAsText"), new GUIContent("Draw distance value")); + Draw_endPlatesConfig_insideFoldout(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"), new GUIContent(descriptionFor_enlargeSmallTextToThisMinTextSize)); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceFromPointToLine: + Draw_coneConfig_insideFoldout_forStraightVectors(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"), new GUIContent(descriptionFor_enlargeSmallTextToThisMinTextSize)); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceFromLineToLine: + Draw_coneConfig_insideFoldout_forStraightVectors(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"), new GUIContent(descriptionFor_enlargeSmallTextToThisMinTextSize)); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceFromPointToPlane: + Draw_coneConfig_insideFoldout_forStraightVectors(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"), new GUIContent(descriptionFor_enlargeSmallTextToThisMinTextSize)); + break; + case (int)MeasurementVisualizer.MeasurementType.distanceAlongOrthographicViewDir: + Draw_coneConfig_insideFoldout_forStraightVectors(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"), new GUIContent(descriptionFor_enlargeSmallTextToThisMinTextSize)); + break; + case (int)MeasurementVisualizer.MeasurementType.distancePerpendicularToOrthographicViewDir: + Draw_coneConfig_insideFoldout_forStraightVectors(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enlargeSmallTextToThisMinTextSize"), new GUIContent(descriptionFor_enlargeSmallTextToThisMinTextSize)); + break; + case (int)MeasurementVisualizer.MeasurementType.angleBetweenVectors: + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawBoundaryLines"), new GUIContent("Draw boundary lines")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("forceRadius_value"), new GUIContent("Radius")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("pointerConfigOfAngleBetweenVectors"), new GUIContent("Pointers")); + Draw_coneLength_forCircledVectors(); + break; + case (int)MeasurementVisualizer.MeasurementType.angleFromLineToPlane: + Draw_coneLength_forCircledVectors(); + break; + case (int)MeasurementVisualizer.MeasurementType.angleFromPlaneToPlane: + Draw_coneLength_forCircledVectors(); + break; + default: + break; + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesWidth"), new GUIContent("Lines width")); + if (sP_measurementType.enumValueIndex != (int)MeasurementVisualizer.MeasurementType.distanceThresholdBetweenPoints) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + } + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/MeasurementVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/MeasurementVisualizerInspector.cs.meta new file mode 100644 index 0000000..f7c8cc3 --- /dev/null +++ b/Editor/DrawDebugLibrary/MeasurementVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe6531c0e5aca324bb0d0d77aaca4d77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/PhysicsVisualizer2DInspector.cs b/Editor/DrawDebugLibrary/PhysicsVisualizer2DInspector.cs new file mode 100644 index 0000000..d31fece --- /dev/null +++ b/Editor/DrawDebugLibrary/PhysicsVisualizer2DInspector.cs @@ -0,0 +1,586 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(PhysicsVisualizer2D))] + [CanEditMultipleObjects] + public class PhysicsVisualizer2DInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("physics2D"); + SerializedProperty sP_saveDrawnLinesType = serializedObject.FindProperty("saveDrawnLinesType"); + EditorGUILayout.PropertyField(sP_saveDrawnLinesType, new GUIContent("Save drawn lines ?", "This simplifies the visualization. It may be helpful to save performance if you draw many casts at once." + Environment.NewLine + Environment.NewLine + "You can change the initial value of this via 'DrawXXL.DrawPhysics2D.visualizationQuality'.")); + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + bool typeIsCast_notOverlap = false; + SerializedProperty sP_theGameobjectHasACompatibleAndEnabledCollider = serializedObject.FindProperty("theGameobjectHasACompatibleAndEnabledCollider"); + SerializedProperty sP_shape = serializedObject.FindProperty("shape"); + + TryDrawCollisionTypeChooser(sP_shape, sP_theGameobjectHasACompatibleAndEnabledCollider, ref typeIsCast_notOverlap); + + if ((sP_shape.enumValueIndex == (int)PhysicsVisualizer2D.Shape.collidersOnThisGameobject) && (sP_theGameobjectHasACompatibleAndEnabledCollider.boolValue == false)) + { + EditorGUILayout.HelpBox("There is no enabled collider on this gameobject that could be cast. Supported colliders are 'BoxCollider2D', 'CircleCollider2D' and 'CapsuleCollider2D'.", MessageType.None, true); + } + else + { + SerializedProperty sP_wantedHits = serializedObject.FindProperty("wantedHits"); + EditorGUILayout.PropertyField(sP_wantedHits, new GUIContent("Wanted hits")); + DrawDetectedHitsCount(); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + DrawShapeSizeSpecification(sP_shape); + DrawCastDirectionAndDistance(sP_shape, typeIsCast_notOverlap); + DrawOtherSettings(sP_shape, sP_wantedHits, sP_saveDrawnLinesType, typeIsCast_notOverlap); + DrawTextSpecs(sP_saveDrawnLinesType, typeIsCast_notOverlap); + DrawCheckboxFor_drawOnlyIfSelected("physics2D"); + DrawCheckboxFor_hiddenByNearerObjects("physics2D"); + } + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void TryDrawCollisionTypeChooser(SerializedProperty sP_shape, SerializedProperty sP_theGameobjectHasACompatibleAndEnabledCollider, ref bool typeIsCast_notOverlap) + { + SerializedProperty sP_collisionType = serializedObject.FindProperty("collisionType"); + + bool forceDisplayToCast = false; + switch ((PhysicsVisualizer2D.Shape)sP_shape.enumValueIndex) + { + case PhysicsVisualizer2D.Shape.collidersOnThisGameobject: + if (sP_theGameobjectHasACompatibleAndEnabledCollider.boolValue) + { + forceDisplayToCast = false; + typeIsCast_notOverlap = Get_typeIsCast_notOverlap(sP_collisionType, forceDisplayToCast); + } + break; + case PhysicsVisualizer2D.Shape.box: + forceDisplayToCast = false; + typeIsCast_notOverlap = Get_typeIsCast_notOverlap(sP_collisionType, forceDisplayToCast); + break; + case PhysicsVisualizer2D.Shape.circle: + forceDisplayToCast = false; + typeIsCast_notOverlap = Get_typeIsCast_notOverlap(sP_collisionType, forceDisplayToCast); + break; + case PhysicsVisualizer2D.Shape.capsule: + forceDisplayToCast = false; + typeIsCast_notOverlap = Get_typeIsCast_notOverlap(sP_collisionType, forceDisplayToCast); + break; + case PhysicsVisualizer2D.Shape.rayOrPoint: + forceDisplayToCast = false; + typeIsCast_notOverlap = Get_typeIsCast_notOverlap(sP_collisionType, forceDisplayToCast); + break; + case PhysicsVisualizer2D.Shape.ray3D: + forceDisplayToCast = true; + typeIsCast_notOverlap = Get_typeIsCast_notOverlap(sP_collisionType, forceDisplayToCast); + break; + default: + break; + } + + string label_ofShape = typeIsCast_notOverlap ? "Shape to cast" : "Shape to overlap"; + EditorGUILayout.PropertyField(sP_shape, new GUIContent(label_ofShape)); + + switch ((PhysicsVisualizer2D.Shape)sP_shape.enumValueIndex) + { + case PhysicsVisualizer2D.Shape.collidersOnThisGameobject: + if (sP_theGameobjectHasACompatibleAndEnabledCollider.boolValue) + { + if (UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale_2D(transform_onVisualizerObject.parent)) + { + EditorGUILayout.HelpBox("A parent transform has a non-uniform scale -> The collider and cast positions may be wrong.", MessageType.Warning, true); + } + + if (UtilitiesDXXL_EngineBasics.CheckIfThisOrAParentHasANonZRotation_2D(transform_onVisualizerObject)) + { + EditorGUILayout.HelpBox("This transform or a parent has a non-z rotation. -> The collider and cast positions may be wrong.", MessageType.Warning, true); + } + + if (serializedObject.FindProperty("aVisualizedBoxCollider2DOnThisComponent_hasANonZeroEdge").boolValue) + { + EditorGUILayout.HelpBox("A visualized BoxCollider2D component uses 'edge radius'. Casting rounded boxes is not supported." + Environment.NewLine + "-> Fallback to casting the box without the rounded edge.", MessageType.Warning, true); + } + + if (serializedObject.FindProperty("aVisualizedBoxCollider2DOnThisComponent_hasAutoTiling").boolValue) + { + EditorGUILayout.HelpBox("A visualized BoxCollider2D component uses 'Auto Tiling'. The visualisation of this is not supported.", MessageType.Warning, true); + } + + DrawCollisionTypeChooser(sP_collisionType, false); + } + break; + case PhysicsVisualizer2D.Shape.box: + DrawCollisionTypeChooser(sP_collisionType, false); + break; + case PhysicsVisualizer2D.Shape.circle: + DrawCollisionTypeChooser(sP_collisionType, false); + break; + case PhysicsVisualizer2D.Shape.capsule: + DrawCollisionTypeChooser(sP_collisionType, false); + break; + case PhysicsVisualizer2D.Shape.rayOrPoint: + DrawCollisionTypeChooser(sP_collisionType, false); + break; + case PhysicsVisualizer2D.Shape.ray3D: + DrawCollisionTypeChooser(sP_collisionType, true); + break; + default: + break; + } + } + + bool Get_typeIsCast_notOverlap(SerializedProperty sP_collisionType, bool forceDisplayToCast) + { + if (forceDisplayToCast) + { + return true; + } + else + { + return (sP_collisionType.enumValueIndex == (int)CollisionType.cast); + } + } + + void DrawCollisionTypeChooser(SerializedProperty sP_collisionType, bool forceDisplayToCast) + { + string label = "Collision type"; + if (forceDisplayToCast) + { + CollisionType castCollisionType = CollisionType.cast; + + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.EnumPopup(new GUIContent(label), castCollisionType); + EditorGUI.EndDisabledGroup(); + } + else + { + EditorGUILayout.PropertyField(sP_collisionType, new GUIContent(label)); + } + } + + void DrawDetectedHitsCount() + { + int numberOfDetectedHits = serializedObject.FindProperty("numberOfFoundHits").intValue; + Color displayColor = (numberOfDetectedHits == 0) ? serializedObject.FindProperty("colorForNonHittingCasts").colorValue : serializedObject.FindProperty("colorForHittingCasts").colorValue; + string labelText_name = "Detected hits:"; //-> I wanted to color this as well, but rich text seems to work only for the second label + string labelText_value = ("" + numberOfDetectedHits + ""); + GUIStyle style = new GUIStyle(EditorStyles.label); + style.richText = true; + EditorGUILayout.LabelField(labelText_name, labelText_value, style); + } + + void DrawShapeSizeSpecification(SerializedProperty sP_shape) + { + if ((sP_shape.enumValueIndex == (int)PhysicsVisualizer2D.Shape.box) || (sP_shape.enumValueIndex == (int)PhysicsVisualizer2D.Shape.circle) || (sP_shape.enumValueIndex == (int)PhysicsVisualizer2D.Shape.capsule)) + { + GUIStyle richtextEnabledStyle = new GUIStyle(EditorStyles.label); + richtextEnabledStyle.richText = true; + + switch ((PhysicsVisualizer2D.Shape)sP_shape.enumValueIndex) + { + case PhysicsVisualizer2D.Shape.collidersOnThisGameobject: + break; + case PhysicsVisualizer2D.Shape.box: + EditorGUILayout.LabelField("Box: --- Size / Orientation / Position ---", richtextEnabledStyle); + break; + case PhysicsVisualizer2D.Shape.circle: + EditorGUILayout.LabelField("Circle: --- Size / Position ---", richtextEnabledStyle); + break; + case PhysicsVisualizer2D.Shape.capsule: + EditorGUILayout.LabelField("Capsule: --- Size / Orientation / Position ---", richtextEnabledStyle); + break; + case PhysicsVisualizer2D.Shape.rayOrPoint: + break; + case PhysicsVisualizer2D.Shape.ray3D: + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + switch ((PhysicsVisualizer2D.Shape)sP_shape.enumValueIndex) + { + case PhysicsVisualizer2D.Shape.collidersOnThisGameobject: + break; + case PhysicsVisualizer2D.Shape.box: + EditorGUILayout.PropertyField(serializedObject.FindProperty("sizeScaleFactors_ofCastRespCheckedBox"), new GUIContent("Size")); + DrawShapeRotation(); + Draw_DrawPosition2DOffset(true, "Position Offset"); + DrawZPosChooserFor2D(true); + break; + case PhysicsVisualizer2D.Shape.circle: + EditorGUILayout.PropertyField(serializedObject.FindProperty("radiusScaleFactor_ofCastRespCheckedCircle"), new GUIContent("Radius")); + Draw_DrawPosition2DOffset(true, "Position Offset"); + DrawZPosChooserFor2D(true); + break; + case PhysicsVisualizer2D.Shape.capsule: + EditorGUILayout.PropertyField(serializedObject.FindProperty("sizeScaleFactors_ofCastRespCheckedCapsule"), new GUIContent("Size")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("capsuleDirection2D_ofManuallyConstructedCapsuleMeaningNotFromCollider"), new GUIContent("Capsule Expansion")); + DrawShapeRotation(); + Draw_DrawPosition2DOffset(true, "Position Offset"); + DrawZPosChooserFor2D(true); + break; + case PhysicsVisualizer2D.Shape.rayOrPoint: + break; + case PhysicsVisualizer2D.Shape.ray3D: + break; + default: + break; + } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + else + { + if (sP_shape.enumValueIndex == (int)PhysicsVisualizer2D.Shape.rayOrPoint) + { + Draw_DrawPosition2DOffset(false, "Position Offset"); + DrawZPosChooserFor2D(); + } + + if (sP_shape.enumValueIndex == (int)PhysicsVisualizer2D.Shape.ray3D) + { + Draw_DrawPosition3DOffset(false, "Position Offset"); + DrawZPosChooserFor2D(); + } + } + } + + void DrawShapeRotation() + { + SerializedProperty sP_shapeRotationType = serializedObject.FindProperty("shapeRotationType"); + EditorGUILayout.PropertyField(sP_shapeRotationType, new GUIContent("Rotation")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + switch (sP_shapeRotationType.enumValueIndex) + { + case (int)PhysicsVisualizer2D.ShapeRotationType.transformsRotationPlusOptionalAdditionalRotation: + EditorGUILayout.PropertyField(serializedObject.FindProperty("rotationAngleOfShape_additionallyToTransformsAngle"), new GUIContent("Additional rotation", "The rotation is taken from the transforms z rotation. This value is added onto this.")); + break; + case (int)PhysicsVisualizer2D.ShapeRotationType.customRotationIndependentFromTransform: + EditorGUILayout.PropertyField(serializedObject.FindProperty("rotationAngleOfShape_additionallyToTransformsAngle"), new GUIContent("Custom rotation")); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + void DrawCastDirectionAndDistance(SerializedProperty sP_shape, bool typeIsCast_notOverlap) + { + if (typeIsCast_notOverlap) + { + if (sP_shape.enumValueIndex == (int)PhysicsVisualizer2D.Shape.ray3D) + { + DrawSpecificationOf_customVector3_1("Cast direction", false, null, true, false, true, false); + } + else + { + DrawSpecificationOf_customVector2_1("Cast direction", false, null, true, false, true, false); + } + + EditorGUILayout.LabelField("Cast distance"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + SerializedProperty sP_distanceIsInfinityRespToOtherGO = serializedObject.FindProperty("distanceIsInfinityRespToOtherGO"); + + if (sP_shape.enumValueIndex == (int)PhysicsVisualizer2D.Shape.ray3D) + { + if (visualizerParentMonoBehaviour_unserialized.customVector3Configs[0].source == VisualizerParent.CustomVector3Source.toOtherGameobject) + { + EditorGUILayout.PropertyField(sP_distanceIsInfinityRespToOtherGO, new GUIContent("Till other gameobject")); + } + else + { + EditorGUILayout.PropertyField(sP_distanceIsInfinityRespToOtherGO, new GUIContent("Infinity")); + } + } + else + { + if (visualizerParentMonoBehaviour_unserialized.customVector2Configs[0].source == VisualizerParent.CustomVector2Source.toOtherGameobject) + { + EditorGUILayout.PropertyField(sP_distanceIsInfinityRespToOtherGO, new GUIContent("Till other gameobject")); + } + else + { + EditorGUILayout.PropertyField(sP_distanceIsInfinityRespToOtherGO, new GUIContent("Infinity")); + } + } + + EditorGUI.BeginDisabledGroup(sP_distanceIsInfinityRespToOtherGO.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("adjustedDistance"), new GUIContent("Flexible")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + void DrawOtherSettings(SerializedProperty sP_shape, SerializedProperty sP_wantedHits, SerializedProperty sP_saveDrawnLinesType, bool typeIsCast_notOverlap) + { + SerializedProperty sP_otherSettings_isFoldedOut = serializedObject.FindProperty("otherSettings_isFoldedOut"); + sP_otherSettings_isFoldedOut.boolValue = EditorGUILayout.Foldout(sP_otherSettings_isFoldedOut.boolValue, "Other settings", true); + if (sP_otherSettings_isFoldedOut.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUILayout.PropertyField(serializedObject.FindProperty("excludeCollidersOnThisGO"), new GUIContent("Exclude colliders on this Gameobject from result", "Caution for disabling this:" + Environment.NewLine + "In many cases the colliders on this Gameobject will overlap with the starting position of the cast shapes. In these cases a collision will be detected, but the position and hit distance may be wrong.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("excludeCollidersOnParentGOs"), new GUIContent("Exclude colliders on parents from result", "Caution for disabling this:" + Environment.NewLine + "In many cases the colliders on the parents will overlap with the starting position of the cast shapes. In these cases a collision will be detected, but the position and hit distance may be wrong.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("excludeCollidersOnChildrenGOs"), new GUIContent("Exclude colliders on children from result", "Caution for disabling this:" + Environment.NewLine + "In many cases the colliders on the children will overlap with the starting position of the cast shapes. In these cases a collision will be detected, but the position and hit distance may be wrong.")); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("layerMask"), new GUIContent("Colliding layers", "The collision check considers only colliders that are part of the herewith selected layers." + Environment.NewLine + Environment.NewLine + "For more details see Unitys documentation of the 'layerMask' parameter inside the 'UnityEngine.Physics2D.*' functions documentation.")); + + bool castShape_isRay3D = (sP_shape.enumValueIndex == (int)PhysicsVisualizer2D.Shape.ray3D); + bool wantedHits_isAll = (sP_wantedHits.enumValueIndex == (int)WantedHits.all); + + //depth restriction: + SerializedProperty sP_useDepth = serializedObject.FindProperty("useDepth"); + + EditorGUI.BeginDisabledGroup(castShape_isRay3D); + EditorGUILayout.PropertyField(sP_useDepth, new GUIContent("Restrict Z range", "When using this the collision results will only include Collider2D who have their Z coordinate inside the specified range." + Environment.NewLine + Environment.NewLine + "This is not available for 'Shape' of 'Ray 3D'." + Environment.NewLine + Environment.NewLine + "For more details see Unitys documentation of 'ContactFilter2D'.")); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUI.BeginDisabledGroup(sP_useDepth.boolValue == false); + EditorGUILayout.PropertyField(serializedObject.FindProperty("minDepth"), new GUIContent("Minimum Z")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("maxDepth"), new GUIContent("Maximum Z")); + + EditorGUI.BeginDisabledGroup(wantedHits_isAll == false); + EditorGUILayout.PropertyField(serializedObject.FindProperty("useOutsideDepth"), new GUIContent("Restrict to OUTSIDE", "Restrict the collisions to the area outside of the range, instead of to area inside the range." + Environment.NewLine + Environment.NewLine + "This is only available if 'Wanted hits' is set to 'All'. And it is not available for 'Shape' of 'Ray 3D'.")); + EditorGUI.EndDisabledGroup(); + + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + EditorGUI.EndDisabledGroup(); + + //normal angle restriction: + SerializedProperty sP_useNormalAngle = serializedObject.FindProperty("useNormalAngle"); + EditorGUI.BeginDisabledGroup(castShape_isRay3D || (typeIsCast_notOverlap == false) || (wantedHits_isAll == false)); + EditorGUILayout.PropertyField(sP_useNormalAngle, new GUIContent("Restrict by normal angle", "This restricts the result to collisons whose collision normal points into a direction that lies inside the specified angle segment. The angle segment is defined in global space and independent of the cast direction. An angle of 0 means 'towards global right' (positive x-axis). Higher angles are turned counter clockwise from there." + Environment.NewLine + Environment.NewLine + "This is only available for casts with 'Wanted hits' set to 'All'. And it is not available for 'Shape' of 'Ray 3D' and not for colliders that are configurated as triggers and not for overlap checks." + Environment.NewLine + Environment.NewLine + "For more details see Unitys documentation of 'ContactFilter2D'.")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUI.BeginDisabledGroup(sP_useNormalAngle.boolValue == false); + + SerializedProperty sP_minNormalAngle = serializedObject.FindProperty("minNormalAngle"); + SerializedProperty sP_maxNormalAngle = serializedObject.FindProperty("maxNormalAngle"); + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(sP_minNormalAngle, new GUIContent("Minimum normal angle", "The start of the segment that defines the allowed normal angles (in degrees). It is measured in global space counter clockwise from 'towards right' (positive x-axis)")); + bool minNormalAngle_changed = EditorGUI.EndChangeCheck(); + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(sP_maxNormalAngle, new GUIContent("Maximum normal angle", "The end of the segment that defines the allowed normal angles (in degrees). It is measured in global space counter clockwise from 'towards right' (positive x-axis)")); + bool maxNormalAngle_changed = EditorGUI.EndChangeCheck(); + + if (minNormalAngle_changed) + { + sP_maxNormalAngle.floatValue = Mathf.Max(sP_minNormalAngle.floatValue, sP_maxNormalAngle.floatValue); + } + else + { + if (maxNormalAngle_changed) + { + sP_minNormalAngle.floatValue = Mathf.Min(sP_minNormalAngle.floatValue, sP_maxNormalAngle.floatValue); + } + } + + // The angle range via only single slider, that displays a span: + // (disadvantage: it doesn't display the values as numbers) + // float minNormalAngle = sP_minNormalAngle.floatValue; + // float maxNormalAngle = sP_maxNormalAngle.floatValue; + // EditorGUILayout.MinMaxSlider("Angle Segment (0°-360°)",ref minNormalAngle, ref maxNormalAngle, 0.0f, 360.0f); + // sP_minNormalAngle.floatValue = minNormalAngle; + // sP_maxNormalAngle.floatValue = maxNormalAngle; + + EditorGUILayout.PropertyField(serializedObject.FindProperty("useOutsideNormalAngle"), new GUIContent("Restrict to OUTSIDE", "Restrict the collisions to the normal angles outside of the defined segment, instead of to the angles inside the segment.")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + EditorGUI.EndDisabledGroup(); + + //others: + EditorGUI.BeginDisabledGroup(castShape_isRay3D || (wantedHits_isAll == false)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("useTriggers"), new GUIContent("Collide with triggers", "Specifies wheather the collision check also interacts with colliders that are configured as triggers." + Environment.NewLine + " Note that the restiction of 'normal angles' doesn't work on triggers." + Environment.NewLine + Environment.NewLine + "This is only available if 'Wanted hits' is set to 'All'. And it is not available for 'Shape' of 'Ray 3D'.")); + EditorGUI.EndDisabledGroup(); + + string displayNameOfColorForNonHittingChecks; + string displayNameOfColorForHittingChecks; + if (typeIsCast_notOverlap) + { + displayNameOfColorForNonHittingChecks = "Non hitting rays"; + displayNameOfColorForHittingChecks = "Hitting rays"; + } + else + { + displayNameOfColorForNonHittingChecks = "Not Overlapping"; + displayNameOfColorForHittingChecks = "Overlapping"; + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForNonHittingCasts"), new GUIContent(displayNameOfColorForNonHittingChecks, "You can change the initial value of this via 'DrawXXL.DrawPhysics2D.colorForNonHittingCasts'.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForHittingCasts"), new GUIContent(displayNameOfColorForHittingChecks, "You can change the initial value of this via 'DrawXXL.DrawPhysics2D.colorForHittingCasts'.")); + + if (typeIsCast_notOverlap) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForCastLineBeyondHit"), new GUIContent("After last hit", "You can change the initial value of this via 'DrawXXL.DrawPhysics2D.colorForCastLineBeyondHit'.")); + DrawChooserLineFor_overwriteColorForCastsHitNormals(); + Draw_castCorridorVisualizerDensity(sP_saveDrawnLinesType); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + void DrawChooserLineFor_overwriteColorForCastsHitNormals() + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("doOverwriteColorForCastsHitNormals"), new GUIContent("Custom Hit Normal Color", "The default color for normals at collision positions is that 'Color of hitting rays' is used, but with an adjusted brightness. Though you can overwrite the color of the normal here.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColorForCastsHitNormals"), GUIContent.none); + EditorGUILayout.EndHorizontal(); + } + + void Draw_castCorridorVisualizerDensity(SerializedProperty sP_saveDrawnLinesType) + { + if (sP_saveDrawnLinesType.enumValueIndex == (int)PhysicsVisualizer.SaveDrawnLinesType.yes_displayWithLowDetails) + { + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.PropertyField(serializedObject.FindProperty("castCorridorVisualizerDensity"), new GUIContent("Density (of cast corridor visualizers)", "Not available in 'save drawn lines' mode.")); + EditorGUI.EndDisabledGroup(); + } + else + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("castCorridorVisualizerDensity"), new GUIContent("Density (of cast corridor visualizers)", "You can change the initial value of this via 'DrawXXL.DrawPhysics2D.castCorridorVisualizerDensity'." + Environment.NewLine + Environment.NewLine + "If you reached a limit and no new corridor visualizers appear you can raise the maximum value via 'DrawXXL.DrawPhysics2D.maxCorridorVisualizersPerCastVisualization'.")); + } + } + + public void DrawTextSpecs(SerializedProperty sP_saveDrawnLinesType, bool typeIsCast_notOverlap) + { + if (sP_saveDrawnLinesType.enumValueIndex == (int)PhysicsVisualizer.SaveDrawnLinesType.yes_displayWithLowDetails) + { + EditorGUI.BeginDisabledGroup(true); + GUIStyle style_forFoldoutLine = new GUIStyle(EditorStyles.foldout); + EditorGUILayout.Foldout(false, new GUIContent("Text", "Not available in 'save drawn lines' mode."), false, style_forFoldoutLine); + EditorGUI.EndDisabledGroup(); + } + else + { + //-> this fakes the appearance of beeing inside the parents text specification foldout + bool emptyLineAtEndIfOutfolded = false; + DrawTextInputInclMarkupHelper(true, false, null, emptyLineAtEndIfOutfolded); + + if (serializedObject.FindProperty("textSection_isOutfolded").boolValue == true) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + if (typeIsCast_notOverlap) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawCastNameTag_atCastOrigin"), new GUIContent("Draw text tag at cast origin", "You can change the initial value of this via 'DrawXXL.DrawPhysics2D.drawCastNameTag_atCastOrigin'.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawCastNameTag_atHitPositions"), new GUIContent("Draw text tag at hit positions", "You can change the initial value of this via 'DrawXXL.DrawPhysics2D.drawCastNameTag_atHitPositions'.")); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForCastsHitText"), new GUIContent("Hit description color", "You can change the initial value of this via 'DrawXXL.DrawPhysics2D.colorForCastsHitText'.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("scaleFactor_forCastHitTextSize"), new GUIContent("Text size of hit descriptions", "You can change the initial value of this via 'DrawXXL.DrawPhysics2D.scaleFactor_forCastHitTextSize'.")); + DrawChooserFor_useCustomDirectionForHitResultText(sP_saveDrawnLinesType); + } + else + { + SerializedProperty sP_overlapResultTextSizeInterpretation = serializedObject.FindProperty("overlapResultTextSizeInterpretation"); + EditorGUILayout.PropertyField(sP_overlapResultTextSizeInterpretation, new GUIContent("Text Size Reference Frame")); + + switch (sP_overlapResultTextSizeInterpretation.enumValueIndex) + { + case (int)PhysicsVisualizer.OverlapResultTextSizeInterpretation.relativeToTheSizeOfTheOverlapingPhysicsShape: + break; + case (int)PhysicsVisualizer.OverlapResultTextSizeInterpretation.fixedWorldSpaceSize: + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("forcedConstantWorldspaceTextSize_forOverlapResultTexts"), new GUIContent("Text size")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + case (int)PhysicsVisualizer.OverlapResultTextSizeInterpretation.relativeToTheSceneViewWindowSize: + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts"), new GUIContent("Text size")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + case (int)PhysicsVisualizer.OverlapResultTextSizeInterpretation.relativeToTheGameViewWindowSize: + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts"), new GUIContent("Text size")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + default: + break; + } + + SerializedProperty sP_maxListedColliders_inOverlapVolumesTextList = serializedObject.FindProperty("maxListedColliders_inOverlapVolumesTextList"); + EditorGUILayout.PropertyField(sP_maxListedColliders_inOverlapVolumesTextList, new GUIContent("Maximum listed colliders in results text list", "The results list will be truncated if there are more results, along with a notification how many results are hidden." + Environment.NewLine + Environment.NewLine + "You can set the initial value of this via 'DrawPhysics2D.MaxListedColliders_inOverlapVolumesTextList'.")); + sP_maxListedColliders_inOverlapVolumesTextList.intValue = Mathf.Max(1, sP_maxListedColliders_inOverlapVolumesTextList.intValue); + + SerializedProperty sP_maxOverlapingCollidersWithUntruncatedText = serializedObject.FindProperty("maxOverlapingCollidersWithUntruncatedText"); + if (sP_saveDrawnLinesType.enumValueIndex == (int)PhysicsVisualizer.SaveDrawnLinesType.no_useFullDetails) + { + EditorGUILayout.PropertyField(sP_maxOverlapingCollidersWithUntruncatedText, new GUIContent("Maximum collision markers with untruncated text", "If more collisions than this number are found then the description text at the collision position marker will be truncated to only a sequential number." + Environment.NewLine + Environment.NewLine + "You can set the initial value of this via 'DrawPhysics2D.maxOverlapingCollidersWithUntruncatedText'.")); + } + else + { + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.PropertyField(sP_maxOverlapingCollidersWithUntruncatedText, new GUIContent("Maximum collision markers with untruncated text", "Only available if 'save drawn lines' is disabled.")); + EditorGUI.EndDisabledGroup(); + } + sP_maxOverlapingCollidersWithUntruncatedText.intValue = Mathf.Max(0, sP_maxOverlapingCollidersWithUntruncatedText.intValue); + + } + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + } + + void DrawChooserFor_useCustomDirectionForHitResultText(SerializedProperty sP_saveDrawnLinesType) + { + if (sP_saveDrawnLinesType.enumValueIndex == (int)PhysicsVisualizer.SaveDrawnLinesType.no_useFullDetails) + { + SerializedProperty sP_useCustomDirectionForHitResultText = serializedObject.FindProperty("useCustomDirectionForHitResultText"); + EditorGUILayout.BeginHorizontal(); + + EditorGUILayout.PropertyField(sP_useCustomDirectionForHitResultText, new GUIContent("Custom placement of hit description block", "You can change the initial value of this via 'DrawPhysics2D.directionOfHitResultText'.")); + + EditorGUI.BeginDisabledGroup(!sP_useCustomDirectionForHitResultText.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("customDirectionForHitResultText"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.EndHorizontal(); + } + else + { + EditorGUI.BeginDisabledGroup(true); + + SerializedProperty sP_useCustomDirectionForHitResultText = serializedObject.FindProperty("useCustomDirectionForHitResultText"); + EditorGUILayout.BeginHorizontal(); + + EditorGUILayout.PropertyField(sP_useCustomDirectionForHitResultText, new GUIContent("Custom placement of hit description block", "Only available if 'save drawn lines' is disabled.")); + + EditorGUI.BeginDisabledGroup(!sP_useCustomDirectionForHitResultText.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("customDirectionForHitResultText"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.EndHorizontal(); + + EditorGUI.EndDisabledGroup(); + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/PhysicsVisualizer2DInspector.cs.meta b/Editor/DrawDebugLibrary/PhysicsVisualizer2DInspector.cs.meta new file mode 100644 index 0000000..25889c8 --- /dev/null +++ b/Editor/DrawDebugLibrary/PhysicsVisualizer2DInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 09561109327f5bc43880b988763916a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/PhysicsVisualizerInspector.cs b/Editor/DrawDebugLibrary/PhysicsVisualizerInspector.cs new file mode 100644 index 0000000..12862cc --- /dev/null +++ b/Editor/DrawDebugLibrary/PhysicsVisualizerInspector.cs @@ -0,0 +1,511 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(PhysicsVisualizer))] + [CanEditMultipleObjects] + public class PhysicsVisualizerInspector : VisualizerParentInspector + { + PhysicsVisualizer physicsVisualizer_unserializedMonoB; + + void OnEnable() + { + OnEnable_base(); + physicsVisualizer_unserializedMonoB = (PhysicsVisualizer)target; + } + + public void OnSceneGUI() + { + if (physicsVisualizer_unserializedMonoB.showTransformIndependentRotationHandle) + { + Vector3 positionOfPhysicsShape = physicsVisualizer_unserializedMonoB.GetDrawPos3D_global(); + float sizeOfRotationHandle = HandleUtility.GetHandleSize(positionOfPhysicsShape); + Vector3 shiftOffsetDirectionFromTransformHandle_normalized = Vector3.up; + if (SceneView.lastActiveSceneView != null) + { + shiftOffsetDirectionFromTransformHandle_normalized = SceneView.lastActiveSceneView.camera.transform.up; + } + Vector3 postionOfAdditionalRotationHandle = positionOfPhysicsShape + shiftOffsetDirectionFromTransformHandle_normalized * 2.5f * sizeOfRotationHandle; + Quaternion returnedRotationFromHandle; + + switch (physicsVisualizer_unserializedMonoB.shapeOrientationType) + { + case PhysicsVisualizer.ShapeOrientationType.transformsRotationPlusOptionalAdditionalLocalRotation: + Quaternion optionalAdditionalRotation_local = physicsVisualizer_unserializedMonoB.transform.rotation * Quaternion.Euler(physicsVisualizer_unserializedMonoB.optionalAdditionalRotation_asEulersInV3); + Quaternion returnedRotationFromHandle_local = Handles.RotationHandle(optionalAdditionalRotation_local, postionOfAdditionalRotationHandle); + Quaternion returnedRotationFromHandle_global = Quaternion.Inverse(physicsVisualizer_unserializedMonoB.transform.rotation) * returnedRotationFromHandle_local; + physicsVisualizer_unserializedMonoB.optionalAdditionalRotation_asEulersInV3 = returnedRotationFromHandle_global.eulerAngles; + break; + case PhysicsVisualizer.ShapeOrientationType.transformsRotationPlusOptionalAdditionalGlobalRotation: + returnedRotationFromHandle = Handles.RotationHandle(Quaternion.Euler(physicsVisualizer_unserializedMonoB.optionalAdditionalRotation_asEulersInV3), postionOfAdditionalRotationHandle); + physicsVisualizer_unserializedMonoB.optionalAdditionalRotation_asEulersInV3 = returnedRotationFromHandle.eulerAngles; + break; + case PhysicsVisualizer.ShapeOrientationType.customRotationIndependentFromTransform: + returnedRotationFromHandle = Handles.RotationHandle(Quaternion.Euler(physicsVisualizer_unserializedMonoB.customRotation_asEulersInV3), postionOfAdditionalRotationHandle); + physicsVisualizer_unserializedMonoB.customRotation_asEulersInV3 = returnedRotationFromHandle.eulerAngles; + break; + default: + break; + } + + Handles.Label(postionOfAdditionalRotationHandle, "Handle for Physics Shape", new GUIStyle()); + } + } + + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("physics"); + SerializedProperty sP_saveDrawnLinesType = serializedObject.FindProperty("saveDrawnLinesType"); + EditorGUILayout.PropertyField(sP_saveDrawnLinesType, new GUIContent("Save drawn lines ?", "This simplifies the visualization. It may be helpful to save performance if you draw many casts at once." + Environment.NewLine + Environment.NewLine + "You can change the initial value of this via 'DrawXXL.DrawPhysics.visualizationQuality'.")); + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + bool typeIsCast_notCheck = false; + SerializedProperty sP_theGameobjectHasACompatibleAndEnabledCollider = serializedObject.FindProperty("theGameobjectHasACompatibleAndEnabledCollider"); + SerializedProperty sP_shape = serializedObject.FindProperty("shape"); + + TryDrawCollisionTypeChooser(sP_shape, sP_theGameobjectHasACompatibleAndEnabledCollider, ref typeIsCast_notCheck); + + if ((sP_shape.enumValueIndex == (int)PhysicsVisualizer.Shape.collidersOnThisGameobject) && (sP_theGameobjectHasACompatibleAndEnabledCollider.boolValue == false)) + { + EditorGUILayout.HelpBox("There is no enabled collider on this gameobject that could be cast. Supported colliders are 'BoxCollider', 'SphereCollider' and 'CapsuleCollider'.", MessageType.None, true); + } + else + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("wantedHits"), new GUIContent("Wanted hits")); + DrawDetectedHitsCount(); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + DrawShapeSizeSpecification(sP_shape); + DrawCastDirectionAndDistance(typeIsCast_notCheck); + DrawOtherSettings(sP_saveDrawnLinesType, typeIsCast_notCheck); + DrawTextSpecs(sP_saveDrawnLinesType, typeIsCast_notCheck); + DrawCheckboxFor_drawOnlyIfSelected("physics"); + DrawCheckboxFor_hiddenByNearerObjects("physics"); + } + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void TryDrawCollisionTypeChooser(SerializedProperty sP_shape, SerializedProperty sP_theGameobjectHasACompatibleAndEnabledCollider, ref bool typeIsCast_notCheck) + { + SerializedProperty sP_collisionType = serializedObject.FindProperty("collisionType"); + + bool forceDisplayToCast = false; + switch ((PhysicsVisualizer.Shape)sP_shape.enumValueIndex) + { + case PhysicsVisualizer.Shape.collidersOnThisGameobject: + if (sP_theGameobjectHasACompatibleAndEnabledCollider.boolValue) + { + forceDisplayToCast = false; + typeIsCast_notCheck = Get_typeIsCast_notCheck(sP_collisionType, forceDisplayToCast); + } + break; + case PhysicsVisualizer.Shape.box: + forceDisplayToCast = false; + typeIsCast_notCheck = Get_typeIsCast_notCheck(sP_collisionType, forceDisplayToCast); + break; + case PhysicsVisualizer.Shape.sphere: + forceDisplayToCast = false; + typeIsCast_notCheck = Get_typeIsCast_notCheck(sP_collisionType, forceDisplayToCast); + break; + case PhysicsVisualizer.Shape.capsule: + forceDisplayToCast = false; + typeIsCast_notCheck = Get_typeIsCast_notCheck(sP_collisionType, forceDisplayToCast); + break; + case PhysicsVisualizer.Shape.ray: + forceDisplayToCast = true; + typeIsCast_notCheck = Get_typeIsCast_notCheck(sP_collisionType, forceDisplayToCast); + break; + default: + break; + } + + string label_ofShape = typeIsCast_notCheck ? "Shape to cast" : "Shape to overlap"; + EditorGUILayout.PropertyField(sP_shape, new GUIContent(label_ofShape)); + + switch ((PhysicsVisualizer.Shape)sP_shape.enumValueIndex) + { + case PhysicsVisualizer.Shape.collidersOnThisGameobject: + if (sP_theGameobjectHasACompatibleAndEnabledCollider.boolValue) + { + if (UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(transform_onVisualizerObject.parent)) + { + EditorGUILayout.HelpBox("A parent transform has a non-uniform scale -> The collider and cast positions may be wrong.", MessageType.Warning, true); + } + DrawCollisionTypeChooser(sP_collisionType, forceDisplayToCast); + } + break; + case PhysicsVisualizer.Shape.box: + DrawCollisionTypeChooser(sP_collisionType, forceDisplayToCast); + break; + case PhysicsVisualizer.Shape.sphere: + DrawCollisionTypeChooser(sP_collisionType, forceDisplayToCast); + break; + case PhysicsVisualizer.Shape.capsule: + DrawCollisionTypeChooser(sP_collisionType, forceDisplayToCast); + break; + case PhysicsVisualizer.Shape.ray: + DrawCollisionTypeChooser(sP_collisionType, forceDisplayToCast); + break; + default: + break; + } + } + + bool Get_typeIsCast_notCheck(SerializedProperty sP_collisionType, bool forceDisplayToCast) + { + if (forceDisplayToCast) + { + return true; + } + else + { + return (sP_collisionType.enumValueIndex == (int)CollisionType.cast); + } + } + + void DrawCollisionTypeChooser(SerializedProperty sP_collisionType, bool forceDisplayToCast) + { + string label = "Collision type"; + if (forceDisplayToCast) + { + CollisionType castCollisionType = CollisionType.cast; + + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.EnumPopup(new GUIContent(label), castCollisionType); + EditorGUI.EndDisabledGroup(); + } + else + { + EditorGUILayout.PropertyField(sP_collisionType, new GUIContent(label)); + } + } + + void DrawDetectedHitsCount() + { + int numberOfDetectedHits = serializedObject.FindProperty("numberOfFoundHits").intValue; + Color displayColor = (numberOfDetectedHits == 0) ? serializedObject.FindProperty("colorForNonHittingCasts").colorValue : serializedObject.FindProperty("colorForHittingCasts").colorValue; + string labelText_name = "Detected hits:"; //-> I wanted to color this as well, but rich text seems to work only for the second label + string labelText_value = ("" + numberOfDetectedHits + ""); + GUIStyle style = new GUIStyle(EditorStyles.label); + style.richText = true; + EditorGUILayout.LabelField(labelText_name, labelText_value, style); + } + + void DrawShapeSizeSpecification(SerializedProperty sP_shape) + { + if ((sP_shape.enumValueIndex == (int)PhysicsVisualizer.Shape.box) || (sP_shape.enumValueIndex == (int)PhysicsVisualizer.Shape.sphere) || (sP_shape.enumValueIndex == (int)PhysicsVisualizer.Shape.capsule)) + { + GUIStyle richtextEnabledStyle = new GUIStyle(EditorStyles.label); + richtextEnabledStyle.richText = true; + + switch ((PhysicsVisualizer.Shape)sP_shape.enumValueIndex) + { + case PhysicsVisualizer.Shape.collidersOnThisGameobject: + break; + case PhysicsVisualizer.Shape.box: + EditorGUILayout.LabelField("Box: --- Size / Orientation / Position ---", richtextEnabledStyle); + break; + case PhysicsVisualizer.Shape.sphere: + EditorGUILayout.LabelField("Sphere: --- Size / Position ---", richtextEnabledStyle); + break; + case PhysicsVisualizer.Shape.capsule: + EditorGUILayout.LabelField("Capsule: --- Size / Orientation / Position ---", richtextEnabledStyle); + break; + case PhysicsVisualizer.Shape.ray: + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + switch ((PhysicsVisualizer.Shape)sP_shape.enumValueIndex) + { + case PhysicsVisualizer.Shape.collidersOnThisGameobject: + break; + case PhysicsVisualizer.Shape.box: + EditorGUILayout.PropertyField(serializedObject.FindProperty("sizeScaleFactors_ofCastRespCheckedBox"), new GUIContent("Size")); + DrawShapeOrientation(); + Draw_DrawPosition3DOffset(true, "Position Offset"); + break; + case PhysicsVisualizer.Shape.sphere: + EditorGUILayout.PropertyField(serializedObject.FindProperty("radiusScaleFactor_ofCastRespCheckedShape"), new GUIContent("Radius")); + Draw_DrawPosition3DOffset(true, "Position Offset"); + break; + case PhysicsVisualizer.Shape.capsule: + EditorGUILayout.PropertyField(serializedObject.FindProperty("radiusScaleFactor_ofCastRespCheckedShape"), new GUIContent("Radius")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("heightScaleFactor_ofCastRespCheckedCapsule"), new GUIContent("Height")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("capsuleAlignment"), new GUIContent("Height alignment")); + DrawShapeOrientation(); + Draw_DrawPosition3DOffset(true, "Position Offset"); + break; + case PhysicsVisualizer.Shape.ray: + break; + default: + break; + } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + else + { + if (sP_shape.enumValueIndex == (int)PhysicsVisualizer.Shape.ray) + { + Draw_DrawPosition3DOffset(false, "Position Offset"); + } + } + } + + void DrawShapeOrientation() + { + SerializedProperty sP_shapeOrientationType = serializedObject.FindProperty("shapeOrientationType"); + EditorGUILayout.PropertyField(sP_shapeOrientationType, new GUIContent("Orientation")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + switch (sP_shapeOrientationType.enumValueIndex) + { + case (int)PhysicsVisualizer.ShapeOrientationType.transformsRotationPlusOptionalAdditionalLocalRotation: + EditorGUILayout.PropertyField(serializedObject.FindProperty("optionalAdditionalRotation_asEulersInV3"), new GUIContent("Additional rotation (local)", "This is added to the rotation from the transform component. The angle values here rotate around the local axes of the transform, which may already be skewed and define a local space.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("showTransformIndependentRotationHandle"), new GUIContent("Show additional rotation handle", "This activates an additional rotation handle which is independent from the transforms rotation handle and only affects the additional rotation defined in the above line.")); + break; + case (int)PhysicsVisualizer.ShapeOrientationType.transformsRotationPlusOptionalAdditionalGlobalRotation: + EditorGUILayout.PropertyField(serializedObject.FindProperty("optionalAdditionalRotation_asEulersInV3"), new GUIContent("Additional rotation (global)", "This is added to the rotation from the transform component. The angle values here rotate around the global axes, independent of how the transform is already skewed in space.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("showTransformIndependentRotationHandle"), new GUIContent("Show additional rotation handle", "This activates an additional rotation handle which is independent from the transforms rotation handle and only affects the additional rotation defined in the above line.")); + break; + case (int)PhysicsVisualizer.ShapeOrientationType.customRotationIndependentFromTransform: + EditorGUILayout.PropertyField(serializedObject.FindProperty("customRotation_asEulersInV3"), new GUIContent("Custom rotation")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("showTransformIndependentRotationHandle"), new GUIContent("Show additional rotation handle", "This activates an additional rotation handle which is independent from the transforms rotation handle and only affects the custom rotation defined in the above line.")); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawCastDirectionAndDistance(bool typeIsCast_notCheck) + { + if (typeIsCast_notCheck) + { + DrawSpecificationOf_customVector3_1("Cast direction", false, null, true, false, true, false); + + EditorGUILayout.LabelField("Cast distance"); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + SerializedProperty sP_distanceIsInfinityRespToOtherGO = serializedObject.FindProperty("distanceIsInfinityRespToOtherGO"); + + if (visualizerParentMonoBehaviour_unserialized.customVector3Configs[0].source == VisualizerParent.CustomVector3Source.toOtherGameobject) + { + EditorGUILayout.PropertyField(sP_distanceIsInfinityRespToOtherGO, new GUIContent("Till other gameobject")); + } + else + { + EditorGUILayout.PropertyField(sP_distanceIsInfinityRespToOtherGO, new GUIContent("Infinity")); + } + + EditorGUI.BeginDisabledGroup(sP_distanceIsInfinityRespToOtherGO.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("adjustedDistance"), new GUIContent("Flexible")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + void DrawOtherSettings(SerializedProperty sP_saveDrawnLinesType, bool typeIsCast_notCheck) + { + SerializedProperty sP_otherSettings_isFoldedOut = serializedObject.FindProperty("otherSettings_isFoldedOut"); + sP_otherSettings_isFoldedOut.boolValue = EditorGUILayout.Foldout(sP_otherSettings_isFoldedOut.boolValue, "Other settings", true); + if (sP_otherSettings_isFoldedOut.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUILayout.PropertyField(serializedObject.FindProperty("excludeCollidersOnThisGO"), new GUIContent("Exclude colliders on this Gameobject from result", "Caution for disabling this:" + Environment.NewLine + "In many cases the colliders on this Gameobject will overlap with the starting position of the cast shapes. In these cases a collision will be detected, but the position and hit distance may be wrong.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("excludeCollidersOnParentGOs"), new GUIContent("Exclude colliders on parents from result", "Caution for disabling this:" + Environment.NewLine + "In many cases the colliders on the parents will overlap with the starting position of the cast shapes. In these cases a collision will be detected, but the position and hit distance may be wrong.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("excludeCollidersOnChildrenGOs"), new GUIContent("Exclude colliders on children from result", "Caution for disabling this:" + Environment.NewLine + "In many cases the colliders on the children will overlap with the starting position of the cast shapes. In these cases a collision will be detected, but the position and hit distance may be wrong.")); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("layerMask"), new GUIContent("Colliding layers", "The collision check considers only colliders that are part of the herewith selected layers." + Environment.NewLine + Environment.NewLine + "For more details see Unitys documentation of the 'layerMask' parameter inside the 'UnityEngine.Physics.*' functions documentation.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("queryTriggerInteraction"), new GUIContent("Trigger Interaction Config", "This defines whether the collision checks interact with colliders that are configurated as triggers." + Environment.NewLine + "'Use global' means that the global setting is used, which is defined by 'UnityEngine.Physics.queriesHitTriggers'." + Environment.NewLine + Environment.NewLine + "For more details see Unitys documentation of 'QueryTriggerInteraction'.")); + + string displayNameOfColorForNonHittingChecks; + string displayNameOfColorForHittingChecks; + if (typeIsCast_notCheck) + { + displayNameOfColorForNonHittingChecks = "Non hitting rays"; + displayNameOfColorForHittingChecks = "Hitting rays"; + } + else + { + displayNameOfColorForNonHittingChecks = "Not Overlapping"; + displayNameOfColorForHittingChecks = "Overlapping"; + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForNonHittingCasts"), new GUIContent(displayNameOfColorForNonHittingChecks, "You can change the initial value of this via 'DrawPhysics.colorForNonHittingCasts'.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForHittingCasts"), new GUIContent(displayNameOfColorForHittingChecks, "You can change the initial value of this via 'DrawPhysics.colorForHittingCasts'.")); + + if (typeIsCast_notCheck) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForCastLineBeyondHit"), new GUIContent("After last hit", "You can change the initial value of this via 'DrawPhysics.colorForCastLineBeyondHit'.")); + DrawChooserLineFor_overwriteColorForCastsHitNormals(); + Draw_castSilhouetteVisualizerDensity(sP_saveDrawnLinesType); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + void DrawChooserLineFor_overwriteColorForCastsHitNormals() + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("doOverwriteColorForCastsHitNormals"), new GUIContent("Custom Hit Normal Color", "The default color for normals at collision positions is that 'Color of hitting rays' is used, but with an adjusted brightness. Though you can overwrite the color of the normal here.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColorForCastsHitNormals"), GUIContent.none); + EditorGUILayout.EndHorizontal(); + } + + void Draw_castSilhouetteVisualizerDensity(SerializedProperty sP_saveDrawnLinesType) + { + if (sP_saveDrawnLinesType.enumValueIndex == (int)PhysicsVisualizer.SaveDrawnLinesType.yes_displayWithLowDetails) + { + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.PropertyField(serializedObject.FindProperty("castSilhouetteVisualizerDensity"), new GUIContent("Density (of cast silhouette visualizers)", "Not available in 'save drawn lines' mode.")); + EditorGUI.EndDisabledGroup(); + } + else + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("castSilhouetteVisualizerDensity"), new GUIContent("Density (of cast silhouette visualizers)", "You can change the initial value of this via 'DrawXXL.DrawPhysics.castSilhouetteVisualizerDensity'." + Environment.NewLine + Environment.NewLine + "If you reached a limit and no new silhouettes appear you can raise the maximum value via 'DrawXXL.DrawPhysics.maxSilhouettesPerCastVisualization'.")); + } + } + + public void DrawTextSpecs(SerializedProperty sP_saveDrawnLinesType, bool typeIsCast_notCheck) + { + if (sP_saveDrawnLinesType.enumValueIndex == (int)PhysicsVisualizer.SaveDrawnLinesType.yes_displayWithLowDetails) + { + EditorGUI.BeginDisabledGroup(true); + GUIStyle style_forFoldoutLine = new GUIStyle(EditorStyles.foldout); + EditorGUILayout.Foldout(false, new GUIContent("Text", "Not available in 'save drawn lines' mode."), false, style_forFoldoutLine); + EditorGUI.EndDisabledGroup(); + } + else + { + //-> this fakes the appearance of beeing inside the parents text specification foldout + bool emptyLineAtEndIfOutfolded = false; + DrawTextInputInclMarkupHelper(true, false, null, emptyLineAtEndIfOutfolded); + + if (serializedObject.FindProperty("textSection_isOutfolded").boolValue == true) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + if (typeIsCast_notCheck) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawCastNameTag_atCastOrigin"), new GUIContent("Draw text tag at cast origin", "You can change the initial value of this via 'DrawPhysics.drawCastNameTag_atCastOrigin'.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawCastNameTag_atHitPositions"), new GUIContent("Draw text tag at hit positions", "You can change the initial value of this via 'DrawPhysics.drawCastNameTag_atHitPositions'.")); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForCastsHitText"), new GUIContent("Hit description color", "You can change the initial value of this via 'DrawPhysics.colorForCastsHitText'.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("scaleFactor_forCastHitTextSize"), new GUIContent("Text size of hit descriptions", "You can change the initial value of this via 'DrawPhysics.scaleFactor_forCastHitTextSize'.")); + DrawChooserFor_useCustomDirectionForHitResultText(sP_saveDrawnLinesType); + } + else + { + SerializedProperty sP_overlapResultTextSizeInterpretation = serializedObject.FindProperty("overlapResultTextSizeInterpretation"); + EditorGUILayout.PropertyField(sP_overlapResultTextSizeInterpretation, new GUIContent("Text Size Reference Frame")); + + switch (sP_overlapResultTextSizeInterpretation.enumValueIndex) + { + case (int)PhysicsVisualizer.OverlapResultTextSizeInterpretation.relativeToTheSizeOfTheOverlapingPhysicsShape: + break; + case (int)PhysicsVisualizer.OverlapResultTextSizeInterpretation.fixedWorldSpaceSize: + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("forcedConstantWorldspaceTextSize_forOverlapResultTexts"), new GUIContent("Text size")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + case (int)PhysicsVisualizer.OverlapResultTextSizeInterpretation.relativeToTheSceneViewWindowSize: + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts"), new GUIContent("Text size")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + case (int)PhysicsVisualizer.OverlapResultTextSizeInterpretation.relativeToTheGameViewWindowSize: + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts"), new GUIContent("Text size")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + default: + break; + } + + SerializedProperty sP_maxListedColliders_inOverlapVolumesTextList = serializedObject.FindProperty("maxListedColliders_inOverlapVolumesTextList"); + EditorGUILayout.PropertyField(sP_maxListedColliders_inOverlapVolumesTextList, new GUIContent("Maximum listed colliders in results text list", "The results list will be truncated if there are more results, along with a notification how many results are hidden." + Environment.NewLine + Environment.NewLine + "You can set the initial value of this via 'DrawPhysics.MaxListedColliders_inOverlapVolumesTextList'.")); + sP_maxListedColliders_inOverlapVolumesTextList.intValue = Mathf.Max(1, sP_maxListedColliders_inOverlapVolumesTextList.intValue); + + SerializedProperty sP_maxOverlapingCollidersWithUntruncatedText = serializedObject.FindProperty("maxOverlapingCollidersWithUntruncatedText"); + if (sP_saveDrawnLinesType.enumValueIndex == (int)PhysicsVisualizer.SaveDrawnLinesType.no_useFullDetails) + { + EditorGUILayout.PropertyField(sP_maxOverlapingCollidersWithUntruncatedText, new GUIContent("Maximum collision markers with untruncated text", "If more collisions than this number are found then the description text at the collision position marker will be truncated to only a sequential number." + Environment.NewLine + Environment.NewLine + "You can set the initial value of this via 'DrawPhysics.maxOverlapingCollidersWithUntruncatedText'.")); + } + else + { + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.PropertyField(sP_maxOverlapingCollidersWithUntruncatedText, new GUIContent("Maximum collision markers with untruncated text", "Only available if 'save drawn lines' is disabled.")); + EditorGUI.EndDisabledGroup(); + } + sP_maxOverlapingCollidersWithUntruncatedText.intValue = Mathf.Max(0, sP_maxOverlapingCollidersWithUntruncatedText.intValue); + + } + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + } + + void DrawChooserFor_useCustomDirectionForHitResultText(SerializedProperty sP_saveDrawnLinesType) + { + if (sP_saveDrawnLinesType.enumValueIndex == (int)PhysicsVisualizer.SaveDrawnLinesType.no_useFullDetails) + { + SerializedProperty sP_useCustomDirectionForHitResultText = serializedObject.FindProperty("useCustomDirectionForHitResultText"); + EditorGUILayout.BeginHorizontal(); + + EditorGUILayout.PropertyField(sP_useCustomDirectionForHitResultText, new GUIContent("Custom placement of hit description block", "You can change the initial value of this via 'DrawPhysics.directionOfHitResultText'.")); + + EditorGUI.BeginDisabledGroup(!sP_useCustomDirectionForHitResultText.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("customDirectionForHitResultText"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.EndHorizontal(); + } + else + { + EditorGUI.BeginDisabledGroup(true); + + SerializedProperty sP_useCustomDirectionForHitResultText = serializedObject.FindProperty("useCustomDirectionForHitResultText"); + EditorGUILayout.BeginHorizontal(); + + EditorGUILayout.PropertyField(sP_useCustomDirectionForHitResultText, new GUIContent("Custom placement of hit description block", "Only available if 'save drawn lines' is disabled.")); + + EditorGUI.BeginDisabledGroup(!sP_useCustomDirectionForHitResultText.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("customDirectionForHitResultText"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.EndHorizontal(); + + EditorGUI.EndDisabledGroup(); + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/PhysicsVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/PhysicsVisualizerInspector.cs.meta new file mode 100644 index 0000000..d9f0f10 --- /dev/null +++ b/Editor/DrawDebugLibrary/PhysicsVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 969573b37874e894b9b60f080b9544f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/PositionVisualizerInspector.cs b/Editor/DrawDebugLibrary/PositionVisualizerInspector.cs new file mode 100644 index 0000000..3e184c5 --- /dev/null +++ b/Editor/DrawDebugLibrary/PositionVisualizerInspector.cs @@ -0,0 +1,58 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(PositionVisualizer))] + [CanEditMultipleObjects] + public class PositionVisualizerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("position"); + + SerializedProperty sP_global = serializedObject.FindProperty("global"); + SerializedProperty sP_local = serializedObject.FindProperty("local"); + SerializedProperty sP_allParents = serializedObject.FindProperty("allParents"); + + bool hasNoParents = (transform_onVisualizerObject.parent == null); + if (hasNoParents) + { + sP_global.boolValue = true; + sP_local.boolValue = false; + sP_allParents.boolValue = false; + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.PropertyField(sP_global, new GUIContent("Global")); + EditorGUILayout.PropertyField(sP_local, new GUIContent("Local")); + EditorGUI.EndDisabledGroup(); + } + else + { + EditorGUILayout.PropertyField(sP_global, new GUIContent("Global")); + EditorGUILayout.PropertyField(sP_local, new GUIContent("Local")); + } + + if (sP_local.boolValue == false) { sP_allParents.boolValue = false; } + + EditorGUI.BeginDisabledGroup(!sP_local.boolValue); + EditorGUILayout.PropertyField(sP_allParents, new GUIContent("For all parents")); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineWidth"), new GUIContent("Line width")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + + DrawTextInputInclMarkupHelper(); + DrawCheckboxFor_drawOnlyIfSelected("position"); + DrawCheckboxFor_hiddenByNearerObjects("position"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/PositionVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/PositionVisualizerInspector.cs.meta new file mode 100644 index 0000000..48f09a9 --- /dev/null +++ b/Editor/DrawDebugLibrary/PositionVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc49aa16f5c23294e842626a8292949e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/RotationVisualizerInspector.cs b/Editor/DrawDebugLibrary/RotationVisualizerInspector.cs new file mode 100644 index 0000000..8554074 --- /dev/null +++ b/Editor/DrawDebugLibrary/RotationVisualizerInspector.cs @@ -0,0 +1,104 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(RotationVisualizer))] + [CanEditMultipleObjects] + public class RotationVisualizerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("rotation"); + + SerializedProperty sP_rotationType = serializedObject.FindProperty("rotationType"); + EditorGUILayout.PropertyField(sP_rotationType, new GUIContent("Rotation type")); + bool displayIsQuaternion = ((sP_rotationType.enumValueIndex == (int)RotationVisualizer.RotationType.quaternionGlobal) || (sP_rotationType.enumValueIndex == (int)RotationVisualizer.RotationType.quaternionLocal)); + bool displayIsEuler = !displayIsQuaternion; + bool isLocal = ((sP_rotationType.enumValueIndex == (int)RotationVisualizer.RotationType.quaternionLocal) || (sP_rotationType.enumValueIndex == (int)RotationVisualizer.RotationType.eulerAnglesLocal)); + + if (displayIsQuaternion) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("color_ofTurnAxis"), new GUIContent("Turn axis color")); + } + + if (displayIsEuler) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay"), new GUIContent("Angles from code instead from inspector", "Angles from code instead from inspector:" + Environment.NewLine + Environment.NewLine + "The same overall rotation can be created by different sets of x/y/z-angles. For example (100/0/0) ends up as the same overall rotation than (80/180/180). Unity uses a different set of x/y/z-angles for display in the inspectors transform component than what transform.eulerAngles returns in code, thought in the end it's both the same overall rotation.")); + } + + SerializedProperty sP_length_ofUpAndForwardVectors; + if (displayIsQuaternion) + { + sP_length_ofUpAndForwardVectors = serializedObject.FindProperty("length_ofUpAndForwardVectors_caseQuaternion"); + } + else + { + sP_length_ofUpAndForwardVectors = serializedObject.FindProperty("length_ofUpAndForwardVectors_caseEuler"); + } + + GUIContent guiContent_ofUpForwardLength; + if (isLocal) + { + guiContent_ofUpForwardLength = new GUIContent("Rotated Up/Forward (length)", "This is in local units." + Environment.NewLine + Environment.NewLine + "You can disable the display of up and forward vectors by setting this value to 0."); + } + else + { + guiContent_ofUpForwardLength = new GUIContent("Rotated Up/Forward (length)", "You can disable the display of up and forward vectors by setting this value to 0."); + } + + EditorGUILayout.PropertyField(sP_length_ofUpAndForwardVectors, guiContent_ofUpForwardLength); + if (sP_length_ofUpAndForwardVectors.floatValue < 0.001f) + { + sP_length_ofUpAndForwardVectors.floatValue = 0.0f; + } + + if (displayIsEuler) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUI.BeginDisabledGroup(UtilitiesDXXL_Math.ApproximatelyZero(sP_length_ofUpAndForwardVectors.floatValue)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("alpha_ofSquareSpannedByForwardAndUp"), new GUIContent("Alpha (up/forward square)", "Is only available if length (up/forward) is bigger than 0.")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + SerializedProperty sP_drawCustomRotatedVector; + if (displayIsQuaternion) + { + sP_drawCustomRotatedVector = serializedObject.FindProperty("drawCustomRotatedVector_caseQuaternion"); + } + else + { + sP_drawCustomRotatedVector = serializedObject.FindProperty("drawCustomRotatedVector_caseEuler"); + } + + DrawSpecificationOf_customVector3_1("Rotate custom vector", true, sP_drawCustomRotatedVector, false, false, true, false); + + if (displayIsQuaternion) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineWidth"), new GUIContent("Lines width")); + } + + if (displayIsEuler) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("alpha_ofUnrotatedGimbalAxes"), new GUIContent("Alpha (unrotated axes)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gimbalSize"), new GUIContent("Gimbal size", "This doesn't affect the display of the rotated vectors but only scales the size of the three main axes.")); + } + + Draw_DrawPosition3DOffset(); + DrawTextInputInclMarkupHelper(); + DrawCheckboxFor_drawOnlyIfSelected("rotation"); + DrawCheckboxFor_hiddenByNearerObjects("rotation"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/RotationVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/RotationVisualizerInspector.cs.meta new file mode 100644 index 0000000..eacf0a7 --- /dev/null +++ b/Editor/DrawDebugLibrary/RotationVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0cf22c7aae289b147b16cb3a42620cb8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/ScaleVisualizerInspector.cs b/Editor/DrawDebugLibrary/ScaleVisualizerInspector.cs new file mode 100644 index 0000000..ae7d48b --- /dev/null +++ b/Editor/DrawDebugLibrary/ScaleVisualizerInspector.cs @@ -0,0 +1,47 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(ScaleVisualizer))] + [CanEditMultipleObjects] + public class ScaleVisualizerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("scale"); + + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.PropertyField(serializedObject.FindProperty("scaleType"), new GUIContent("Scale Type", "This is automatically set depending on if this gameObject has a parent or not.")); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawXDim"), new GUIContent("X")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawYDim"), new GUIContent("Y")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawZDim"), new GUIContent("Z")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("relSizeOfPlanes"), new GUIContent("Planes size")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineWidth"), new GUIContent("Line width")); + + GUILayout.BeginHorizontal(); + SerializedProperty sP_force_overwriteColor = serializedObject.FindProperty("force_overwriteColor"); + EditorGUILayout.PropertyField(sP_force_overwriteColor, new GUIContent("Force color")); + EditorGUI.BeginDisabledGroup(!sP_force_overwriteColor.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("overwriteColor"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + Draw_DrawPosition3DOffset(); + DrawTextInputInclMarkupHelper(); + DrawCheckboxFor_drawOnlyIfSelected("scale"); + DrawCheckboxFor_hiddenByNearerObjects("scale"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/ScaleVisualizerInspector.cs.meta b/Editor/DrawDebugLibrary/ScaleVisualizerInspector.cs.meta new file mode 100644 index 0000000..f1f3f3b --- /dev/null +++ b/Editor/DrawDebugLibrary/ScaleVisualizerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e8149ace8bc0b441958d0527f31b663 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/ShapeDrawer2DInspector.cs b/Editor/DrawDebugLibrary/ShapeDrawer2DInspector.cs new file mode 100644 index 0000000..d788e83 --- /dev/null +++ b/Editor/DrawDebugLibrary/ShapeDrawer2DInspector.cs @@ -0,0 +1,272 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(ShapeDrawer2D))] + [CanEditMultipleObjects] + public class ShapeDrawer2DInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("shape2D"); + + SerializedProperty sP_shapeType = serializedObject.FindProperty("shapeType"); + EditorGUILayout.PropertyField(sP_shapeType, new GUIContent("Shape type")); + + GUILayout.Space(0.75f * EditorGUIUtility.singleLineHeight); + + SerializedProperty sP_sizeDefinition = serializedObject.FindProperty("sizeDefinition"); + Draw_sizeInterpretationChooser(sP_sizeDefinition); + DrawShapeSpecificOptions(sP_shapeType, sP_sizeDefinition); + DrawGeneralOptions(sP_shapeType, sP_sizeDefinition); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void Draw_sizeInterpretationChooser(SerializedProperty sP_sizeDefinition) + { + EditorGUILayout.PropertyField(sP_sizeDefinition, new GUIContent("Size definition", "Some of the following parameters that define the size of the shape can be defined relative to a context of interest." + Environment.NewLine + "The values you specify in fields below like 'Radius' or 'Lines width' will be interpreted according to the setting here.")); + + SerializedProperty sP_cameraForSizeDefinitionIsAvailable = serializedObject.FindProperty("cameraForSizeDefinitionIsAvailable"); + switch ((ShapeDrawer2D.ShapeSizeDefinition)sP_sizeDefinition.enumValueIndex) + { + case ShapeDrawer2D.ShapeSizeDefinition.relativeToGlobalScaleOfTheTransformUsingTheBiggestAbsoluteComponentButIgnoringZ: + break; + case ShapeDrawer2D.ShapeSizeDefinition.absoluteUnits: + break; + case ShapeDrawer2D.ShapeSizeDefinition.relativeToTheSceneViewWindowSize: + if (sP_cameraForSizeDefinitionIsAvailable.boolValue == false) + { + EditorGUILayout.HelpBox("Scene View Camera Window is not available", MessageType.Warning, true); + } + break; + case ShapeDrawer2D.ShapeSizeDefinition.relativeToTheGameViewWindowSize: + if (sP_cameraForSizeDefinitionIsAvailable.boolValue == false) + { + EditorGUILayout.HelpBox("No Game View Camera found.", MessageType.Warning, true); + } + break; + default: + break; + } + } + + void DrawShapeSpecificOptions(SerializedProperty sP_shapeType, SerializedProperty sP_sizeDefinition) + { + switch (sP_shapeType.enumValueIndex) + { + case (int)ShapeDrawer2D.ShapeType.circle: + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer2D.ShapeType.ellipse: + Draw_sizeInterpretationDependentLine("width_scaleFactor_initialValue1", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_scaleFactor_initialValue2", "Height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer2D.ShapeType.star: + EditorGUILayout.PropertyField(serializedObject.FindProperty("cornerOptionsForIrregularStar"), new GUIContent("Corners")); + Draw_sizeInterpretationDependentLine("width_scaleFactor_initialValue1", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_scaleFactor_initialValue1", "Height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer2D.ShapeType.capsule: + Draw_sizeInterpretationDependentLine("width_scaleFactor_initialValue1", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_scaleFactor_initialValue2", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("capusleDirection2D"), new GUIContent("Direction")); + break; + case (int)ShapeDrawer2D.ShapeType.icon: + EditorGUILayout.PropertyField(serializedObject.FindProperty("iconType"), new GUIContent("Icon type")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("showAtlasOfAllAvailableIcons"), new GUIContent("Show atlas of all available icons")); + Draw_sizeInterpretationDependentLine("sizeOfIconScaleFactor", "Size", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("iconIsMirroredHorizontally"), new GUIContent("Mirror horizontally")); + break; + case (int)ShapeDrawer2D.ShapeType.triangle: + Draw_sizeInterpretationDependentLine("width_scaleFactor_initialValue1", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_scaleFactor_initialValue1", "Height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer2D.ShapeType.square: + Draw_sizeInterpretationDependentLine("width_scaleFactor_initialValue1", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_scaleFactor_initialValue1", "Height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer2D.ShapeType.pentagon: + Draw_sizeInterpretationDependentLine("width_scaleFactor_initialValue1", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_scaleFactor_initialValue1", "Height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer2D.ShapeType.hexagon: + Draw_sizeInterpretationDependentLine("width_scaleFactor_initialValue1", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_scaleFactor_initialValue1", "Height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer2D.ShapeType.septagon: + Draw_sizeInterpretationDependentLine("width_scaleFactor_initialValue1", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_scaleFactor_initialValue1", "Height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer2D.ShapeType.octagon: + Draw_sizeInterpretationDependentLine("width_scaleFactor_initialValue1", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_scaleFactor_initialValue1", "Height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer2D.ShapeType.decagon: + Draw_sizeInterpretationDependentLine("width_scaleFactor_initialValue1", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_scaleFactor_initialValue1", "Height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer2D.ShapeType.dot: + Draw_sizeInterpretationDependentLine("sizeOfIconScaleFactor", "Size", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("dotDensity"), new GUIContent("Fill density", "Raise this if you want the dot to be more opaque.")); + break; + default: + break; + } + } + + void DrawGeneralOptions(SerializedProperty sP_shapeType, SerializedProperty sP_sizeDefinition) + { + bool isIcon = (sP_shapeType.enumValueIndex == (int)ShapeDrawer2D.ShapeType.icon); + bool isStar = (sP_shapeType.enumValueIndex == (int)ShapeDrawer2D.ShapeType.star); + bool isDot = (sP_shapeType.enumValueIndex == (int)ShapeDrawer2D.ShapeType.dot); + + if (isDot == false) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("rotation_angleDegCC"), new GUIContent("Rotation")); + Draw_sizeInterpretationDependentLine("linesWidth", "Lines width", null, sP_sizeDefinition); + } + + if ((isIcon == false) && (isDot == false)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineStyle"), new GUIContent("Line style")); + Draw_sizeInterpretationDependentLine("stylePatternScaleFactor", "Line style scaling", null, sP_sizeDefinition); + } + + bool displayFillstyleOption = ((isIcon == false) && (isStar == false) && (isDot == false)); + if (displayFillstyleOption) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("fillStyle"), new GUIContent("Fill style")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("shapeFillDensity"), new GUIContent("Fill density")); + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + + Draw_DrawPosition2DOffset(); + DrawZPosChooserFor2D(); + DrawTextSpecs(sP_sizeDefinition, isIcon, isDot); + DrawCheckboxFor_drawOnlyIfSelected("shape"); + DrawCheckboxFor_hiddenByNearerObjects("shape2D"); + } + + void DrawTextSpecs(SerializedProperty sP_sizeDefinition, bool isIcon, bool isDot) + { + //-> this fakes the appearance of beeing inside the parents text specification foldout + bool emptyLineAtEndIfOutfolded = false; + DrawTextInputInclMarkupHelper(true, false, null, emptyLineAtEndIfOutfolded); + + if (serializedObject.FindProperty("textSection_isOutfolded").boolValue == true) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + if (CheckIf_shapeAttachedTextsizeReferenceContext_isUsed(sP_sizeDefinition, isIcon, isDot)) + { + DrawTextSizeChooser(); + } + + if ((isIcon == false) && (isDot == false)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("textBlockAboveLine"), new GUIContent("Text block above line")); + } + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + bool CheckIf_shapeAttachedTextsizeReferenceContext_isUsed(SerializedProperty sP_sizeDefinition, bool isIcon, bool isDot) + { + if (CheckIf_shapeSizeDefinition_isDependentOn_screenspace(sP_sizeDefinition)) + { + return false; + } + else + { + if (isIcon || isDot) + { + return false; + } + else + { + return true; + } + } + } + + void DrawTextSizeChooser() + { + EditorGUILayout.LabelField("Text Size"); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_shapeAttachedTextsizeReferenceContext = serializedObject.FindProperty("shapeAttachedTextsizeReferenceContext"); + EditorGUILayout.PropertyField(sP_shapeAttachedTextsizeReferenceContext, new GUIContent("Relative to")); + + switch (sP_shapeAttachedTextsizeReferenceContext.enumValueIndex) + { + case (int)ShapeDrawer.ShapeAttachedTextsizeReferenceContext.sizeOfShape: + break; + case (int)ShapeDrawer.ShapeAttachedTextsizeReferenceContext.globalSpace: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value"), new GUIContent("Size per letter", "Text size in world units")); + break; + case (int)ShapeDrawer.ShapeAttachedTextsizeReferenceContext.sceneViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value_relToScreen"), new GUIContent("Size per letter", "Text size relative to Scene View window size.")); + break; + case (int)ShapeDrawer.ShapeAttachedTextsizeReferenceContext.gameViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value_relToScreen"), new GUIContent("Size per letter", "Text size relative to Game View window size.")); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + bool CheckIf_shapeSizeDefinition_isDependentOn_screenspace(SerializedProperty sP_sizeDefinition) + { + return ((sP_sizeDefinition.enumValueIndex == (int)ShapeDrawer2D.ShapeSizeDefinition.relativeToTheSceneViewWindowSize) || (sP_sizeDefinition.enumValueIndex == (int)ShapeDrawer2D.ShapeSizeDefinition.relativeToTheGameViewWindowSize)); + } + + void Draw_sizeInterpretationDependentLine(string fieldName_withoutRelToScreenSuffix, string displayName, string tooltip, SerializedProperty sP_sizeDefinition) + { + GUIContent guiContent; + string toolTipSuffix = "This is relative to the reference frame defined by 'Size definition'"; + if (tooltip == null) + { + guiContent = new GUIContent(displayName, toolTipSuffix); + } + else + { + guiContent = new GUIContent(displayName, tooltip + Environment.NewLine + Environment.NewLine + toolTipSuffix); + } + + switch ((ShapeDrawer.ShapeSizeDefinition)sP_sizeDefinition.enumValueIndex) + { + case ShapeDrawer.ShapeSizeDefinition.relativeToTheGlobalScaleOfTheTransformRespectivelyItsBiggestAbsoluteComponent: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + ".absolute"), guiContent); + break; + case ShapeDrawer.ShapeSizeDefinition.absoluteUnits: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + ".absolute"), guiContent); + break; + case ShapeDrawer.ShapeSizeDefinition.relativeToTheSceneViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + ".relativeToScreen"), guiContent); + break; + case ShapeDrawer.ShapeSizeDefinition.relativeToTheGameViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + ".relativeToScreen"), guiContent); + break; + default: + break; + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/ShapeDrawer2DInspector.cs.meta b/Editor/DrawDebugLibrary/ShapeDrawer2DInspector.cs.meta new file mode 100644 index 0000000..7d0c5d7 --- /dev/null +++ b/Editor/DrawDebugLibrary/ShapeDrawer2DInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 09be8e1cc1fa90f4c920096395f1ef6d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/ShapeDrawerInspector.cs b/Editor/DrawDebugLibrary/ShapeDrawerInspector.cs new file mode 100644 index 0000000..043a541 --- /dev/null +++ b/Editor/DrawDebugLibrary/ShapeDrawerInspector.cs @@ -0,0 +1,839 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(ShapeDrawer))] + [CanEditMultipleObjects] + public class ShapeDrawerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("shape"); + + SerializedProperty sP_shapeCategory = serializedObject.FindProperty("shapeCategory"); + SerializedProperty sP_shapeType_3D = serializedObject.FindProperty("shapeType_3D"); + SerializedProperty sP_shapeType_flat = serializedObject.FindProperty("shapeType_flat"); + SerializedProperty sP_pyramidDefinitionVariant = serializedObject.FindProperty("pyramidDefinitionVariant"); + SerializedProperty sP_frustumDefinitionVariant = serializedObject.FindProperty("frustumDefinitionVariant"); + + EditorGUILayout.PropertyField(sP_shapeCategory, new GUIContent("Shape category")); + DrawShapeTypeChoosers(sP_shapeCategory, sP_shapeType_3D, sP_shapeType_flat, sP_pyramidDefinitionVariant, sP_frustumDefinitionVariant); + + bool isIcon = ((sP_shapeCategory.enumValueIndex == (int)ShapeDrawer.ShapeCategory.flat) && (sP_shapeType_flat.enumValueIndex == (int)ShapeDrawer.ShapeType_flat.icon)); + bool isDot = ((sP_shapeCategory.enumValueIndex == (int)ShapeDrawer.ShapeCategory.flat) && (sP_shapeType_flat.enumValueIndex == (int)ShapeDrawer.ShapeType_flat.dot)); + bool isPlane = ((sP_shapeCategory.enumValueIndex == (int)ShapeDrawer.ShapeCategory.flat) && (sP_shapeType_flat.enumValueIndex == (int)ShapeDrawer.ShapeType_flat.plane)); + bool isRhombus = ((sP_shapeCategory.enumValueIndex == (int)ShapeDrawer.ShapeCategory.flat) && (sP_shapeType_flat.enumValueIndex == (int)ShapeDrawer.ShapeType_flat.rhombus)); + + DrawPositionDefinition(sP_shapeCategory, sP_shapeType_3D, sP_frustumDefinitionVariant); + DrawOrientationDefinition(sP_shapeCategory, isIcon, isDot, isPlane, isRhombus); + + SerializedProperty sP_sizeDefinition = serializedObject.FindProperty("sizeDefinition"); + Draw_sizeInterpretationChooser(sP_sizeDefinition, isRhombus); + + bool displayFillstyleOption = false; + DrawShapeSpecificOptions(sP_shapeCategory, sP_shapeType_3D, sP_pyramidDefinitionVariant, sP_frustumDefinitionVariant, sP_shapeType_flat, ref displayFillstyleOption, sP_sizeDefinition); + DrawGeneralOptions(displayFillstyleOption, isIcon, isDot, isPlane, isRhombus, sP_sizeDefinition); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawShapeTypeChoosers(SerializedProperty sP_shapeCategory, SerializedProperty sP_shapeType_3D, SerializedProperty sP_shapeType_flat, SerializedProperty sP_pyramidDefinitionVariant, SerializedProperty sP_frustumDefinitionVariant) + { + switch (sP_shapeCategory.enumValueIndex) + { + case (int)ShapeDrawer.ShapeCategory._3D: + EditorGUILayout.PropertyField(sP_shapeType_3D, new GUIContent("Type of 3D shape")); + break; + case (int)ShapeDrawer.ShapeCategory.flat: + EditorGUILayout.PropertyField(sP_shapeType_flat, new GUIContent("Type of flat shape")); + break; + default: + break; + } + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + if (sP_shapeCategory.enumValueIndex == (int)ShapeDrawer.ShapeCategory._3D) + { + if (sP_shapeType_3D.enumValueIndex == (int)ShapeDrawer.ShapeType_3D.pyramid) + { + EditorGUILayout.PropertyField(sP_pyramidDefinitionVariant, new GUIContent("Pyramid definition variant")); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + + if (sP_shapeType_3D.enumValueIndex == (int)ShapeDrawer.ShapeType_3D.cone) + { + EditorGUILayout.PropertyField(sP_pyramidDefinitionVariant, new GUIContent("Cone definition variant")); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + + if (sP_shapeType_3D.enumValueIndex == (int)ShapeDrawer.ShapeType_3D.frustum) + { + EditorGUILayout.PropertyField(sP_frustumDefinitionVariant, new GUIContent("Frustum definition variant")); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + if (sP_shapeCategory.enumValueIndex == (int)ShapeDrawer.ShapeCategory.flat) + { + if (sP_shapeType_flat.enumValueIndex == (int)ShapeDrawer.ShapeType_flat.icon) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("iconType"), new GUIContent("Icon type")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("showAtlasOfAllAvailableIcons"), new GUIContent("Show atlas of all available icons")); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + } + + void DrawPositionDefinition(SerializedProperty sP_shapeCategory, SerializedProperty sP_shapeType_3D, SerializedProperty sP_frustumDefinitionVariant) + { + GUIStyle style_ofHeadline = new GUIStyle(); + style_ofHeadline.fontStyle = FontStyle.Bold; + EditorGUILayout.LabelField(serializedObject.FindProperty("labelOfPosition").stringValue, style_ofHeadline); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + Draw_DrawPosition3DOffset(true, "Offset from transform position"); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + if ((sP_shapeCategory.enumValueIndex == (int)ShapeDrawer.ShapeCategory._3D) && (sP_shapeType_3D.enumValueIndex == (int)ShapeDrawer.ShapeType_3D.frustum) && (sP_frustumDefinitionVariant.enumValueIndex == (int)ShapeDrawer.FrustumDefinitionVariant.centersOfBigAndSmallClipPlanes)) + { + //special case: one frustum variant uses a second position: + EditorGUILayout.LabelField("Position of center of small clip plane", style_ofHeadline); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("partnerGameobject"), new GUIContent("Position")); + EditorGUI.BeginDisabledGroup(visualizerParentMonoBehaviour_unserialized.partnerGameobject == null); + Draw_DrawPosition3DOffset_ofPartnerGameobject(true, "Offset from other transform position"); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + + void DrawOrientationDefinition(SerializedProperty sP_shapeCategory, bool isIcon, bool isDot, bool isPlane, bool isRhombus) + { + bool customVectorPickers_useGreyedOutVectors_3and4 = false; + if ((sP_shapeCategory.enumValueIndex == (int)ShapeDrawer.ShapeCategory.flat) && (isRhombus == false)) + { + SerializedProperty sP_force2DShapeTo_facingToSceneViewCam = serializedObject.FindProperty("force2DShapeTo_facingToSceneViewCam"); + SerializedProperty sP_force2DShapeTo_facingToGameViewCam = serializedObject.FindProperty("force2DShapeTo_facingToGameViewCam"); + + bool forceToSceneViewCam_isGreyedOut = false; + bool forceToGameViewCam_isGreyedOut = false; + + if (sP_force2DShapeTo_facingToGameViewCam.boolValue == true) + { + sP_force2DShapeTo_facingToSceneViewCam.boolValue = false; + forceToSceneViewCam_isGreyedOut = true; + } + + if (sP_force2DShapeTo_facingToSceneViewCam.boolValue == true) + { + sP_force2DShapeTo_facingToGameViewCam.boolValue = false; + forceToGameViewCam_isGreyedOut = true; + } + + EditorGUI.BeginDisabledGroup(forceToSceneViewCam_isGreyedOut); + EditorGUILayout.PropertyField(sP_force2DShapeTo_facingToSceneViewCam, new GUIContent("Force facing to Scene view camera")); + EditorGUI.EndDisabledGroup(); + + EditorGUI.BeginDisabledGroup(forceToGameViewCam_isGreyedOut); + EditorGUILayout.PropertyField(sP_force2DShapeTo_facingToGameViewCam, new GUIContent("Force facing to Game view camera")); + EditorGUI.EndDisabledGroup(); + + customVectorPickers_useGreyedOutVectors_3and4 = ((sP_force2DShapeTo_facingToGameViewCam.boolValue == true) || (sP_force2DShapeTo_facingToSceneViewCam.boolValue == true)); + + if (sP_force2DShapeTo_facingToGameViewCam.boolValue == true) + { + visualizerParentMonoBehaviour_unserialized.customVector3Configs[2].observerCamera = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + visualizerParentMonoBehaviour_unserialized.customVector3Configs[3].observerCamera = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + } + + if (sP_force2DShapeTo_facingToSceneViewCam.boolValue == true) + { + visualizerParentMonoBehaviour_unserialized.customVector3Configs[2].observerCamera = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + visualizerParentMonoBehaviour_unserialized.customVector3Configs[3].observerCamera = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + } + + if (isPlane) + { + visualizerParentMonoBehaviour_unserialized.customVector3Configs[2].source = VisualizerParent.CustomVector3Source.observerCameraUp; + visualizerParentMonoBehaviour_unserialized.customVector3Configs[3].source = VisualizerParent.CustomVector3Source.observerCameraForward; + } + else + { + if (isIcon || isDot) + { + visualizerParentMonoBehaviour_unserialized.customVector3Configs[2].source = VisualizerParent.CustomVector3Source.observerCameraBack; + visualizerParentMonoBehaviour_unserialized.customVector3Configs[3].source = VisualizerParent.CustomVector3Source.observerCameraUp; + } + else + { + visualizerParentMonoBehaviour_unserialized.customVector3Configs[2].source = VisualizerParent.CustomVector3Source.observerCameraForward; + visualizerParentMonoBehaviour_unserialized.customVector3Configs[3].source = VisualizerParent.CustomVector3Source.observerCameraUp; + } + } + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + + if (customVectorPickers_useGreyedOutVectors_3and4) + { + string explantionText_forGreyedOut = " (forced to face camera)"; + + EditorGUI.BeginDisabledGroup(true); + if (serializedObject.FindProperty("forwardVector_hasHigherPrioThan_upVector").boolValue) + { + DrawSpecificationOf_customVector3_3(serializedObject.FindProperty("labelOfForwardVector").stringValue + explantionText_forGreyedOut, false, null, true, false, true, false); + if (isDot == false) + { + DrawSpecificationOf_customVector3_4(serializedObject.FindProperty("labelOfUpVector").stringValue + explantionText_forGreyedOut, false, null, true, false, true, true); + } + } + else + { + DrawSpecificationOf_customVector3_4(serializedObject.FindProperty("labelOfUpVector").stringValue + explantionText_forGreyedOut, false, null, true, false, true, false); + DrawSpecificationOf_customVector3_3(serializedObject.FindProperty("labelOfForwardVector").stringValue + explantionText_forGreyedOut, false, null, true, false, true, true); + } + EditorGUI.EndDisabledGroup(); + } + else + { + bool hideEverythingThatConcernsLength_atCustomVectorPicker = isRhombus ? false : true; + if (serializedObject.FindProperty("forwardVector_hasHigherPrioThan_upVector").boolValue) + { + DrawSpecificationOf_customVector3_1(serializedObject.FindProperty("labelOfForwardVector").stringValue, false, null, hideEverythingThatConcernsLength_atCustomVectorPicker, false, true, false); + if (isDot == false) + { + DrawSpecificationOf_customVector3_2(serializedObject.FindProperty("labelOfUpVector").stringValue, false, null, hideEverythingThatConcernsLength_atCustomVectorPicker, false, true, true); + } + } + else + { + DrawSpecificationOf_customVector3_2(serializedObject.FindProperty("labelOfUpVector").stringValue, false, null, hideEverythingThatConcernsLength_atCustomVectorPicker, false, true, false); + DrawSpecificationOf_customVector3_1(serializedObject.FindProperty("labelOfForwardVector").stringValue, false, null, hideEverythingThatConcernsLength_atCustomVectorPicker, false, true, true); + } + } + } + + void Draw_sizeInterpretationChooser(SerializedProperty sP_sizeDefinition, bool isRhombus) + { + EditorGUILayout.PropertyField(sP_sizeDefinition, new GUIContent("Size definition", "Some of the following parameters that define the size of the shape can be defined relative to a context of interest." + Environment.NewLine + "The values you specify in fields below like 'Size' or 'Lines width' will be interpreted according to the setting here.")); + + SerializedProperty sP_cameraForSizeDefinitionIsAvailable = serializedObject.FindProperty("cameraForSizeDefinitionIsAvailable"); + switch ((ShapeDrawer.ShapeSizeDefinition)sP_sizeDefinition.enumValueIndex) + { + case ShapeDrawer.ShapeSizeDefinition.relativeToTheGlobalScaleOfTheTransformRespectivelyItsBiggestAbsoluteComponent: + break; + case ShapeDrawer.ShapeSizeDefinition.absoluteUnits: + break; + case ShapeDrawer.ShapeSizeDefinition.relativeToTheSceneViewWindowSize: + if (sP_cameraForSizeDefinitionIsAvailable.boolValue == false) + { + EditorGUILayout.HelpBox("Scene View Camera Window is not available", MessageType.Warning, true); + } + if (isRhombus) { DrawInfoBoxForRhombusInScreenspace("Scene View"); } + break; + case ShapeDrawer.ShapeSizeDefinition.relativeToTheGameViewWindowSize: + if (sP_cameraForSizeDefinitionIsAvailable.boolValue == false) + { + EditorGUILayout.HelpBox("No Game View Camera found.", MessageType.Warning, true); + } + if (isRhombus) { DrawInfoBoxForRhombusInScreenspace("Game View"); } + break; + default: + break; + } + } + + void DrawInfoBoxForRhombusInScreenspace(string typeOfScreen) + { + EditorGUILayout.HelpBox("The size of 'Rhombus' is defined by the two edge vectors and thus is not dependent on the screen window size. Though at least 'Lines width' and 'Line style scaling' are now tied to the " + typeOfScreen + " window size.", MessageType.Info, false); + } + + void DrawShapeSpecificOptions(SerializedProperty sP_shapeCategory, SerializedProperty sP_shapeType_3D, SerializedProperty sP_pyramidDefinitionVariant, SerializedProperty sP_frustumDefinitionVariant, SerializedProperty sP_shapeType_flat, ref bool displayFillstyleOption, SerializedProperty sP_sizeDefinition) + { + + switch (sP_shapeCategory.enumValueIndex) + { + case (int)ShapeDrawer.ShapeCategory._3D: + DrawShapeSpecificOptions_for3DShapes(sP_shapeType_3D, sP_pyramidDefinitionVariant, sP_frustumDefinitionVariant, sP_sizeDefinition); + break; + case (int)ShapeDrawer.ShapeCategory.flat: + DrawShapeSpecificOptions_forFlatShapes(sP_shapeType_flat, ref displayFillstyleOption, sP_sizeDefinition); + break; + default: + break; + } + } + + void DrawShapeSpecificOptions_for3DShapes(SerializedProperty sP_shapeType_3D, SerializedProperty sP_pyramidDefinitionVariant, SerializedProperty sP_frustumDefinitionVariant, SerializedProperty sP_sizeDefinition) + { + SerializedProperty sP_coneIsFilled = serializedObject.FindProperty("coneIsFilled"); + + switch (sP_shapeType_3D.enumValueIndex) + { + case (int)ShapeDrawer.ShapeType_3D.cube: + Draw_sizeInterpretationDependentLine("scaleFactors_ofHullVolume", "Size", null, sP_sizeDefinition); + + SerializedProperty sP_cubeIsFilled = serializedObject.FindProperty("cubeIsFilled"); + EditorGUILayout.PropertyField(sP_cubeIsFilled, new GUIContent("Fill sides")); + if (serializedObject.FindProperty("cubeIsFilled").boolValue) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorOfSidePlanes"), new GUIContent("Color of cube sides")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("segmentsPerSide"), new GUIContent("Segments per cube side")); + Draw_sizeInterpretationDependentLine("linesWidthOfCubeFillLines", "Line width of side filling", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("useEdgesColorAsTextColor_ifAvailable"), new GUIContent("Text color from edges", "The text color can be chosen to be the same as the edge color or the same as side planes color.")); + } + break; + case (int)ShapeDrawer.ShapeType_3D.sphere: + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("struts"), new GUIContent("Struts")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("sphereQuality"), new GUIContent("Roundness Quality", "You can change the initial value of this for newly created components via 'DrawShapes.LinesPerSphereCircle'.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("onlyUpperHalf"), new GUIContent("Only upper half shell")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawEquator"), new GUIContent("Draw equator")); + break; + case (int)ShapeDrawer.ShapeType_3D.capsule: + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius", "In constrast to the behaviour of the size definition of CapsuleCollider all three dimensions are taken into account here, since the upward orientation can be freely chosen and doesn't have to fit a transform axis.", sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightOfCapsule3D_scaleFactor", "Height", "In constrast to the behaviour of the size definition of CapsuleCollider all three dimensions are taken into account here, since the upward orientation can be freely chosen and doesn't have to fit a transform axis.", sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("struts"), new GUIContent("Struts")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("sphereQuality"), new GUIContent("Roundness Quality", "You can change the initial value of this for newly created components via 'DrawShapes.LinesPerSphereCircle'.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("onlyUpperHalf"), new GUIContent("Only upper half shell")); + break; + case (int)ShapeDrawer.ShapeType_3D.cylinder: + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("width_ofBase_scaleFactor", "Width of base", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("length_ofBase_scaleFactor", "Length of base", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("baseShape_withInitialValueOf_circle4struts"), new GUIContent("Extruded shape")); + break; + case (int)ShapeDrawer.ShapeType_3D.extrusion: + Draw_sizeInterpretationDependentLine("heightToUp_scaleFactor", "Upward extrusion height", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightToDown_scaleFactor", "Downward extrusion height", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("width_ofBase_scaleFactor", "Width of extruded cross section", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("length_ofBase_scaleFactor", "Length of extruded cross section", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("baseShape_withInitialValueOf_square"), new GUIContent("Extruded shape")); + break; + case (int)ShapeDrawer.ShapeType_3D.ellipsoid: + SerializedProperty sP_ellipsoidIsNonUniform = serializedObject.FindProperty("ellipsoidIsNonUniform"); + EditorGUILayout.PropertyField(sP_ellipsoidIsNonUniform, new GUIContent("Non uniform half shells")); + if (sP_ellipsoidIsNonUniform.boolValue) + { + Draw_sizeInterpretationDependentLine("radiusUpScaleFactor_ellipsoid", "Upward radius", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("radiusDownScaleFactor_ellipsoid", "Downward radius", null, sP_sizeDefinition); + } + else + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("onlyUpperHalf"), new GUIContent("Only upper half shell")); + Draw_sizeInterpretationDependentLine("radiusUpScaleFactor_ellipsoid", "Upward radius", null, sP_sizeDefinition); + } + Draw_sizeInterpretationDependentLine("width_ofBase_scaleFactor", "X - equator radius", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("length_ofBase_scaleFactor", "Z - equator radius", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("struts"), new GUIContent("Struts")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("sphereQuality"), new GUIContent("Roundness Quality", "You can change the initial value of this for newly created components via 'DrawShapes.LinesPerSphereCircle'.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawEquator"), new GUIContent("Draw equator")); + break; + case (int)ShapeDrawer.ShapeType_3D.pyramid: + switch (sP_pyramidDefinitionVariant.enumValueIndex) + { + case (int)ShapeDrawer.PyramidDefinitionVariant.fromCenterOfBasePlane: + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("width_ofBase_scaleFactor", "Width of base", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("length_ofBase_scaleFactor", "Length of base", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer.PyramidDefinitionVariant.fromApex: + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("angleDegVert_initialValueOf90"), new GUIContent("Angle (vertical)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("angleDegHoriz_initialValueOf90"), new GUIContent("Angle (horizontal)")); + break; + case (int)ShapeDrawer.PyramidDefinitionVariant.fromCenterOfHullVolume: + Draw_sizeInterpretationDependentLine("scaleFactors_ofHullVolume", "Size of hull", null, sP_sizeDefinition); + break; + default: + break; + } + EditorGUILayout.PropertyField(serializedObject.FindProperty("baseShape_withInitialValueOf_square"), new GUIContent("Base shape")); + break; + case (int)ShapeDrawer.ShapeType_3D.bipyramid: + Draw_sizeInterpretationDependentLine("heightToUp_scaleFactor", "Height of upper pyramid", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightToDown_scaleFactor", "Height of lower pyramid", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("width_ofBase_scaleFactor", "Width of base", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("length_ofBase_scaleFactor", "Length of base", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("baseShape_withInitialValueOf_square"), new GUIContent("Base shape")); + break; + case (int)ShapeDrawer.ShapeType_3D.cone: + EditorGUILayout.PropertyField(sP_coneIsFilled, new GUIContent("Dense filling")); + if (sP_coneIsFilled.boolValue) + { + switch (sP_pyramidDefinitionVariant.enumValueIndex) + { + case (int)ShapeDrawer.PyramidDefinitionVariant.fromCenterOfBasePlane: + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("width_ofBase_scaleFactor", "Width of base circle", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("length_ofBase_scaleFactor", "Length of base circle", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer.PyramidDefinitionVariant.fromApex: + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("angleDegVert_initialValueOf90"), new GUIContent("Angle (vertical)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("angleDegHoriz_initialValueOf90"), new GUIContent("Angle (horizontal)")); + break; + case (int)ShapeDrawer.PyramidDefinitionVariant.fromCenterOfHullVolume: + Draw_sizeInterpretationDependentLine("scaleFactors_ofHullVolume", "Size of hull", null, sP_sizeDefinition); + break; + default: + break; + } + } + else + { + switch (sP_pyramidDefinitionVariant.enumValueIndex) + { + case (int)ShapeDrawer.PyramidDefinitionVariant.fromCenterOfBasePlane: + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("width_ofBase_scaleFactor", "Width of base circle", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("length_ofBase_scaleFactor", "Length of base circle", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer.PyramidDefinitionVariant.fromApex: + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("angleDegVert_initialValueOf90"), new GUIContent("Angle (vertical)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("angleDegHoriz_initialValueOf90"), new GUIContent("Angle (horizontal)")); + break; + case (int)ShapeDrawer.PyramidDefinitionVariant.fromCenterOfHullVolume: + Draw_sizeInterpretationDependentLine("scaleFactors_ofHullVolume", "Size of hull", null, sP_sizeDefinition); + break; + default: + break; + } + } + break; + case (int)ShapeDrawer.ShapeType_3D.frustum: + switch (sP_frustumDefinitionVariant.enumValueIndex) + { + case (int)ShapeDrawer.FrustumDefinitionVariant.centerOfBigClipPlanePlusDistanceAndScaleFactorOfSmallPlane: + Draw_sizeInterpretationDependentLine("distanceBetweenClipPlanes_scaleFactor", "Distance between clip planes", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("scalingFactor_forSmallClipPlane"), new GUIContent("Small clip plane size (relative to big plane)")); + Draw_sizeInterpretationDependentLine("width_ofBigClipPlane_scaleFactor", "Big clip plane width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_ofBigClipPlane_scaleFactor", "Big clip plane height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer.FrustumDefinitionVariant.centerOfBigClipPlanePlusDistancesToSmallPlaneAndApex: + Draw_sizeInterpretationDependentLine("distance_bigClipPlaneToApex_scaleFactor", "Distance from big clip plane to apex", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("distanceBetweenClipPlanes_scaleFactor", "Distance between clip planes", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("width_ofBigClipPlane_scaleFactor", "Big clip plane width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_ofBigClipPlane_scaleFactor", "Big clip plane height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer.FrustumDefinitionVariant.centersOfBigAndSmallClipPlanes: + Draw_sizeInterpretationDependentLine("width_ofBigClipPlane_scaleFactor", "Big clip plane width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_ofBigClipPlane_scaleFactor", "Big clip plane height", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("width_ofSmallClipPlane_scaleFactor", "Small clip plane width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("height_ofSmallClipPlane_scaleFactor", "Small clip plane height", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer.FrustumDefinitionVariant.fromApex: + EditorGUILayout.PropertyField(serializedObject.FindProperty("angleDeg_initialValueOf60"), new GUIContent("Field of view (vertical angle)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("aspectRatio"), new GUIContent("Aspect ratio")); + Draw_sizeInterpretationDependentLine("distanceApexToNearPlane_scaleFactor", "Near clip planes distance from apex", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("distance_bigClipPlaneToApex_scaleFactor", "Far clip planes distance from apex", null, sP_sizeDefinition); + break; + case (int)ShapeDrawer.FrustumDefinitionVariant.fromCenterOfHullVolume: + Draw_sizeInterpretationDependentLine("scaleFactors_ofHullVolume", "Size of hull", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("scalingFactor_forSmallClipPlane"), new GUIContent("Small clip plane size (relative to big plane)")); + break; + default: + break; + } + EditorGUILayout.PropertyField(serializedObject.FindProperty("baseShape_withInitialValueOf_square"), new GUIContent("Clip planes shape")); + break; + default: + break; + } + } + + void DrawShapeSpecificOptions_forFlatShapes(SerializedProperty sP_shapeType_flat, ref bool displayFillstyleOption, SerializedProperty sP_sizeDefinition) + { + SerializedProperty sP_flatShapeIsNonUniform = serializedObject.FindProperty("flatShapeIsNonUniform"); + string flatShapeIsNonUniform_description = "Uneven aspect ratio"; + + switch (sP_shapeType_flat.enumValueIndex) + { + case (int)ShapeDrawer.ShapeType_flat.circle: + displayFillstyleOption = true; + EditorGUILayout.PropertyField(sP_flatShapeIsNonUniform, new GUIContent(flatShapeIsNonUniform_description)); + if (sP_flatShapeIsNonUniform.boolValue) + { + Draw_sizeInterpretationDependentLine("widthScaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("flattenRoundLines_intoShapePlane"), new GUIContent("Force round lines to flat", "This only applies if 'Lines width' is bigger than zero.")); + } + else + { + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + } + break; + case (int)ShapeDrawer.ShapeType_flat.ellipse: + displayFillstyleOption = true; + Draw_sizeInterpretationDependentLine("radiusSideward_ofEllipse_scaleFactor", "Radius towards side", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("radiusUpward_ofEllipse_scaleFactor", "Radius towards up", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + break; + case (int)ShapeDrawer.ShapeType_flat.star: + EditorGUILayout.PropertyField(sP_flatShapeIsNonUniform, new GUIContent(flatShapeIsNonUniform_description)); + if (sP_flatShapeIsNonUniform.boolValue) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("cornerOptionsForIrregularStar"), new GUIContent("Corners")); + Draw_sizeInterpretationDependentLine("widthScaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("flattenRoundLines_intoShapePlane"), new GUIContent("Force round lines to flat", "This only applies if 'Lines width' is bigger than zero.")); + } + else + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("corners"), new GUIContent("Corners")); + Draw_sizeInterpretationDependentLine("outerRadiusOfStars_scaleFactor", "Outer radius", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("innerRadiusFactor"), new GUIContent("Inner radius (relative to outer radius)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + } + break; + case (int)ShapeDrawer.ShapeType_flat.capsule: + displayFillstyleOption = true; + Draw_sizeInterpretationDependentLine("widthOfCapsule2D_scaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightOfCapsule2D_scaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("capusleDirection2D"), new GUIContent("Direction")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + break; + case (int)ShapeDrawer.ShapeType_flat.icon: + Draw_sizeInterpretationDependentLine("uniformSizeScaleFactor", "Size", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("iconIsMirroredHorizontally"), new GUIContent("Mirror horizontally")); + break; + case (int)ShapeDrawer.ShapeType_flat.triangle: + displayFillstyleOption = true; + EditorGUILayout.PropertyField(sP_flatShapeIsNonUniform, new GUIContent(flatShapeIsNonUniform_description)); + if (sP_flatShapeIsNonUniform.boolValue) + { + Draw_sizeInterpretationDependentLine("widthScaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("flattenRoundLines_intoShapePlane"), new GUIContent("Force round lines to flat", "This only applies if 'Lines width' is bigger than zero.")); + } + else + { + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius (of hull circle)", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + } + break; + case (int)ShapeDrawer.ShapeType_flat.square: + displayFillstyleOption = true; + EditorGUILayout.PropertyField(sP_flatShapeIsNonUniform, new GUIContent(flatShapeIsNonUniform_description)); + if (sP_flatShapeIsNonUniform.boolValue) + { + Draw_sizeInterpretationDependentLine("widthScaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("flattenRoundLines_intoShapePlane"), new GUIContent("Force round lines to flat", "This only applies if 'Lines width' is bigger than zero.")); + } + else + { + Draw_sizeInterpretationDependentLine("uniformSizeScaleFactor", "Size", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + } + break; + case (int)ShapeDrawer.ShapeType_flat.pentagon: + displayFillstyleOption = true; + EditorGUILayout.PropertyField(sP_flatShapeIsNonUniform, new GUIContent(flatShapeIsNonUniform_description)); + if (sP_flatShapeIsNonUniform.boolValue) + { + Draw_sizeInterpretationDependentLine("widthScaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("flattenRoundLines_intoShapePlane"), new GUIContent("Force round lines to flat", "This only applies if 'Lines width' is bigger than zero.")); + } + else + { + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius (of hull circle)", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + } + break; + case (int)ShapeDrawer.ShapeType_flat.hexagon: + displayFillstyleOption = true; + EditorGUILayout.PropertyField(sP_flatShapeIsNonUniform, new GUIContent(flatShapeIsNonUniform_description)); + if (sP_flatShapeIsNonUniform.boolValue) + { + Draw_sizeInterpretationDependentLine("widthScaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("flattenRoundLines_intoShapePlane"), new GUIContent("Force round lines to flat", "This only applies if 'Lines width' is bigger than zero.")); + } + else + { + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius (of hull circle)", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + } + break; + case (int)ShapeDrawer.ShapeType_flat.septagon: + displayFillstyleOption = true; + EditorGUILayout.PropertyField(sP_flatShapeIsNonUniform, new GUIContent(flatShapeIsNonUniform_description)); + if (sP_flatShapeIsNonUniform.boolValue) + { + Draw_sizeInterpretationDependentLine("widthScaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("flattenRoundLines_intoShapePlane"), new GUIContent("Force round lines to flat", "This only applies if 'Lines width' is bigger than zero.")); + } + else + { + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius (of hull circle)", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + } + break; + case (int)ShapeDrawer.ShapeType_flat.octagon: + displayFillstyleOption = true; + EditorGUILayout.PropertyField(sP_flatShapeIsNonUniform, new GUIContent(flatShapeIsNonUniform_description)); + if (sP_flatShapeIsNonUniform.boolValue) + { + Draw_sizeInterpretationDependentLine("widthScaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("flattenRoundLines_intoShapePlane"), new GUIContent("Force round lines to flat", "This only applies if 'Lines width' is bigger than zero.")); + } + else + { + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius (of hull circle)", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + } + break; + case (int)ShapeDrawer.ShapeType_flat.decagon: + displayFillstyleOption = true; + EditorGUILayout.PropertyField(sP_flatShapeIsNonUniform, new GUIContent(flatShapeIsNonUniform_description)); + if (sP_flatShapeIsNonUniform.boolValue) + { + Draw_sizeInterpretationDependentLine("widthScaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("heightScaleFactor", "Height", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("flattenRoundLines_intoShapePlane"), new GUIContent("Force round lines to flat", "This only applies if 'Lines width' is bigger than zero.")); + } + else + { + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius (of hull circle)", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + } + break; + case (int)ShapeDrawer.ShapeType_flat.regularPolygon: + displayFillstyleOption = true; + EditorGUILayout.PropertyField(serializedObject.FindProperty("corners"), new GUIContent("Corners")); + Draw_sizeInterpretationDependentLine("radiusScaleFactor", "Radius (of hull circle)", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("filledWithSpokes"), new GUIContent("Filled with spokes")); + break; + case (int)ShapeDrawer.ShapeType_flat.plane: + Draw_sizeInterpretationDependentLine("widthOfPlane_scaleFactor", "Width", null, sP_sizeDefinition); + Draw_sizeInterpretationDependentLine("lengthOfPlane_scaleFactor", "Length", null, sP_sizeDefinition); + Draw_extendPlaneToOtherGO(); + Draw_planeStrutConfig(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("planeAnchorVisualizationSize"), new GUIContent("Size of Anchor Point Visualization")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("pointer_as_textAttachStyle_forPlanes"), new GUIContent("Text position beside plane", "This only applies if 'Drawn text tag' is filled")); + break; + case (int)ShapeDrawer.ShapeType_flat.rhombus: + EditorGUILayout.PropertyField(serializedObject.FindProperty("rhombusPositionDescribesCenterNotCorner"), new GUIContent("Position defines center, not corner")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("subSegments"), new GUIContent("Sub segments")); + break; + case (int)ShapeDrawer.ShapeType_flat.dot: + Draw_sizeInterpretationDependentLine("uniformSizeScaleFactor", "Size", null, sP_sizeDefinition); + EditorGUILayout.PropertyField(serializedObject.FindProperty("dotDensity"), new GUIContent("Fill density", "Raise this if you want the dot to be more opaque.")); + break; + default: + break; + } + } + + void DrawGeneralOptions(bool displayFillstyleOption, bool isIcon, bool isDot, bool isPlane, bool isRhombus, SerializedProperty sP_sizeDefinition) + { + if (isDot == false) + { + Draw_sizeInterpretationDependentLine("linesWidth", "Lines width", null, sP_sizeDefinition); + } + + if ((isIcon == false) && (isDot == false)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineStyle"), new GUIContent("Line style")); + Draw_sizeInterpretationDependentLine("stylePatternScaleFactor", "Line style scaling", null, sP_sizeDefinition); + } + + if (displayFillstyleOption) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("fillStyle"), new GUIContent("Fill style")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("shapeFillDensity"), new GUIContent("Fill density")); + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + + bool shapeDisplaysText_viaPointCollection = ((isIcon == false) && (isDot == false) && (isRhombus == false) && ((isPlane == false) || (serializedObject.FindProperty("pointer_as_textAttachStyle_forPlanes").boolValue))); + DrawTextSpecs(sP_sizeDefinition, shapeDisplaysText_viaPointCollection); + DrawCheckboxFor_drawOnlyIfSelected("shape"); + DrawCheckboxFor_hiddenByNearerObjects("shape"); + } + + void DrawTextSpecs(SerializedProperty sP_sizeDefinition, bool shapeDisplaysText_viaPointCollection) + { + //-> this fakes the appearance of beeing inside the parents text specification foldout + bool emptyLineAtEndIfOutfolded = false; + DrawTextInputInclMarkupHelper(true, false, null, emptyLineAtEndIfOutfolded); + + if (serializedObject.FindProperty("textSection_isOutfolded").boolValue == true) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + if (CheckIf_shapeAttachedTextsizeReferenceContext_isUsed(sP_sizeDefinition, shapeDisplaysText_viaPointCollection)) + { + DrawTextSizeChooser(); + } + + if (shapeDisplaysText_viaPointCollection) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("textBlockAboveLine"), new GUIContent("Text block above line")); + } + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + bool CheckIf_shapeAttachedTextsizeReferenceContext_isUsed(SerializedProperty sP_sizeDefinition, bool shapeDisplaysText_viaPointCollection) + { + if (CheckIf_shapeSizeDefinition_isDependentOn_screenspace(sP_sizeDefinition)) + { + return false; + } + else + { + return shapeDisplaysText_viaPointCollection; + } + } + + void DrawTextSizeChooser() + { + EditorGUILayout.LabelField("Text Size"); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_shapeAttachedTextsizeReferenceContext = serializedObject.FindProperty("shapeAttachedTextsizeReferenceContext"); + EditorGUILayout.PropertyField(sP_shapeAttachedTextsizeReferenceContext, new GUIContent("Relative to")); + + switch (sP_shapeAttachedTextsizeReferenceContext.enumValueIndex) + { + case (int)ShapeDrawer.ShapeAttachedTextsizeReferenceContext.sizeOfShape: + break; + case (int)ShapeDrawer.ShapeAttachedTextsizeReferenceContext.globalSpace: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value"), new GUIContent("Size per letter", "Text size in world units")); + break; + case (int)ShapeDrawer.ShapeAttachedTextsizeReferenceContext.sceneViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value_relToScreen"), new GUIContent("Size per letter", "Text size relative to Scene View window size.")); + break; + case (int)ShapeDrawer.ShapeAttachedTextsizeReferenceContext.gameViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value_relToScreen"), new GUIContent("Size per letter", "Text size relative to Game View window size.")); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + bool CheckIf_shapeSizeDefinition_isDependentOn_screenspace(SerializedProperty sP_sizeDefinition) + { + return ((sP_sizeDefinition.enumValueIndex == (int)ShapeDrawer.ShapeSizeDefinition.relativeToTheSceneViewWindowSize) || (sP_sizeDefinition.enumValueIndex == (int)ShapeDrawer.ShapeSizeDefinition.relativeToTheGameViewWindowSize)); + } + + void Draw_sizeInterpretationDependentLine(string fieldName_withoutRelToScreenSuffix, string displayName, string tooltip, SerializedProperty sP_sizeDefinition) + { + GUIContent guiContent; + string toolTipSuffix = "This is relative to the reference frame defined by 'Size definition'"; + if (tooltip == null) + { + guiContent = new GUIContent(displayName, toolTipSuffix); + } + else + { + guiContent = new GUIContent(displayName, tooltip + Environment.NewLine + Environment.NewLine + toolTipSuffix); + } + + // handle Vector3 field (scaleFactors_ofHullVolume) which still uses old _relToScreen convention + if (fieldName_withoutRelToScreenSuffix == "scaleFactors_ofHullVolume") + { + switch ((ShapeDrawer.ShapeSizeDefinition)sP_sizeDefinition.enumValueIndex) + { + case ShapeDrawer.ShapeSizeDefinition.relativeToTheGlobalScaleOfTheTransformRespectivelyItsBiggestAbsoluteComponent: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix), guiContent); + break; + case ShapeDrawer.ShapeSizeDefinition.absoluteUnits: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix), guiContent); + break; + case ShapeDrawer.ShapeSizeDefinition.relativeToTheSceneViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + "_relToScreen"), guiContent); + break; + case ShapeDrawer.ShapeSizeDefinition.relativeToTheGameViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + "_relToScreen"), guiContent); + break; + default: + break; + } + return; + } + + switch ((ShapeDrawer.ShapeSizeDefinition)sP_sizeDefinition.enumValueIndex) + { + case ShapeDrawer.ShapeSizeDefinition.relativeToTheGlobalScaleOfTheTransformRespectivelyItsBiggestAbsoluteComponent: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + ".absolute"), guiContent); + break; + case ShapeDrawer.ShapeSizeDefinition.absoluteUnits: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + ".absolute"), guiContent); + break; + case ShapeDrawer.ShapeSizeDefinition.relativeToTheSceneViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + ".relativeToScreen"), guiContent); + break; + case ShapeDrawer.ShapeSizeDefinition.relativeToTheGameViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + ".relativeToScreen"), guiContent); + break; + default: + break; + } + } + + void Draw_extendPlaneToOtherGO() + { + SerializedProperty sP_extendPlaneToOtherGO = serializedObject.FindProperty("extendPlaneToOtherGO"); + EditorGUILayout.PropertyField(sP_extendPlaneToOtherGO, new GUIContent("Extend Plane to other Gameobject", "This will extend the drawn plane so it incorporates the position of an other Gameobject, respectively the perpendicular plump position on the plane of this other Gameobject.")); + bool gameobjectIsAssigned = (sP_extendPlaneToOtherGO.objectReferenceValue != null); + + EditorGUI.BeginDisabledGroup(gameobjectIsAssigned == false); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + string tooltip = gameobjectIsAssigned ? null : "This is only available if the Gameobject in the preceding line is assigned."; + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawPlumbLine_fromExtentionPosition"), new GUIContent("Draw perpendicular line to other Gameobject", tooltip)); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + EditorGUI.EndDisabledGroup(); + } + + void Draw_planeStrutConfig() + { + SerializedProperty sP_planeStrutDefinitionType = serializedObject.FindProperty("planeStrutDefinitionType"); + EditorGUILayout.PropertyField(sP_planeStrutDefinitionType, new GUIContent("Sub segments definition")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + if (sP_planeStrutDefinitionType.enumValueIndex == (int)ShapeDrawer.PlaneStrutDefinitionType.fixedNumber) + { + SerializedProperty sP_subSegments = serializedObject.FindProperty("subSegments"); + EditorGUILayout.PropertyField(sP_subSegments, new GUIContent("Number of Sub Segments")); + sP_subSegments.intValue = Mathf.Max(sP_subSegments.intValue, 1); + } + else + { + SerializedProperty sP_fixedPlaneStrutDistance = serializedObject.FindProperty("fixedPlaneStrutDistance"); + EditorGUILayout.PropertyField(sP_fixedPlaneStrutDistance, new GUIContent("Distance of Sub Segments", "This is always in world space, so it is independent from the 'Size definition' setting above.")); + sP_fixedPlaneStrutDistance.floatValue = Mathf.Max(sP_fixedPlaneStrutDistance.floatValue, UtilitiesDXXL_Shapes.min_fixedWorldSpaceDistanceOfStrutSegments); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/ShapeDrawerInspector.cs.meta b/Editor/DrawDebugLibrary/ShapeDrawerInspector.cs.meta new file mode 100644 index 0000000..2d315ea --- /dev/null +++ b/Editor/DrawDebugLibrary/ShapeDrawerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8130065c3bc0110449d42f3c5661dec1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/ShapeDrawerScreenspaceInspector.cs b/Editor/DrawDebugLibrary/ShapeDrawerScreenspaceInspector.cs new file mode 100644 index 0000000..5fcab91 --- /dev/null +++ b/Editor/DrawDebugLibrary/ShapeDrawerScreenspaceInspector.cs @@ -0,0 +1,139 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(ShapeDrawerScreenspace))] + [CanEditMultipleObjects] + public class ShapeDrawerScreenspaceInspector : VisualizerScreenspaceParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("shape"); + if (DrawCameraChooser(true)) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + SerializedProperty sP_shapeType = serializedObject.FindProperty("shapeType"); + EditorGUILayout.PropertyField(sP_shapeType, new GUIContent("Shape type")); + + GUILayout.Space(0.75f * EditorGUIUtility.singleLineHeight); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("positionInsideViewport0to1"), new GUIContent("Position (inside viewport)")); + DrawShapeSpecificOptions(sP_shapeType); + DrawGeneralOptions(sP_shapeType); + } + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawShapeSpecificOptions(SerializedProperty sP_shapeType) + { + + switch (sP_shapeType.enumValueIndex) + { + case (int)ShapeDrawer2D.ShapeType.circle: + EditorGUILayout.PropertyField(serializedObject.FindProperty("radius_relToViewportHeight"), new GUIContent("Radius", tooltip_explaining_relativeToViewPortHeight)); + break; + case (int)ShapeDrawer2D.ShapeType.ellipse: + EditorGUILayout.PropertyField(serializedObject.FindProperty("width_relToViewportHeight_initialValue01"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("height_relToViewportHeight_initialValue02"), new GUIContent("Height", tooltip_explaining_relativeToViewPortHeight)); + break; + case (int)ShapeDrawer2D.ShapeType.star: + EditorGUILayout.PropertyField(serializedObject.FindProperty("cornerOptionsForIrregularStar"), new GUIContent("Corners")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("width_relToViewportHeight_initialValue01"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("height_relToViewportHeight_initialValue01"), new GUIContent("Height", tooltip_explaining_relativeToViewPortHeight)); + break; + case (int)ShapeDrawer2D.ShapeType.capsule: + EditorGUILayout.PropertyField(serializedObject.FindProperty("width_relToViewportHeight_initialValue01"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("height_relToViewportHeight_initialValue02"), new GUIContent("Height", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("capusleDirection2D"), new GUIContent("Direction")); + break; + case (int)ShapeDrawer2D.ShapeType.icon: + EditorGUILayout.PropertyField(serializedObject.FindProperty("iconType"), new GUIContent("Icon type")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("sizeOfIcon_relToViewportHeight"), new GUIContent("Size", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("iconIsMirroredHorizontally"), new GUIContent("Mirror horizontally")); + break; + case (int)ShapeDrawer2D.ShapeType.triangle: + EditorGUILayout.PropertyField(serializedObject.FindProperty("width_relToViewportHeight_initialValue01"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("height_relToViewportHeight_initialValue01"), new GUIContent("Height", tooltip_explaining_relativeToViewPortHeight)); + break; + case (int)ShapeDrawer2D.ShapeType.square: + EditorGUILayout.PropertyField(serializedObject.FindProperty("width_relToViewportHeight_initialValue01"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("height_relToViewportHeight_initialValue01"), new GUIContent("Height", tooltip_explaining_relativeToViewPortHeight)); + break; + case (int)ShapeDrawer2D.ShapeType.pentagon: + EditorGUILayout.PropertyField(serializedObject.FindProperty("width_relToViewportHeight_initialValue01"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("height_relToViewportHeight_initialValue01"), new GUIContent("Height", tooltip_explaining_relativeToViewPortHeight)); + break; + case (int)ShapeDrawer2D.ShapeType.hexagon: + EditorGUILayout.PropertyField(serializedObject.FindProperty("width_relToViewportHeight_initialValue01"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("height_relToViewportHeight_initialValue01"), new GUIContent("Height", tooltip_explaining_relativeToViewPortHeight)); + break; + case (int)ShapeDrawer2D.ShapeType.septagon: + EditorGUILayout.PropertyField(serializedObject.FindProperty("width_relToViewportHeight_initialValue01"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("height_relToViewportHeight_initialValue01"), new GUIContent("Height", tooltip_explaining_relativeToViewPortHeight)); + break; + case (int)ShapeDrawer2D.ShapeType.octagon: + EditorGUILayout.PropertyField(serializedObject.FindProperty("width_relToViewportHeight_initialValue01"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("height_relToViewportHeight_initialValue01"), new GUIContent("Height", tooltip_explaining_relativeToViewPortHeight)); + break; + case (int)ShapeDrawer2D.ShapeType.decagon: + EditorGUILayout.PropertyField(serializedObject.FindProperty("width_relToViewportHeight_initialValue01"), new GUIContent("Width", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("height_relToViewportHeight_initialValue01"), new GUIContent("Height", tooltip_explaining_relativeToViewPortHeight)); + break; + case (int)ShapeDrawer2D.ShapeType.dot: + EditorGUILayout.PropertyField(serializedObject.FindProperty("radius_relToViewportHeight"), new GUIContent("Radius", tooltip_explaining_relativeToViewPortHeight)); + EditorGUILayout.PropertyField(serializedObject.FindProperty("dotDensity"), new GUIContent("Fill density", "Raise this if you want the dot to be more opaque.")); + break; + default: + break; + } + } + + void DrawGeneralOptions(SerializedProperty sP_shapeType) + { + bool isIcon = (sP_shapeType.enumValueIndex == (int)ShapeDrawer2D.ShapeType.icon); + bool isDot = (sP_shapeType.enumValueIndex == (int)ShapeDrawer2D.ShapeType.dot); + bool isStar = (sP_shapeType.enumValueIndex == (int)ShapeDrawer2D.ShapeType.star); + + if (isDot == false) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("zRotationDegCC"), new GUIContent("Rotation")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesWidth_relToViewportHeight"), new GUIContent("Lines width", tooltip_explaining_relativeToViewPortHeight)); + } + + if ((isIcon == false) && (isDot == false)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("lineStyle"), new GUIContent("Line style")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("stylePatternScaleFactor"), new GUIContent("Line style scaling")); + } + + bool displayFillstyleOption = ((isIcon == false) && (isDot == false) && (isStar == false)); + if (displayFillstyleOption) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("fillStyle"), new GUIContent("Fill style")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("shapeFillDensity"), new GUIContent("Fill density")); + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawPointerIfOffscreen"), new GUIContent("Draw pointer if off screen")); + if ((isIcon == false) && (isDot == false)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("addTextForOutsideDistance_toOffscreenPointer"), new GUIContent("Add text for outside screen distance", "This only applies if the shape position is outside of the viewport.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawHullEdgeLines_forScreenEncasingShapes"), new GUIContent("Draw indicator for screen encasing shapes", "This helps to identify and locate shapes that are (partly) bigger than the screen.")); + } + + DrawTextInputInclMarkupHelper(); + DrawCheckboxFor_drawOnlyIfSelected("shape"); + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/ShapeDrawerScreenspaceInspector.cs.meta b/Editor/DrawDebugLibrary/ShapeDrawerScreenspaceInspector.cs.meta new file mode 100644 index 0000000..3ef08c0 --- /dev/null +++ b/Editor/DrawDebugLibrary/ShapeDrawerScreenspaceInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 72934fc66d4837548937f8010c21850c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/TagDrawer2DInspector.cs b/Editor/DrawDebugLibrary/TagDrawer2DInspector.cs new file mode 100644 index 0000000..278126c --- /dev/null +++ b/Editor/DrawDebugLibrary/TagDrawer2DInspector.cs @@ -0,0 +1,183 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(TagDrawer2D))] + [CanEditMultipleObjects] + public class TagDrawer2DInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("tag2D"); + + EditorGUILayout.HelpBox("If you want to tag multiple gameobjects at once or want a pointer for offscreen objects you can use the 'Tag Drawer Screenspace' component instead.", MessageType.None, true); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + SerializedProperty sP_pointerSizeInterpretation = serializedObject.FindProperty("pointerSizeInterpretation"); + DrawTextSpecs(sP_pointerSizeInterpretation); + Draw_DrawPosition2DOffset(false, "Tagged Position: Offset From Transform"); + DrawSize_ofPointer(sP_pointerSizeInterpretation); + DrawCoordinatesOptions_ofPointer(sP_pointerSizeInterpretation); + + SerializedProperty sP_forcePointerDirection = serializedObject.FindProperty("forcePointerDirection"); + DrawSpecificationOf_customVector2_1("Force pointer direction", true, sP_forcePointerDirection, true, true, false, false); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("skipConeDrawing"), new GUIContent("Hide cone")); + Draw_sizeInterpretationDependentLine("linesWidth", "Lines width", "Lines width", null, sP_pointerSizeInterpretation); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color")); + DrawZPosChooserFor2D(); + DrawCheckboxFor_drawOnlyIfSelected("tag"); + DrawCheckboxFor_hiddenByNearerObjects("tag2D"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawTextSpecs(SerializedProperty sP_pointerSizeInterpretation) + { + //-> this fakes the appearance of beeing inside the parents text specification foldout + bool emptyLineAtEndIfOutfolded = false; + DrawTextInputInclMarkupHelper(true, false, null, emptyLineAtEndIfOutfolded); + + if (serializedObject.FindProperty("textSection_isOutfolded").boolValue == true) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + DrawFixedTextSize_ofPointer(sP_pointerSizeInterpretation); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawFixedTextSize_ofPointer(SerializedProperty sP_pointerSizeInterpretation) + { + if (CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace(sP_pointerSizeInterpretation) == false) + { + EditorGUILayout.LabelField("Text Size"); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_attachedTextsizeReferenceContext = serializedObject.FindProperty("attachedTextsizeReferenceContext"); + EditorGUILayout.PropertyField(sP_attachedTextsizeReferenceContext, new GUIContent("Relative to")); + + switch (sP_attachedTextsizeReferenceContext.enumValueIndex) + { + case (int)TagDrawer.AttachedTextsizeReferenceContext.extentOfTag: + break; + case (int)TagDrawer.AttachedTextsizeReferenceContext.globalSpace: + EditorGUILayout.PropertyField(serializedObject.FindProperty("pointerTextSize_value"), new GUIContent("Size per letter", "Text size in world units")); + break; + case (int)TagDrawer.AttachedTextsizeReferenceContext.sceneViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty("pointerTextSize_value_relToScreen"), new GUIContent("Size per letter", "Text size relative to Scene View window size.")); + break; + case (int)TagDrawer.AttachedTextsizeReferenceContext.gameViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty("pointerTextSize_value_relToScreen"), new GUIContent("Size per letter", "Text size relative to Game View window size.")); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawCoordinatesOptions_ofPointer(SerializedProperty sP_pointerSizeInterpretation) + { + SerializedProperty sP_drawGlobalCoordinates = serializedObject.FindProperty("drawGlobalCoordinates"); + EditorGUILayout.PropertyField(sP_drawGlobalCoordinates, new GUIContent("Draw global coordinates")); + + DrawSizeAndTextBoldness_forMarkingCross_ofPointer(sP_drawGlobalCoordinates, sP_pointerSizeInterpretation); + } + + void DrawSizeAndTextBoldness_forMarkingCross_ofPointer(SerializedProperty sP_drawGlobalCoordinates, SerializedProperty sP_pointerSizeInterpretation) + { + bool sizeOfMarkingCross_isGreyedOut = (sP_drawGlobalCoordinates.boolValue == false); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUI.BeginDisabledGroup(sizeOfMarkingCross_isGreyedOut); + Draw_sizeInterpretationDependentLine("sizeOfMarkingCross", "Size of coordinates", "Size of coordinates", null, sP_pointerSizeInterpretation); + EditorGUILayout.PropertyField(serializedObject.FindProperty("strokeWidth_forCoordinateTexts_onPointVisualiation_in0to1"), new GUIContent("Bold Text")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawSize_ofPointer(SerializedProperty sP_pointerSizeInterpretation) + { + SerializedProperty sP_textOffsetDistance_isOutfolded = serializedObject.FindProperty("textOffsetDistance_isOutfolded"); + sP_textOffsetDistance_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_textOffsetDistance_isOutfolded.boolValue, "Pointer Size", true); + if (sP_textOffsetDistance_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUILayout.PropertyField(sP_pointerSizeInterpretation, new GUIContent("Size interpretation", "The pointer size can be specified relative to a context of interest. The 'Length value' and along with it the text size will be interpreted according to the setting here.")); + + SerializedProperty sP_cameraForSizeDefinitionIsAvailable = serializedObject.FindProperty("cameraForSizeDefinitionIsAvailable"); + if (sP_cameraForSizeDefinitionIsAvailable.boolValue == false) + { + if (sP_pointerSizeInterpretation.enumValueIndex == (int)TagDrawer.PointerSizeInterpretation.relativeToTheSceneViewWindowSize) + { + EditorGUILayout.HelpBox("Scene View Camera Window is not available", MessageType.Warning, true); + } + + if (sP_pointerSizeInterpretation.enumValueIndex == (int)TagDrawer.PointerSizeInterpretation.relativeToTheGameViewWindowSize) + { + EditorGUILayout.HelpBox("No Game View Camera found.", MessageType.Warning, true); + } + } + + Draw_sizeInterpretationDependentLine("textOffsetDistance", "Length", "Length / Text size", null, sP_pointerSizeInterpretation); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + bool CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace(SerializedProperty sP_pointerSizeInterpretation) + { + return ((sP_pointerSizeInterpretation.enumValueIndex == (int)TagDrawer.PointerSizeInterpretation.relativeToTheSceneViewWindowSize) || (sP_pointerSizeInterpretation.enumValueIndex == (int)TagDrawer.PointerSizeInterpretation.relativeToTheGameViewWindowSize)); + } + + void Draw_sizeInterpretationDependentLine(string fieldName_withoutRelToScreenSuffix, string displayName, string displayName_ifRelToScreenSize, string tooltip, SerializedProperty sP_pointerSizeInterpretation) + { + GUIContent guiContent; + string toolTipSuffix = "This is relative to the reference frame defined by 'Size interpretation'"; + string used_displayName = CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace(sP_pointerSizeInterpretation) ? displayName_ifRelToScreenSize : displayName; + if (tooltip == null) + { + guiContent = new GUIContent(used_displayName, toolTipSuffix); + } + else + { + guiContent = new GUIContent(used_displayName, tooltip + Environment.NewLine + Environment.NewLine + toolTipSuffix); + } + + switch ((TagDrawer.PointerSizeInterpretation)sP_pointerSizeInterpretation.enumValueIndex) + { + case TagDrawer.PointerSizeInterpretation.absoluteUnits: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix), guiContent); + break; + case TagDrawer.PointerSizeInterpretation.relativeToGameobjectSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix), guiContent); + break; + case TagDrawer.PointerSizeInterpretation.relativeToTheSceneViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + "_relToScreen"), guiContent); + break; + case TagDrawer.PointerSizeInterpretation.relativeToTheGameViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + "_relToScreen"), guiContent); + break; + default: + break; + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/TagDrawer2DInspector.cs.meta b/Editor/DrawDebugLibrary/TagDrawer2DInspector.cs.meta new file mode 100644 index 0000000..99caa5b --- /dev/null +++ b/Editor/DrawDebugLibrary/TagDrawer2DInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f555426e775029e4197ab2b1d52f58e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/TagDrawerInspector.cs b/Editor/DrawDebugLibrary/TagDrawerInspector.cs new file mode 100644 index 0000000..5cd78b4 --- /dev/null +++ b/Editor/DrawDebugLibrary/TagDrawerInspector.cs @@ -0,0 +1,232 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(TagDrawer))] + [CanEditMultipleObjects] + public class TagDrawerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("tag"); + + EditorGUILayout.HelpBox("If you want to tag multiple gameobjects at once or want a pointer for offscreen objects you can use the 'Tag Drawer Screenspace' component instead.", MessageType.None, true); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + SerializedProperty sP_tagStyle = serializedObject.FindProperty("tagStyle"); + EditorGUILayout.PropertyField(sP_tagStyle, new GUIContent("Tag style")); + + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + + string displayNameOfMainColor = null; + switch (sP_tagStyle.enumValueIndex) + { + case (int)TagDrawer.TagStyle.pointer: + DrawSpecs_forPointer(); + displayNameOfMainColor = "Color"; + break; + case (int)TagDrawer.TagStyle.boxed: + DrawSpecs_forBoxed(); + displayNameOfMainColor = "Text color"; + break; + default: + break; + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForText"), new GUIContent(displayNameOfMainColor)); + DrawCheckboxFor_drawOnlyIfSelected("tag"); + DrawCheckboxFor_hiddenByNearerObjects("tag"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawSpecs_forPointer() + { + SerializedProperty sP_pointerSizeInterpretation = serializedObject.FindProperty("pointerSizeInterpretation"); + + DrawTextSpecs(sP_pointerSizeInterpretation); + Draw_DrawPosition3DOffset(false, "Tagged Position: Offset From Transform"); + DrawSize_ofPointer(sP_pointerSizeInterpretation); + DrawCoordinatesOptions_ofPointer(sP_pointerSizeInterpretation); + + SerializedProperty sP_forcePointerDirection = serializedObject.FindProperty("forcePointerDirection"); + DrawSpecificationOf_customVector3_1("Force pointer direction", true, sP_forcePointerDirection, true, true, false, false); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("skipConeDrawing"), new GUIContent("Hide cone")); + Draw_sizeInterpretationDependentLine("linesWidth", "Lines width", "Lines width", null, sP_pointerSizeInterpretation); + } + + void DrawTextSpecs(SerializedProperty sP_pointerSizeInterpretation) + { + //-> this fakes the appearance of beeing inside the parents text specification foldout + bool emptyLineAtEndIfOutfolded = false; + DrawTextInputInclMarkupHelper(true, false, null, emptyLineAtEndIfOutfolded); + + if (serializedObject.FindProperty("textSection_isOutfolded").boolValue == true) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + DrawFixedTextSize_ofPointer(sP_pointerSizeInterpretation); + GUILayout.Space(EditorGUIUtility.singleLineHeight); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawFixedTextSize_ofPointer(SerializedProperty sP_pointerSizeInterpretation) + { + if ((sP_pointerSizeInterpretation == null) || CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace(sP_pointerSizeInterpretation) == false) + { + EditorGUILayout.LabelField("Text Size"); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_attachedTextsizeReferenceContext = serializedObject.FindProperty("attachedTextsizeReferenceContext"); + EditorGUILayout.PropertyField(sP_attachedTextsizeReferenceContext, new GUIContent("Relative to")); + + switch (sP_attachedTextsizeReferenceContext.enumValueIndex) + { + case (int)TagDrawer.AttachedTextsizeReferenceContext.extentOfTag: + break; + case (int)TagDrawer.AttachedTextsizeReferenceContext.globalSpace: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value"), new GUIContent("Size per letter", "Text size in world units")); + break; + case (int)TagDrawer.AttachedTextsizeReferenceContext.sceneViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value_relToScreen"), new GUIContent("Size per letter", "Text size relative to Scene View window size.")); + break; + case (int)TagDrawer.AttachedTextsizeReferenceContext.gameViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty("textSize_value_relToScreen"), new GUIContent("Size per letter", "Text size relative to Game View window size.")); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + void DrawCoordinatesOptions_ofPointer(SerializedProperty sP_pointerSizeInterpretation) + { + SerializedProperty sP_drawGlobalCoordinates = serializedObject.FindProperty("drawGlobalCoordinates"); + SerializedProperty sP_drawLocalCoordinates = serializedObject.FindProperty("drawLocalCoordinates"); + EditorGUILayout.PropertyField(sP_drawGlobalCoordinates, new GUIContent("Draw global coordinates")); + + EditorGUI.BeginDisabledGroup(visualizerParentMonoBehaviour_unserialized.transform.parent == null); + EditorGUILayout.PropertyField(sP_drawLocalCoordinates, new GUIContent("Draw local coordinates")); + EditorGUI.EndDisabledGroup(); + + DrawSizeAndTextBoldness_ofMarkingCross_ofPointer(sP_drawGlobalCoordinates, sP_drawLocalCoordinates, sP_pointerSizeInterpretation); + } + + void DrawSizeAndTextBoldness_ofMarkingCross_ofPointer(SerializedProperty sP_drawGlobalCoordinates, SerializedProperty sP_drawLocalCoordinates, SerializedProperty sP_pointerSizeInterpretation) + { + bool sizeOfMarkingCross_isGreyedOut = ((sP_drawGlobalCoordinates.boolValue == false) && (sP_drawLocalCoordinates.boolValue == false)); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUI.BeginDisabledGroup(sizeOfMarkingCross_isGreyedOut); + Draw_sizeInterpretationDependentLine("sizeOfMarkingCross", "Size of coordinates", "Size of coordinates", null, sP_pointerSizeInterpretation); + EditorGUILayout.PropertyField(serializedObject.FindProperty("strokeWidth_forCoordinateTexts_onPointVisualiation_in0to1"), new GUIContent("Bold Text")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawSize_ofPointer(SerializedProperty sP_pointerSizeInterpretation) + { + SerializedProperty sP_textOffsetDistance_isOutfolded = serializedObject.FindProperty("textOffsetDistance_isOutfolded"); + sP_textOffsetDistance_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_textOffsetDistance_isOutfolded.boolValue, "Pointer Size", true); + if (sP_textOffsetDistance_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUILayout.PropertyField(sP_pointerSizeInterpretation, new GUIContent("Size interpretation", "The pointer size can be specified relative to a context of interest. The 'Length value' and along with it the text size will be interpreted according to the setting here.")); + + SerializedProperty sP_cameraForSizeDefinitionIsAvailable = serializedObject.FindProperty("cameraForSizeDefinitionIsAvailable"); + if (sP_cameraForSizeDefinitionIsAvailable.boolValue == false) + { + if (sP_pointerSizeInterpretation.enumValueIndex == (int)TagDrawer.PointerSizeInterpretation.relativeToTheSceneViewWindowSize) + { + EditorGUILayout.HelpBox("Scene View Camera Window is not available", MessageType.Warning, true); + } + + if (sP_pointerSizeInterpretation.enumValueIndex == (int)TagDrawer.PointerSizeInterpretation.relativeToTheGameViewWindowSize) + { + EditorGUILayout.HelpBox("No Game View Camera found.", MessageType.Warning, true); + } + } + + Draw_sizeInterpretationDependentLine("textOffsetDistance", "Length", "Length / Text size", null, sP_pointerSizeInterpretation); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + bool CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace(SerializedProperty sP_pointerSizeInterpretation) + { + return ((sP_pointerSizeInterpretation.enumValueIndex == (int)TagDrawer.PointerSizeInterpretation.relativeToTheSceneViewWindowSize) || (sP_pointerSizeInterpretation.enumValueIndex == (int)TagDrawer.PointerSizeInterpretation.relativeToTheGameViewWindowSize)); + } + + void Draw_sizeInterpretationDependentLine(string fieldName_withoutRelToScreenSuffix, string displayName, string displayName_ifRelToScreenSize, string tooltip, SerializedProperty sP_pointerSizeInterpretation) + { + GUIContent guiContent; + string toolTipSuffix = "This is relative to the reference frame defined by 'Size interpretation'"; + string used_displayName = CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace(sP_pointerSizeInterpretation) ? displayName_ifRelToScreenSize : displayName; + if (tooltip == null) + { + guiContent = new GUIContent(used_displayName, toolTipSuffix); + } + else + { + guiContent = new GUIContent(used_displayName, tooltip + Environment.NewLine + Environment.NewLine + toolTipSuffix); + } + + switch ((TagDrawer.PointerSizeInterpretation)sP_pointerSizeInterpretation.enumValueIndex) + { + case TagDrawer.PointerSizeInterpretation.absoluteUnits: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix), guiContent); + break; + case TagDrawer.PointerSizeInterpretation.relativeToGameobjectSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix), guiContent); + break; + case TagDrawer.PointerSizeInterpretation.relativeToTheSceneViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + "_relToScreen"), guiContent); + break; + case TagDrawer.PointerSizeInterpretation.relativeToTheGameViewWindowSize: + EditorGUILayout.PropertyField(serializedObject.FindProperty(fieldName_withoutRelToScreenSuffix + "_relToScreen"), guiContent); + break; + default: + break; + } + } + + void DrawSpecs_forBoxed() + { + DrawTextSpecs(null); + DrawDifferentBoxColor_ofBoxed(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("encapsulateChildren"), new GUIContent("Encapsulate children")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("textBlockAboveLine"), new GUIContent("Text block above line")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesWidth"), new GUIContent("Lines width")); + } + + void DrawDifferentBoxColor_ofBoxed() + { + SerializedProperty sP_differentBoxColor = serializedObject.FindProperty("differentBoxColor"); + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_differentBoxColor, new GUIContent("Custom box color", "With this you can define a color for the box that differs from the text color.")); + EditorGUI.BeginDisabledGroup(!sP_differentBoxColor.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("differentBoxColor_value"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/TagDrawerInspector.cs.meta b/Editor/DrawDebugLibrary/TagDrawerInspector.cs.meta new file mode 100644 index 0000000..0016c45 --- /dev/null +++ b/Editor/DrawDebugLibrary/TagDrawerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a51a954ea1e597943843bf58a5200ceb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/TagDrawerScreenspaceInspector.cs b/Editor/DrawDebugLibrary/TagDrawerScreenspaceInspector.cs new file mode 100644 index 0000000..9059e26 --- /dev/null +++ b/Editor/DrawDebugLibrary/TagDrawerScreenspaceInspector.cs @@ -0,0 +1,153 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(TagDrawerScreenspace))] + [CanEditMultipleObjects] + public class TagDrawerScreenspaceInspector : VisualizerScreenspaceParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("tag"); + if (DrawCameraChooser(true)) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + SerializedProperty sP_taggedPositionType = serializedObject.FindProperty("taggedPositionType"); + EditorGUILayout.PropertyField(sP_taggedPositionType, new GUIContent("Tagged position type")); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + string displayNameOfMainColor = null; + DrawIndividualSpecsForEachTaggedPositionType(sP_taggedPositionType, ref displayNameOfMainColor); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("linesWidth_relToViewportHeight"), new GUIContent("Lines width", "This is relative to the viewport height.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("colorForText"), new GUIContent(displayNameOfMainColor)); + DrawCheckboxFor_drawOnlyIfSelected("screenspace tag"); + } + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawIndividualSpecsForEachTaggedPositionType(SerializedProperty sP_taggedPositionType, ref string displayNameOfMainColor) + { + switch (sP_taggedPositionType.enumValueIndex) + { + case (int)TagDrawerScreenspace.TaggedPositionType.positionOnViewport: + DrawSpecsFor_positionOnViewport(ref displayNameOfMainColor); + break; + case (int)TagDrawerScreenspace.TaggedPositionType.aGameobject: + DrawSpecsFor_aGameobject(ref displayNameOfMainColor); + break; + case (int)TagDrawerScreenspace.TaggedPositionType.multipleGameobjects: + DrawSpecsFor_multipleGameobjects(ref displayNameOfMainColor); + break; + default: + break; + } + } + + void DrawSpecsFor_positionOnViewport(ref string displayNameOfMainColor) + { + DrawTextInputInclMarkupHelper(true, true); + EditorGUILayout.PropertyField(serializedObject.FindProperty("positionInsideViewport0to1"), new GUIContent("Position (inside viewport)")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("textOffsetDistance_relToViewportHeight"), new GUIContent("Pointer size", "This is relative to the viewport height.")); + Draw_pointerDirectionSpecificationType(); + DrawForceTextSize_caseFlexiblePointerLength(); + Draw_offScreenBehaviour_forCaseOf_positionOnViewport(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("skipConeDrawing"), new GUIContent("Hide cone", "This only applies if the position is inside of the viewport.")); + displayNameOfMainColor = "Color"; + } + + void Draw_pointerDirectionSpecificationType() + { + SerializedProperty sP_pointerDirectionSpecificationType = serializedObject.FindProperty("pointerDirectionSpecificationType"); + EditorGUILayout.PropertyField(sP_pointerDirectionSpecificationType, new GUIContent("Pointer direction")); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + switch (sP_pointerDirectionSpecificationType.enumValueIndex) + { + case (int)TagDrawerScreenspace.PointerDirectionSpecificationType.fixedAngle: + EditorGUILayout.PropertyField(serializedObject.FindProperty("fixedPointerDiretion_angledDegCC"), new GUIContent("Angle")); + break; + case (int)TagDrawerScreenspace.PointerDirectionSpecificationType.vanishingPointPosition: + EditorGUILayout.PropertyField(serializedObject.FindProperty("positionInsideViewport0to1_v2"), new GUIContent("Vanishing point")); + break; + default: + break; + } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void Draw_offScreenBehaviour_forCaseOf_positionOnViewport() + { + SerializedProperty sP_drawPointerIfOffscreen = serializedObject.FindProperty("drawPointerIfOffscreen"); + EditorGUILayout.PropertyField(sP_drawPointerIfOffscreen, new GUIContent("Draw indicator if off screen")); + + EditorGUI.BeginDisabledGroup(!sP_drawPointerIfOffscreen.boolValue); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + GUIContent guiContent_for_addTextForOutsideDistance_toOffscreenPointer = new GUIContent("Add text for outside screen distance", "This only applies if the position is outside of the viewport."); + if (sP_drawPointerIfOffscreen.boolValue) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("addTextForOutsideDistance_toOffscreenPointer"), guiContent_for_addTextForOutsideDistance_toOffscreenPointer); + } + else + { + EditorGUILayout.Toggle(guiContent_for_addTextForOutsideDistance_toOffscreenPointer, false); + } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + EditorGUI.EndDisabledGroup(); + } + + void DrawSpecsFor_aGameobject(ref string displayNameOfMainColor) + { + DrawTextInputInclMarkupHelper(true, true); + EditorGUILayout.PropertyField(serializedObject.FindProperty("partnerGameobject"), new GUIContent("Tagged gameobject")); + DrawDifferentBoxColor(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("encapsulateChildren"), new GUIContent("Encapsulate children")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawPointerIfOffscreen"), new GUIContent("Draw indicator if off screen")); + displayNameOfMainColor = "Text color"; + } + + void DrawSpecsFor_multipleGameobjects(ref string displayNameOfMainColor) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("taggedScreenspaceObjects"), new GUIContent("Tagged gameobjects")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("encapsulateChildren"), new GUIContent("Encapsulate children")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawPointerIfOffscreen"), new GUIContent("Draw indicator if off screen")); + displayNameOfMainColor = "Text color"; + } + + void DrawForceTextSize_caseFlexiblePointerLength() + { + SerializedProperty sP_forceTextSize = serializedObject.FindProperty("forceTextSize"); + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_forceTextSize, new GUIContent("Fixed text size", "This prevents the text size from scaling with the pointer length." + Environment.NewLine + Environment.NewLine + "The text size can still be scaled via 'Text/Style/Size scaling'.")); + EditorGUI.BeginDisabledGroup(!sP_forceTextSize.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("forceTextSize_value"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + } + + void DrawDifferentBoxColor() + { + SerializedProperty sP_differentBoxColor = serializedObject.FindProperty("differentBoxColor"); + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_differentBoxColor, new GUIContent("Custom box color", "With this you can define a color for the box that differs from the text color.")); + EditorGUI.BeginDisabledGroup(!sP_differentBoxColor.boolValue); + EditorGUILayout.PropertyField(serializedObject.FindProperty("differentBoxColor_value"), GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/TagDrawerScreenspaceInspector.cs.meta b/Editor/DrawDebugLibrary/TagDrawerScreenspaceInspector.cs.meta new file mode 100644 index 0000000..b95187e --- /dev/null +++ b/Editor/DrawDebugLibrary/TagDrawerScreenspaceInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2b1d6f41cdb0fe4481ed98905895d3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/TextDrawer2DInspector.cs b/Editor/DrawDebugLibrary/TextDrawer2DInspector.cs new file mode 100644 index 0000000..9c05549 --- /dev/null +++ b/Editor/DrawDebugLibrary/TextDrawer2DInspector.cs @@ -0,0 +1,39 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(TextDrawer2D))] + [CanEditMultipleObjects] + public class TextDrawer2DInspector : TextDrawerInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("text"); + DrawTextInputInclMarkupHelper(true, true, "Drawn text:"); + DrawSpecificationOf_customVector2_1("Text direction", false, null, true, true, true, false); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color", "This can be overwritten by 'Text/Style/Colored', but then still defines the color of a frame box.")); + SerializedProperty sP_sizeInterpretation = serializedObject.FindProperty("sizeInterpretation"); + SerializedProperty sP_forceTextEnlargementToThisMinWidth = serializedObject.FindProperty("forceTextEnlargementToThisMinWidth"); + SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth = serializedObject.FindProperty("forceRestrictTextSizeToThisMaxTextWidth"); + DrawSizeSpecs(sP_sizeInterpretation, sP_forceTextEnlargementToThisMinWidth, sP_forceRestrictTextSizeToThisMaxTextWidth, "The here used gameobject size is defined by the biggest absolute global scale dimension (excluding z) of the transform."); + EditorGUILayout.PropertyField(serializedObject.FindProperty("textAnchor"), new GUIContent("Text anchor")); + DrawFrameBoxSpecs(); + Draw_TextBlockConstraints(sP_sizeInterpretation, sP_forceTextEnlargementToThisMinWidth, sP_forceRestrictTextSizeToThisMaxTextWidth); + EditorGUILayout.PropertyField(serializedObject.FindProperty("autoFlipToPreventMirrorInverted"), new GUIContent("Auto flip to prevent mirror inverted", "This flips the text horizontally so it is always non-mirrored readable in the camera specified by the settings above or else by 'DrawBasics.cameraForAutomaticOrientation'.")); + Draw_DrawPosition2DOffset(); + DrawZPosChooserFor2D(); + DrawCheckboxFor_drawOnlyIfSelected("text"); + DrawCheckboxFor_hiddenByNearerObjects("text"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + } +#endif +} diff --git a/Editor/DrawDebugLibrary/TextDrawer2DInspector.cs.meta b/Editor/DrawDebugLibrary/TextDrawer2DInspector.cs.meta new file mode 100644 index 0000000..83d10a6 --- /dev/null +++ b/Editor/DrawDebugLibrary/TextDrawer2DInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1971e4e62afdc924596df57f1e5a8b5c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/TextDrawerInspector.cs b/Editor/DrawDebugLibrary/TextDrawerInspector.cs new file mode 100644 index 0000000..8ae4f81 --- /dev/null +++ b/Editor/DrawDebugLibrary/TextDrawerInspector.cs @@ -0,0 +1,301 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(TextDrawer))] + [CanEditMultipleObjects] + public class TextDrawerInspector : VisualizerParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("text"); + DrawTextInputInclMarkupHelper(true, true, "Drawn text:"); + SerializedProperty sP_forceTextTo_facingToSceneViewCam = serializedObject.FindProperty("forceTextTo_facingToSceneViewCam"); + SerializedProperty sP_forceTextTo_facingToGameViewCam = serializedObject.FindProperty("forceTextTo_facingToGameViewCam"); + DrawOrientationSpecs(sP_forceTextTo_facingToSceneViewCam, sP_forceTextTo_facingToGameViewCam); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color", "This can be overwritten by 'Text/Style/Colored', but then still defines the color of a frame box.")); + SerializedProperty sP_sizeInterpretation = serializedObject.FindProperty("sizeInterpretation"); + SerializedProperty sP_forceTextEnlargementToThisMinWidth = serializedObject.FindProperty("forceTextEnlargementToThisMinWidth"); + SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth = serializedObject.FindProperty("forceRestrictTextSizeToThisMaxTextWidth"); + DrawSizeSpecs(sP_sizeInterpretation, sP_forceTextEnlargementToThisMinWidth, sP_forceRestrictTextSizeToThisMaxTextWidth, "The here used gameobject size is defined by the biggest absolute global scale dimension of the transform."); + EditorGUILayout.PropertyField(serializedObject.FindProperty("textAnchor"), new GUIContent("Text anchor")); + DrawFrameBoxSpecs(); + Draw_TextBlockConstraints(sP_sizeInterpretation, sP_forceTextEnlargementToThisMinWidth, sP_forceRestrictTextSizeToThisMaxTextWidth); + DrawAutoFlipCheckbox(sP_forceTextTo_facingToSceneViewCam, sP_forceTextTo_facingToGameViewCam); + Draw_DrawPosition3DOffset(); + DrawCheckboxFor_drawOnlyIfSelected("text"); + DrawCheckboxFor_hiddenByNearerObjects("text"); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + void DrawOrientationSpecs(SerializedProperty sP_forceTextTo_facingToSceneViewCam, SerializedProperty sP_forceTextTo_facingToGameViewCam) + { + bool forceToSceneViewCam_isGreyedOut = false; + bool forceToGameViewCam_isGreyedOut = false; + + if (sP_forceTextTo_facingToGameViewCam.boolValue == true) + { + sP_forceTextTo_facingToSceneViewCam.boolValue = false; + forceToSceneViewCam_isGreyedOut = true; + } + + if (sP_forceTextTo_facingToSceneViewCam.boolValue == true) + { + sP_forceTextTo_facingToGameViewCam.boolValue = false; + forceToGameViewCam_isGreyedOut = true; + } + + EditorGUI.BeginDisabledGroup(forceToSceneViewCam_isGreyedOut); + EditorGUILayout.PropertyField(sP_forceTextTo_facingToSceneViewCam, new GUIContent("Force facing to Scene view camera")); + EditorGUI.EndDisabledGroup(); + + EditorGUI.BeginDisabledGroup(forceToGameViewCam_isGreyedOut); + EditorGUILayout.PropertyField(sP_forceTextTo_facingToGameViewCam, new GUIContent("Force facing to Game view camera")); + EditorGUI.EndDisabledGroup(); + + if (sP_forceTextTo_facingToGameViewCam.boolValue == true) + { + visualizerParentMonoBehaviour_unserialized.customVector3Configs[2].observerCamera = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + visualizerParentMonoBehaviour_unserialized.customVector3Configs[3].observerCamera = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + } + + if (sP_forceTextTo_facingToSceneViewCam.boolValue == true) + { + visualizerParentMonoBehaviour_unserialized.customVector3Configs[2].observerCamera = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + visualizerParentMonoBehaviour_unserialized.customVector3Configs[3].observerCamera = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + } + + visualizerParentMonoBehaviour_unserialized.customVector3Configs[2].source = VisualizerParent.CustomVector3Source.observerCameraRight; + visualizerParentMonoBehaviour_unserialized.customVector3Configs[3].source = VisualizerParent.CustomVector3Source.observerCameraUp; + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + bool customVectorPickers_useGreyedOutVectors_3and4 = ((sP_forceTextTo_facingToGameViewCam.boolValue == true) || (sP_forceTextTo_facingToSceneViewCam.boolValue == true)); + if (customVectorPickers_useGreyedOutVectors_3and4) + { + EditorGUI.BeginDisabledGroup(true); + DrawSpecificationOf_customVector3_3("Text direction", false, null, true, true, true, false); + DrawSpecificationOf_customVector3_4("Text upward direction", false, null, true, true, true, true); + EditorGUI.EndDisabledGroup(); + } + else + { + DrawSpecificationOf_customVector3_1("Text direction", false, null, true, true, true, false); + DrawSpecificationOf_customVector3_2("Text upward direction", false, null, true, true, true, true); + } + } + + public void DrawSizeSpecs(SerializedProperty sP_sizeInterpretation, SerializedProperty sP_forceTextEnlargementToThisMinWidth, SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth, string tooltip_for_relToGamebobjecSizeInterpretation) + { + SerializedProperty sP_size_isOutfolded = serializedObject.FindProperty("size_isOutfolded"); + sP_size_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_size_isOutfolded.boolValue, "Text Size", true); + if (sP_size_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.HelpBox("This defines the width per letter.", MessageType.None, true); + + EditorGUILayout.PropertyField(sP_sizeInterpretation, new GUIContent("Relative to", "The text size can be specified relative to a context of interest. The following size value will be scaled according to this interpretation setting here.")); + + string name_ofSizeLine = "Size value"; + switch (sP_sizeInterpretation.enumValueIndex) + { + case (int)TextDrawer.SizeInterpretation.globalSpace: + EditorGUILayout.PropertyField(serializedObject.FindProperty("size"), new GUIContent(name_ofSizeLine)); + break; + case (int)TextDrawer.SizeInterpretation.sizeOfGameobject: + EditorGUILayout.PropertyField(serializedObject.FindProperty("size"), new GUIContent(name_ofSizeLine, tooltip_for_relToGamebobjecSizeInterpretation)); + break; + case (int)TextDrawer.SizeInterpretation.sceneViewWindowWidth: + EditorGUILayout.PropertyField(serializedObject.FindProperty("size_relToScreen"), new GUIContent(name_ofSizeLine)); + break; + case (int)TextDrawer.SizeInterpretation.gameViewWindowWidth: + EditorGUILayout.PropertyField(serializedObject.FindProperty("size_relToScreen"), new GUIContent(name_ofSizeLine)); + break; + default: + break; + } + + if (sP_forceTextEnlargementToThisMinWidth.boolValue || sP_forceRestrictTextSizeToThisMaxTextWidth.boolValue) + { + EditorGUILayout.HelpBox("This text size may get overwritten due to the activated 'Minimum/Maximum text block width'.", MessageType.None, false); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + GUILayout.Space(0.75f * EditorGUIUtility.singleLineHeight); + } + } + + public void DrawFrameBoxSpecs() + { + SerializedProperty sP_enclosingBox_isOutfolded = serializedObject.FindProperty("enclosingBox_isOutfolded"); + GUIContent guiContent_ofFrameBoxHeader = new GUIContent("Frame box", "If you want to have a different color for the box and the text you can use 'Text/Style/Colored' to overwrite the text color."); + sP_enclosingBox_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_enclosingBox_isOutfolded.boolValue, guiContent_ofFrameBoxHeader, true); + if (sP_enclosingBox_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_enclosingBoxLineStyle = serializedObject.FindProperty("enclosingBoxLineStyle"); + EditorGUILayout.PropertyField(sP_enclosingBoxLineStyle, new GUIContent("Style")); + bool enclosingBoxIsDisabled = sP_enclosingBoxLineStyle.enumValueIndex == (int)DrawBasics.LineStyle.invisible; + + EditorGUI.BeginDisabledGroup(enclosingBoxIsDisabled); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enclosingBox_lineWidth_relToTextSize"), new GUIContent("Width", "This is relative to the text size.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enclosingBox_paddingSize_relToTextSize"), new GUIContent("Padding", "This is relative to the text size.")); + EditorGUI.EndDisabledGroup(); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + public void Draw_TextBlockConstraints(SerializedProperty sP_sizeInterpretation, SerializedProperty sP_forceTextEnlargementToThisMinWidth, SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth) + { + SerializedProperty sP_autoLineBreakWidth_isOutfolded = serializedObject.FindProperty("autoLineBreakWidth_isOutfolded"); + SerializedProperty sP_autoLineBreakWidth = serializedObject.FindProperty("autoLineBreakWidth"); + SerializedProperty sP_autoLineBreakWidth_value = serializedObject.FindProperty("autoLineBreakWidth_value"); + SerializedProperty sP_autoLineBreakWidth_value_relToScreen = serializedObject.FindProperty("autoLineBreakWidth_value_relToScreen"); + SerializedProperty sP_autoLineBreakWidth_interpretation = serializedObject.FindProperty("autoLineBreakWidth_interpretation"); + + SerializedProperty sP_forceTextEnlargementToThisMinWidth_isOutfolded = serializedObject.FindProperty("forceTextEnlargementToThisMinWidth_isOutfolded"); + SerializedProperty sP_forceTextEnlargementToThisMinWidth_value = serializedObject.FindProperty("forceTextEnlargementToThisMinWidth_value"); + SerializedProperty sP_forceTextEnlargementToThisMinWidth_value_relToScreen = serializedObject.FindProperty("forceTextEnlargementToThisMinWidth_value_relToScreen"); + SerializedProperty sP_forceTextEnlargementToThisMinWidth_interpretation = serializedObject.FindProperty("forceTextEnlargementToThisMinWidth_interpretation"); + + SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth_isOutfolded = serializedObject.FindProperty("forceRestrictTextSizeToThisMaxTextWidth_isOutfolded"); + SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth_value = serializedObject.FindProperty("forceRestrictTextSizeToThisMaxTextWidth_value"); + SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth_value_relToScreen = serializedObject.FindProperty("forceRestrictTextSizeToThisMaxTextWidth_value_relToScreen"); + SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth_interpretation = serializedObject.FindProperty("forceRestrictTextSizeToThisMaxTextWidth_interpretation"); + + GUIContent used_GUIContent; + GUIContent used_GUIContentOfEnableToggle; + + string helpBoxText_for_autoLineBreakWidth = "This automatically inserts line breaks into the text, so that the width of the whole text block doesn't exceed the specified width."; + used_GUIContent = new GUIContent("Automatic line breaks"); + used_GUIContentOfEnableToggle = new GUIContent("Force line breaks after width span"); + Draw_TextBlockConstraint(used_GUIContent, used_GUIContentOfEnableToggle, "Maximum line width", helpBoxText_for_autoLineBreakWidth, sP_autoLineBreakWidth_isOutfolded, sP_autoLineBreakWidth, sP_autoLineBreakWidth_value, sP_autoLineBreakWidth_value_relToScreen, sP_autoLineBreakWidth_interpretation, sP_sizeInterpretation); + + string helpBoxText_for_forceTextEnlargementToThisMinWidth = "This overwrites the text size and rescales the text, so that the whole text block has at least the specified width."; + used_GUIContent = new GUIContent("Minimum text block width"); + used_GUIContentOfEnableToggle = new GUIContent("Force text enlargement to reach a minimum text block width"); + EditorGUI.BeginChangeCheck(); + Draw_TextBlockConstraint(used_GUIContent, used_GUIContentOfEnableToggle, "Minimum text block width", helpBoxText_for_forceTextEnlargementToThisMinWidth, sP_forceTextEnlargementToThisMinWidth_isOutfolded, sP_forceTextEnlargementToThisMinWidth, sP_forceTextEnlargementToThisMinWidth_value, sP_forceTextEnlargementToThisMinWidth_value_relToScreen, sP_forceTextEnlargementToThisMinWidth_interpretation, sP_sizeInterpretation); + bool minWidth_changed = EditorGUI.EndChangeCheck(); + + string helpBoxText_for_forceRestrictTextSizeToThisMaxTextWidth = "This overwrites the text size and rescales the text, so that the whole text block is not wider then the specified width." + Environment.NewLine + "If you want restrict the text block width but keep the text size you can use 'Automatic line breaks'."; + used_GUIContent = new GUIContent("Maximum text block width"); + used_GUIContentOfEnableToggle = new GUIContent("Force restrict the text block width to a maximum"); + EditorGUI.BeginChangeCheck(); + Draw_TextBlockConstraint(used_GUIContent, used_GUIContentOfEnableToggle, "Maximum text block width", helpBoxText_for_forceRestrictTextSizeToThisMaxTextWidth, sP_forceRestrictTextSizeToThisMaxTextWidth_isOutfolded, sP_forceRestrictTextSizeToThisMaxTextWidth, sP_forceRestrictTextSizeToThisMaxTextWidth_value, sP_forceRestrictTextSizeToThisMaxTextWidth_value_relToScreen, sP_forceRestrictTextSizeToThisMaxTextWidth_interpretation, sP_sizeInterpretation); + bool maxWidth_changed = EditorGUI.EndChangeCheck(); + + if (minWidth_changed) + { + sP_forceRestrictTextSizeToThisMaxTextWidth_value.floatValue = Mathf.Max(sP_forceTextEnlargementToThisMinWidth_value.floatValue, sP_forceRestrictTextSizeToThisMaxTextWidth_value.floatValue); + } + else + { + if (maxWidth_changed) + { + sP_forceTextEnlargementToThisMinWidth_value.floatValue = Mathf.Min(sP_forceTextEnlargementToThisMinWidth_value.floatValue, sP_forceRestrictTextSizeToThisMaxTextWidth_value.floatValue); + } + } + } + + void Draw_TextBlockConstraint(GUIContent used_GUIContentOfHeadline, GUIContent used_GUIContentOfEnableToggle, string used_nameString_ofValue, string helpBoxText, SerializedProperty sP_isOutfoldedProperty, SerializedProperty sP_boolProperty, SerializedProperty sP_floatProperty, SerializedProperty sP_floatProperty_relToScreen, SerializedProperty sP_blockConstraintInterpretationProperty, SerializedProperty sP_sizeInterpretation) + { + sP_isOutfoldedProperty.boolValue = EditorGUILayout.Foldout(sP_isOutfoldedProperty.boolValue, used_GUIContentOfHeadline, true); + if (sP_isOutfoldedProperty.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUILayout.HelpBox(helpBoxText, MessageType.None, true); + EditorGUILayout.PropertyField(sP_boolProperty, used_GUIContentOfEnableToggle); + EditorGUI.BeginDisabledGroup(!sP_boolProperty.boolValue); + + if (CheckIf_blockWidthConstraintValue_isDependentOn_screenWindowSize(sP_blockConstraintInterpretationProperty, sP_sizeInterpretation)) + { + EditorGUILayout.PropertyField(sP_floatProperty_relToScreen, new GUIContent(used_nameString_ofValue)); + } + else + { + EditorGUILayout.PropertyField(sP_floatProperty, new GUIContent(used_nameString_ofValue)); + } + + EditorGUILayout.PropertyField(sP_blockConstraintInterpretationProperty, new GUIContent("Value interpretation", "The value can be specified relative to a context of interest." + Environment.NewLine + "The '" + used_nameString_ofValue + "' value from the previous line will be scaled according to this interpretation setting here.")); + + if (sP_blockConstraintInterpretationProperty.enumValueIndex == (int)TextDrawer.SizeInterpretationInclFallback.relativeToTheSameAsTextSize) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.PropertyField(sP_sizeInterpretation, new GUIContent("Text Size is relative to")); + EditorGUI.EndDisabledGroup(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + EditorGUI.EndDisabledGroup(); + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + bool CheckIf_blockWidthConstraintValue_isDependentOn_screenWindowSize(SerializedProperty sP_blockConstraintInterpretationProperty, SerializedProperty sP_sizeInterpretation) + { + switch (sP_blockConstraintInterpretationProperty.enumValueIndex) + { + case (int)TextDrawer.SizeInterpretationInclFallback.relativeToTheSameAsTextSize: + switch (sP_sizeInterpretation.enumValueIndex) + { + case (int)TextDrawer.SizeInterpretation.globalSpace: + return false; + case (int)TextDrawer.SizeInterpretation.sizeOfGameobject: + return false; + case (int)TextDrawer.SizeInterpretation.sceneViewWindowWidth: + return true; + case (int)TextDrawer.SizeInterpretation.gameViewWindowWidth: + return true; + default: + return false; + } + case (int)TextDrawer.SizeInterpretationInclFallback.absoluteUnits: + return false; + case (int)TextDrawer.SizeInterpretationInclFallback.relativeToGameobjectSize: + return false; + case (int)TextDrawer.SizeInterpretationInclFallback.relativeToTheSceneViewWindowWidth: + return true; + case (int)TextDrawer.SizeInterpretationInclFallback.relativeToTheGameViewWindowWidth: + return true; + default: + return false; + } + } + + void DrawAutoFlipCheckbox(SerializedProperty sP_forceTextTo_facingToSceneViewCam, SerializedProperty sP_forceTextTo_facingToGameViewCam) + { + if ((sP_forceTextTo_facingToGameViewCam.boolValue == true) || (sP_forceTextTo_facingToSceneViewCam.boolValue == true)) + { + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.Toggle(new GUIContent("Auto flip to prevent mirror inverted", "Only available if 'Force facing to a camera' is disabled."), true); + EditorGUI.EndDisabledGroup(); + } + else + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("autoFlipToPreventMirrorInverted"), new GUIContent("Auto flip to prevent mirror inverted", "This flips the text horizontally so it is always non-mirrored readable in the camera specified by the 'Force facing to a camera' settings above or else by 'DrawBasics.cameraForAutomaticOrientation'.")); + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/TextDrawerInspector.cs.meta b/Editor/DrawDebugLibrary/TextDrawerInspector.cs.meta new file mode 100644 index 0000000..7729eaf --- /dev/null +++ b/Editor/DrawDebugLibrary/TextDrawerInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dfab7e1fe45865d459f908a32081404b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/TextDrawerScreenspaceInspector.cs b/Editor/DrawDebugLibrary/TextDrawerScreenspaceInspector.cs new file mode 100644 index 0000000..5ec66d2 --- /dev/null +++ b/Editor/DrawDebugLibrary/TextDrawerScreenspaceInspector.cs @@ -0,0 +1,131 @@ +namespace DrawXXL +{ + using UnityEngine; + using System; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(TextDrawerScreenspace))] + [CanEditMultipleObjects] + public class TextDrawerScreenspaceInspector : VisualizerScreenspaceParentInspector + { + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + DrawConsumedLines("text"); + if (DrawCameraChooser(true)) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + + DrawTextInputInclMarkupHelper(true, true, "Drawn text:"); + DrawSpecificationOf_customVector2_1("Text direction", false, null, true, true, true, false); + EditorGUILayout.PropertyField(serializedObject.FindProperty("color"), new GUIContent("Color", "This can be overwritten by 'Text/Style/Colored', but then still defines the color of a frame box.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("size_relToViewportHeight"), new GUIContent("Size", "This is the width per letter, relative to the viewport height.")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("textAnchor"), new GUIContent("Text anchor")); + DrawFrameBoxSpecs(); + Draw_ToggleableFloatSliders(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("autoLineBreakAtScreenBorder"), new GUIContent("Automatic line break at viewport border")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("autoFlipTextToPreventUpsideDown"), new GUIContent("Automatic horizontal flip to prevent upside down")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("positionInsideViewport0to1"), new GUIContent("Position (inside viewport)")); + DrawCheckboxFor_drawOnlyIfSelected("screenspace text"); + } + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + public void DrawFrameBoxSpecs() + { + SerializedProperty sP_enclosingBox_isOutfolded = serializedObject.FindProperty("enclosingBox_isOutfolded"); + GUIContent guiContent_ofFrameBoxHeader = new GUIContent("Frame box", "If you want to have a different color for the box and the text you can use 'Text/Style/Colored' to overwrite the text color."); + sP_enclosingBox_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_enclosingBox_isOutfolded.boolValue, guiContent_ofFrameBoxHeader, true); + if (sP_enclosingBox_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_enclosingBoxLineStyle = serializedObject.FindProperty("enclosingBoxLineStyle"); + EditorGUILayout.PropertyField(sP_enclosingBoxLineStyle, new GUIContent("Style")); + bool enclosingBoxIsDisabled = sP_enclosingBoxLineStyle.enumValueIndex == (int)DrawBasics.LineStyle.invisible; + + EditorGUI.BeginDisabledGroup(enclosingBoxIsDisabled); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enclosingBox_lineWidth_relToTextSize"), new GUIContent("Width")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("enclosingBox_paddingSize_relToTextSize"), new GUIContent("Padding")); + EditorGUI.EndDisabledGroup(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + public void Draw_ToggleableFloatSliders() + { + SerializedProperty sP_autoLineBreakWidth_relToViewportWidth_isOutfolded = serializedObject.FindProperty("autoLineBreakWidth_relToViewportWidth_isOutfolded"); + SerializedProperty sP_autoLineBreakWidth_relToViewportWidth = serializedObject.FindProperty("autoLineBreakWidth_relToViewportWidth"); + SerializedProperty sP_autoLineBreakWidth_relToViewportWidth_value = serializedObject.FindProperty("autoLineBreakWidth_relToViewportWidth_value"); + + SerializedProperty sP_forceTextEnlargementToThisMinWidth_relToViewportWidth_isOutfolded = serializedObject.FindProperty("forceTextEnlargementToThisMinWidth_relToViewportWidth_isOutfolded"); + SerializedProperty sP_forceTextEnlargementToThisMinWidth_relToViewportWidth = serializedObject.FindProperty("forceTextEnlargementToThisMinWidth_relToViewportWidth"); + SerializedProperty sP_forceTextEnlargementToThisMinWidth_relToViewportWidth_value = serializedObject.FindProperty("forceTextEnlargementToThisMinWidth_relToViewportWidth_value"); + + SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_isOutfolded = serializedObject.FindProperty("forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_isOutfolded"); + SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth = serializedObject.FindProperty("forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth"); + SerializedProperty sP_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value = serializedObject.FindProperty("forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value"); + + GUIContent used_GUIContent; + GUIContent used_GUIContentOfEnableToggle; + + string helpBoxText_for_autoLineBreakWidth = "This automatically inserts line breaks into the text, so that the width of the whole text block doesn't exceed the specified width."; + used_GUIContent = new GUIContent("Automatic line breaks"); + used_GUIContentOfEnableToggle = new GUIContent("Force line breaks after width span"); + Draw_ToggleableFloatSlider(used_GUIContent, used_GUIContentOfEnableToggle, "Maximum line width (relative to screen width)", helpBoxText_for_autoLineBreakWidth, sP_autoLineBreakWidth_relToViewportWidth_isOutfolded, sP_autoLineBreakWidth_relToViewportWidth, sP_autoLineBreakWidth_relToViewportWidth_value); + + string helpBoxText_for_forceTextEnlargementToThisMinWidth = "This overwrites the text size and rescales the text, so that the whole text block has at least the specified width."; + used_GUIContent = new GUIContent("Minimum text block width"); + used_GUIContentOfEnableToggle = new GUIContent("Force text enlargement to reach a minimum text block width"); + EditorGUI.BeginChangeCheck(); + Draw_ToggleableFloatSlider(used_GUIContent, used_GUIContentOfEnableToggle, "Minimum text block width (relative to screen width)", helpBoxText_for_forceTextEnlargementToThisMinWidth, sP_forceTextEnlargementToThisMinWidth_relToViewportWidth_isOutfolded, sP_forceTextEnlargementToThisMinWidth_relToViewportWidth, sP_forceTextEnlargementToThisMinWidth_relToViewportWidth_value); + bool minWidth_changed = EditorGUI.EndChangeCheck(); + + string helpBoxText_for_forceRestrictTextSizeToThisMaxTextWidth = "This overwrites the text size and rescales the text, so that the whole text block is not wider then the specified width." + Environment.NewLine + Environment.NewLine + "If you want restrict the text block width but keep the text size you can use 'Automatic line breaks'."; + used_GUIContent = new GUIContent("Maximum text block width"); + used_GUIContentOfEnableToggle = new GUIContent("Force restrict the text block width to a maximum"); + EditorGUI.BeginChangeCheck(); + Draw_ToggleableFloatSlider(used_GUIContent, used_GUIContentOfEnableToggle, "Maximum text block width (relative to screen width)", helpBoxText_for_forceRestrictTextSizeToThisMaxTextWidth, sP_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_isOutfolded, sP_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth, sP_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value); + bool maxWidth_changed = EditorGUI.EndChangeCheck(); + + if (minWidth_changed) + { + sP_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value.floatValue = Mathf.Max(sP_forceTextEnlargementToThisMinWidth_relToViewportWidth_value.floatValue, sP_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value.floatValue); + } + else + { + if (maxWidth_changed) + { + sP_forceTextEnlargementToThisMinWidth_relToViewportWidth_value.floatValue = Mathf.Min(sP_forceTextEnlargementToThisMinWidth_relToViewportWidth_value.floatValue, sP_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value.floatValue); + } + } + } + + void Draw_ToggleableFloatSlider(GUIContent used_GUIContentOfHeadline, GUIContent used_GUIContentOfEnableToggle, string used_nameString_ofValue, string helpBoxText, SerializedProperty sP_isOutfoldedProperty, SerializedProperty sP_boolProperty, SerializedProperty sP_floatProperty) + { + sP_isOutfoldedProperty.boolValue = EditorGUILayout.Foldout(sP_isOutfoldedProperty.boolValue, used_GUIContentOfHeadline, true); + if (sP_isOutfoldedProperty.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + EditorGUILayout.HelpBox(helpBoxText, MessageType.None, true); + EditorGUILayout.PropertyField(sP_boolProperty, used_GUIContentOfEnableToggle); + + EditorGUI.BeginDisabledGroup(!sP_boolProperty.boolValue); + EditorGUILayout.PropertyField(sP_floatProperty, new GUIContent(used_nameString_ofValue)); + EditorGUI.EndDisabledGroup(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/TextDrawerScreenspaceInspector.cs.meta b/Editor/DrawDebugLibrary/TextDrawerScreenspaceInspector.cs.meta new file mode 100644 index 0000000..e898dce --- /dev/null +++ b/Editor/DrawDebugLibrary/TextDrawerScreenspaceInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 068aeed28827b954d8afd63e08369bea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/VisualizerParentInspector.cs b/Editor/DrawDebugLibrary/VisualizerParentInspector.cs new file mode 100644 index 0000000..b9bef2e --- /dev/null +++ b/Editor/DrawDebugLibrary/VisualizerParentInspector.cs @@ -0,0 +1,1367 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(VisualizerParent))] + public class VisualizerParentInspector : Editor + { + public VisualizerParent visualizerParentMonoBehaviour_unserialized; + public Transform transform_onVisualizerObject; + + void OnEnable() + { + OnEnable_base(); + } + + public void OnEnable_base() + { + visualizerParentMonoBehaviour_unserialized = (VisualizerParent)target; + transform_onVisualizerObject = visualizerParentMonoBehaviour_unserialized.transform; + } + + public override void OnInspectorGUI() + { + int indentLevel_before = EditorGUI.indentLevel; + serializedObject.Update(); + + EditorGUILayout.HelpBox("This is the parent script that does nothing. Don't create it manually. You can delete this component.", MessageType.Info, true); + + serializedObject.ApplyModifiedProperties(); + EditorGUI.indentLevel = indentLevel_before; + } + + public float DrawConsumedLines(string nameOfVisualizedObject) + { + SerializedProperty sP_drawnLinesPerPass = serializedObject.FindProperty("drawnLinesPerPass"); + GUIStyle style_ofConsumedLinesLabel = new GUIStyle(); + style_ofConsumedLinesLabel.richText = true; + float allowedConsumedLines_0to1 = (float)sP_drawnLinesPerPass.intValue / (float)DrawBasics.MaxAllowedDrawnLinesPerFrame; + float hueValueOfColor = 0.33333f * (1.0f - allowedConsumedLines_0to1); + Color color_visualizingWarningForTooManyLines = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(hueValueOfColor, 0.5f, 1.0f); + string coloredLineNumber = "" + sP_drawnLinesPerPass.intValue + ""; + string tooltipForBoth = "This " + nameOfVisualizedObject + " visualization is drawn with single straight lines (like from 'Debug.DrawLine()'). If too many of these straight lines are drawn it may hit the Editor execution performance." + Environment.NewLine + Environment.NewLine + "The color of this line count becomes more red as the number reaches a critical area." + Environment.NewLine + Environment.NewLine + "(see also 'DrawXXL.DrawBasics.MaxAllowedDrawnLinesPerFrame')"; + GUIContent drawnLinesWord = new GUIContent("Drawn lines:", tooltipForBoth); + GUIContent drawnLinesNumber = new GUIContent(coloredLineNumber, tooltipForBoth); + EditorGUILayout.LabelField(drawnLinesWord, drawnLinesNumber, style_ofConsumedLinesLabel); + + // Game View 渲染模式切换开关 + SerializedProperty sP_wireMesh = serializedObject.FindProperty("useWireMeshInLateUpdate"); + if (sP_wireMesh != null) + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(sP_wireMesh, new GUIContent("Game View visible", "启用 wireMesh 渲染使 Game 视图中可见")); + if (EditorGUI.EndChangeCheck()) + { + serializedObject.ApplyModifiedProperties(); + } + } + + return allowedConsumedLines_0to1; + } + + public void Draw_coneConfig_insideFoldout_forStraightVectors() + { + SerializedProperty sP_coneLength_forStraightVectors_isOutfolded = serializedObject.FindProperty("coneLength_forStraightVectors_isOutfolded"); + sP_coneLength_forStraightVectors_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_coneLength_forStraightVectors_isOutfolded.boolValue, "Cone length", true); + if (sP_coneLength_forStraightVectors_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + Draw_coneLengthInclSpaceInterpretation_forStraightVectors(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + } + } + + public void Draw_coneLengthInclSpaceInterpretation_forStraightVectors() + { + SerializedProperty sP_coneLength_forStraightVectors = serializedObject.FindProperty("coneLength_forStraightVectors"); + SerializedProperty sP_coneLength_interpretation_forStraightVectors = serializedObject.FindProperty("coneLength_interpretation_forStraightVectors"); + EditorGUILayout.PropertyField(sP_coneLength_interpretation_forStraightVectors, new GUIContent("Length interpretation", "You can change the initial value of this via 'DrawXXL.DrawBasics.coneLength_interpretation_forStraightVectors'.")); + switch (sP_coneLength_interpretation_forStraightVectors.enumValueIndex) + { + case (int)DrawBasics.LengthInterpretation.relativeToLineLength: + sP_coneLength_forStraightVectors.floatValue = Mathf.Clamp(sP_coneLength_forStraightVectors.floatValue, UtilitiesDXXL_DrawBasics.min_relConeLengthForVectors, UtilitiesDXXL_DrawBasics.max_relConeLengthForVectors); + sP_coneLength_forStraightVectors.floatValue = EditorGUILayout.Slider("Length value", sP_coneLength_forStraightVectors.floatValue, UtilitiesDXXL_DrawBasics.min_relConeLengthForVectors, UtilitiesDXXL_DrawBasics.max_relConeLengthForVectors); + break; + case (int)DrawBasics.LengthInterpretation.absoluteUnits: + EditorGUILayout.PropertyField(sP_coneLength_forStraightVectors, new GUIContent("Length value")); + sP_coneLength_forStraightVectors.floatValue = Mathf.Max(sP_coneLength_forStraightVectors.floatValue, 0.0f); + break; + default: + break; + } + } + + public void Draw_coneLength_forCircledVectors() + { + SerializedProperty sP_coneLength_forCircledVectors_isOutfolded = serializedObject.FindProperty("coneLength_forCircledVectors_isOutfolded"); + sP_coneLength_forCircledVectors_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_coneLength_forCircledVectors_isOutfolded.boolValue, "Cone length", true); + if (sP_coneLength_forCircledVectors_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_coneLength_forCircledVectors = serializedObject.FindProperty("coneLength_forCircledVectors"); + SerializedProperty sP_coneLength_interpretation_forCircledVectors = serializedObject.FindProperty("coneLength_interpretation_forCircledVectors"); + EditorGUILayout.PropertyField(sP_coneLength_interpretation_forCircledVectors, new GUIContent("Value interpretation", "You can change the initial value of this via 'DrawXXL.DrawBasics.coneLength_interpretation_forCircledVectors'.")); + switch (sP_coneLength_interpretation_forCircledVectors.enumValueIndex) + { + case (int)DrawBasics.LengthInterpretation.relativeToLineLength: + sP_coneLength_forCircledVectors.floatValue = Mathf.Clamp01(sP_coneLength_forCircledVectors.floatValue); + sP_coneLength_forCircledVectors.floatValue = EditorGUILayout.Slider("Relative to radius", sP_coneLength_forCircledVectors.floatValue, 0.0f, 1.0f); + break; + case (int)DrawBasics.LengthInterpretation.absoluteUnits: + EditorGUILayout.PropertyField(sP_coneLength_forCircledVectors, new GUIContent("Absolute length")); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + } + } + + public void Draw_endPlatesConfig_insideFoldout() + { + SerializedProperty sP_endPlates_size_isOutfolded = serializedObject.FindProperty("endPlates_size_isOutfolded"); + sP_endPlates_size_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_endPlates_size_isOutfolded.boolValue, "End plates size", true); + if (sP_endPlates_size_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + Draw_endPlatesSizeInclSpaceInterpretation(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); + } + } + + public void Draw_endPlatesSizeInclSpaceInterpretation() + { + SerializedProperty sP_endPlates_sizeInterpretation = serializedObject.FindProperty("endPlates_sizeInterpretation"); + SerializedProperty sP_endPlates_size = serializedObject.FindProperty("endPlates_size"); + + EditorGUILayout.PropertyField(sP_endPlates_sizeInterpretation, new GUIContent("Size interpretation", "You can change the initial value of this via 'DrawXXL.DrawBasics.endPlates_sizeInterpretation'.")); + switch (sP_endPlates_sizeInterpretation.enumValueIndex) + { + case (int)DrawBasics.LengthInterpretation.relativeToLineLength: + sP_endPlates_size.floatValue = Mathf.Clamp01(sP_endPlates_size.floatValue); + sP_endPlates_size.floatValue = EditorGUILayout.Slider("Size of End Plates", sP_endPlates_size.floatValue, 0.0f, 1.0f); + break; + case (int)DrawBasics.LengthInterpretation.absoluteUnits: + EditorGUILayout.PropertyField(sP_endPlates_size, new GUIContent("Size of End Plates")); + sP_endPlates_size.floatValue = Mathf.Max(sP_endPlates_size.floatValue, 0.0f); + break; + default: + break; + } + } + + static string firstLine_ofTooltip_forLocal_caseFromThisTransform = "This is the local space defined by this transform."; + static string firstLine_ofTooltip_forLocal_caseFromOtherTransform = "This is the local space defined by the transform of the other object."; + + public void Draw_DrawPosition3DOffset(bool skipEmptyLineAtEndOfExpandedBlock = false, string overwrite_foldoutLabel = null, string displayNameOf_globalOffset = null, string displayNameOf_localOffset = null, bool withoutHeadline_norIntend_norSpaceAtEnd = false) + { + string firstLine_ofTooltip_forLocal = firstLine_ofTooltip_forLocal_caseFromThisTransform; + SerializedProperty sP_drawPosOffset3DSection_isOutfolded = serializedObject.FindProperty("drawPosOffset3DSection_isOutfolded"); + SerializedProperty sP_drawPosOffset3D_global = serializedObject.FindProperty("drawPosOffset3D_global"); + SerializedProperty sP_drawPosOffset3D_local = serializedObject.FindProperty("drawPosOffset3D_local"); + Draw_DrawPosition3DOffset(skipEmptyLineAtEndOfExpandedBlock, overwrite_foldoutLabel, firstLine_ofTooltip_forLocal, sP_drawPosOffset3DSection_isOutfolded, sP_drawPosOffset3D_global, sP_drawPosOffset3D_local, displayNameOf_globalOffset, displayNameOf_localOffset, withoutHeadline_norIntend_norSpaceAtEnd); + } + + public void Draw_DrawPosition3DOffset_independentAlternativeValue(bool skipEmptyLineAtEndOfExpandedBlock = false, string overwrite_foldoutLabel = null, string displayNameOf_globalOffset = null, string displayNameOf_localOffset = null, bool withoutHeadline_norIntend_norSpaceAtEnd = false) + { + string firstLine_ofTooltip_forLocal = firstLine_ofTooltip_forLocal_caseFromThisTransform; + SerializedProperty sP_drawPosOffset3DSection_isOutfolded_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset3DSection_isOutfolded_independentAlternativeValue"); + SerializedProperty sP_drawPosOffset3D_global_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset3D_global_independentAlternativeValue"); + SerializedProperty sP_drawPosOffset3D_local_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset3D_local_independentAlternativeValue"); + Draw_DrawPosition3DOffset(skipEmptyLineAtEndOfExpandedBlock, overwrite_foldoutLabel, firstLine_ofTooltip_forLocal, sP_drawPosOffset3DSection_isOutfolded_independentAlternativeValue, sP_drawPosOffset3D_global_independentAlternativeValue, sP_drawPosOffset3D_local_independentAlternativeValue, displayNameOf_globalOffset, displayNameOf_localOffset, withoutHeadline_norIntend_norSpaceAtEnd); + } + + public void Draw_DrawPosition3DOffset_ofPartnerGameobject(bool skipEmptyLineAtEndOfExpandedBlock = false, string overwrite_foldoutLabel = null, string displayNameOf_globalOffset = null, string displayNameOf_localOffset = null, bool withoutHeadline_norIntend_norSpaceAtEnd = false) + { + string firstLine_ofTooltip_forLocal = firstLine_ofTooltip_forLocal_caseFromOtherTransform; + SerializedProperty sP_drawPosOffset3DSection_isOutfolded = serializedObject.FindProperty("drawPosOffset3DSection_ofPartnerGameobject_isOutfolded"); + SerializedProperty sP_drawPosOffset3D_global = serializedObject.FindProperty("drawPosOffset3D_ofPartnerGameobject_global"); + SerializedProperty sP_drawPosOffset3D_local = serializedObject.FindProperty("drawPosOffset3D_ofPartnerGameobject_local"); + Draw_DrawPosition3DOffset(skipEmptyLineAtEndOfExpandedBlock, overwrite_foldoutLabel, firstLine_ofTooltip_forLocal, sP_drawPosOffset3DSection_isOutfolded, sP_drawPosOffset3D_global, sP_drawPosOffset3D_local, displayNameOf_globalOffset, displayNameOf_localOffset, withoutHeadline_norIntend_norSpaceAtEnd); + } + + public void Draw_DrawPosition3DOffset_ofPartnerGameobject_independentAlternativeValue(bool skipEmptyLineAtEndOfExpandedBlock = false, string overwrite_foldoutLabel = null, string displayNameOf_globalOffset = null, string displayNameOf_localOffset = null, bool withoutHeadline_norIntend_norSpaceAtEnd = false) + { + string firstLine_ofTooltip_forLocal = firstLine_ofTooltip_forLocal_caseFromOtherTransform; + SerializedProperty sP_drawPosOffset3DSection_isOutfolded_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset3DSection_ofPartnerGameobject_isOutfolded_independentAlternativeValue"); + SerializedProperty sP_drawPosOffset3D_global_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset3D_ofPartnerGameobject_global_independentAlternativeValue"); + SerializedProperty sP_drawPosOffset3D_local_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset3D_ofPartnerGameobject_local_independentAlternativeValue"); + Draw_DrawPosition3DOffset(skipEmptyLineAtEndOfExpandedBlock, overwrite_foldoutLabel, firstLine_ofTooltip_forLocal, sP_drawPosOffset3DSection_isOutfolded_independentAlternativeValue, sP_drawPosOffset3D_global_independentAlternativeValue, sP_drawPosOffset3D_local_independentAlternativeValue, displayNameOf_globalOffset, displayNameOf_localOffset, withoutHeadline_norIntend_norSpaceAtEnd); + } + + void Draw_DrawPosition3DOffset(bool skipEmptyLineAtEndOfExpandedBlock, string overwrite_foldoutLabel, string firstLine_ofTooltip_forLocal, SerializedProperty sP_drawPosOffset3DSection_isOutfolded, SerializedProperty sP_drawPosOffset3D_global, SerializedProperty sP_drawPosOffset3D_local, string displayNameOf_globalOffset = null, string displayNameOf_localOffset = null, bool withoutHeadline_norIntend_norSpaceAtEnd = false) + { + if (withoutHeadline_norIntend_norSpaceAtEnd) + { + Draw_DrawPosition3DOffset_insideIndentedFoldout(firstLine_ofTooltip_forLocal, sP_drawPosOffset3D_global, sP_drawPosOffset3D_local, displayNameOf_globalOffset, displayNameOf_localOffset); + } + else + { + string used_foldoutLabel = (overwrite_foldoutLabel == null) ? "Draw Position Offset" : overwrite_foldoutLabel; + sP_drawPosOffset3DSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_drawPosOffset3DSection_isOutfolded.boolValue, used_foldoutLabel, true); + if (sP_drawPosOffset3DSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + Draw_DrawPosition3DOffset_insideIndentedFoldout(firstLine_ofTooltip_forLocal, sP_drawPosOffset3D_global, sP_drawPosOffset3D_local, displayNameOf_globalOffset, displayNameOf_localOffset); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + if (skipEmptyLineAtEndOfExpandedBlock == false) { GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); } + } + } + } + + void Draw_DrawPosition3DOffset_insideIndentedFoldout(string firstLine_ofTooltip_forLocal, SerializedProperty sP_drawPosOffset3D_global, SerializedProperty sP_drawPosOffset3D_local, string displayNameOf_globalOffset, string displayNameOf_localOffset) + { + string used_displayNameOf_globalOffset = (displayNameOf_globalOffset == null) ? "global" : displayNameOf_globalOffset; + string used_displayNameOf_localOffset = (displayNameOf_localOffset == null) ? "local" : displayNameOf_localOffset; + + EditorGUILayout.PropertyField(sP_drawPosOffset3D_global, new GUIContent(used_displayNameOf_globalOffset)); + EditorGUILayout.PropertyField(sP_drawPosOffset3D_local, new GUIContent(used_displayNameOf_localOffset, firstLine_ofTooltip_forLocal + Environment.NewLine + Environment.NewLine + "It may lead to wrong results if a parent has a non-uniform scale.")); + } + + public void Draw_DrawPosition2DOffset(bool skipEmptyLineAtEndOfExpandedBlock = false, string overwrite_foldoutLabel = null, string displayNameOf_globalOffset = null, string displayNameOf_localOffset = null, bool withoutHeadline_norIntend_norSpaceAtEnd = false) + { + string firstLine_ofTooltip_forLocal = firstLine_ofTooltip_forLocal_caseFromThisTransform; + SerializedProperty sP_drawPosOffset2DSection_isOutfolded = serializedObject.FindProperty("drawPosOffset2DSection_isOutfolded"); + SerializedProperty sP_drawPosOffset2D_global = serializedObject.FindProperty("drawPosOffset2D_global"); + SerializedProperty sP_drawPosOffset2D_local = serializedObject.FindProperty("drawPosOffset2D_local"); + Transform transformThatDefinesTheLocalSpace = transform_onVisualizerObject; + Draw_DrawPosition2DOffset(skipEmptyLineAtEndOfExpandedBlock, overwrite_foldoutLabel, firstLine_ofTooltip_forLocal, sP_drawPosOffset2DSection_isOutfolded, sP_drawPosOffset2D_global, sP_drawPosOffset2D_local, transformThatDefinesTheLocalSpace, displayNameOf_globalOffset, displayNameOf_localOffset, withoutHeadline_norIntend_norSpaceAtEnd); + } + + public void Draw_DrawPosition2DOffset_independentAlternativeValue(bool skipEmptyLineAtEndOfExpandedBlock = false, string overwrite_foldoutLabel = null, string displayNameOf_globalOffset = null, string displayNameOf_localOffset = null, bool withoutHeadline_norIntend_norSpaceAtEnd = false) + { + string firstLine_ofTooltip_forLocal = firstLine_ofTooltip_forLocal_caseFromThisTransform; + SerializedProperty sP_drawPosOffset2DSection_isOutfolded_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset2DSection_isOutfolded_independentAlternativeValue"); + SerializedProperty sP_drawPosOffset2D_global_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset2D_global_independentAlternativeValue"); + SerializedProperty sP_drawPosOffset2D_local_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset2D_local_independentAlternativeValue"); + Transform transformThatDefinesTheLocalSpace = transform_onVisualizerObject; + Draw_DrawPosition2DOffset(skipEmptyLineAtEndOfExpandedBlock, overwrite_foldoutLabel, firstLine_ofTooltip_forLocal, sP_drawPosOffset2DSection_isOutfolded_independentAlternativeValue, sP_drawPosOffset2D_global_independentAlternativeValue, sP_drawPosOffset2D_local_independentAlternativeValue, transformThatDefinesTheLocalSpace, displayNameOf_globalOffset, displayNameOf_localOffset, withoutHeadline_norIntend_norSpaceAtEnd); + } + + public void Draw_DrawPosition2DOffset_ofPartnerGameobject(bool skipEmptyLineAtEndOfExpandedBlock = false, string overwrite_foldoutLabel = null, string displayNameOf_globalOffset = null, string displayNameOf_localOffset = null, bool withoutHeadline_norIntend_norSpaceAtEnd = false) + { + if (visualizerParentMonoBehaviour_unserialized.partnerGameobject != null) + { + string firstLine_ofTooltip_forLocal = firstLine_ofTooltip_forLocal_caseFromOtherTransform; + SerializedProperty sP_drawPosOffset2DSection_isOutfolded = serializedObject.FindProperty("drawPosOffset2DSection_ofPartnerGameobject_isOutfolded"); + SerializedProperty sP_drawPosOffset2D_global = serializedObject.FindProperty("drawPosOffset2D_ofPartnerGameobject_global"); + SerializedProperty sP_drawPosOffset2D_local = serializedObject.FindProperty("drawPosOffset2D_ofPartnerGameobject_local"); + Transform transformThatDefinesTheLocalSpace = visualizerParentMonoBehaviour_unserialized.partnerGameobject.transform; + Draw_DrawPosition2DOffset(skipEmptyLineAtEndOfExpandedBlock, overwrite_foldoutLabel, firstLine_ofTooltip_forLocal, sP_drawPosOffset2DSection_isOutfolded, sP_drawPosOffset2D_global, sP_drawPosOffset2D_local, transformThatDefinesTheLocalSpace, displayNameOf_globalOffset, displayNameOf_localOffset, withoutHeadline_norIntend_norSpaceAtEnd); + } + } + + public void Draw_DrawPosition2DOffset_ofPartnerGameobject_independentAlternativeValue(bool skipEmptyLineAtEndOfExpandedBlock = false, string overwrite_foldoutLabel = null, string displayNameOf_globalOffset = null, string displayNameOf_localOffset = null, bool withoutHeadline_norIntend_norSpaceAtEnd = false) + { + if (visualizerParentMonoBehaviour_unserialized.partnerGameobject != null) + { + string firstLine_ofTooltip_forLocal = firstLine_ofTooltip_forLocal_caseFromOtherTransform; + SerializedProperty sP_drawPosOffset2DSection_isOutfolded_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset2DSection_ofPartnerGameobject_isOutfolded_independentAlternativeValue"); + SerializedProperty sP_drawPosOffset2D_global_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset2D_ofPartnerGameobject_global_independentAlternativeValue"); + SerializedProperty sP_drawPosOffset2D_local_independentAlternativeValue = serializedObject.FindProperty("drawPosOffset2D_ofPartnerGameobject_local_independentAlternativeValue"); + Transform transformThatDefinesTheLocalSpace = visualizerParentMonoBehaviour_unserialized.partnerGameobject.transform; + Draw_DrawPosition2DOffset(skipEmptyLineAtEndOfExpandedBlock, overwrite_foldoutLabel, firstLine_ofTooltip_forLocal, sP_drawPosOffset2DSection_isOutfolded_independentAlternativeValue, sP_drawPosOffset2D_global_independentAlternativeValue, sP_drawPosOffset2D_local_independentAlternativeValue, transformThatDefinesTheLocalSpace, displayNameOf_globalOffset, displayNameOf_localOffset, withoutHeadline_norIntend_norSpaceAtEnd); + } + } + + void Draw_DrawPosition2DOffset(bool skipEmptyLineAtEndOfExpandedBlock, string overwrite_foldoutLabel, string firstLine_ofTooltip_forLocal, SerializedProperty sP_drawPosOffset2DSection_isOutfolded, SerializedProperty sP_drawPosOffset2D_global, SerializedProperty sP_drawPosOffset2D_local, Transform transformThatDefinesTheLocalSpace, string displayNameOf_globalOffset = null, string displayNameOf_localOffset = null, bool withoutHeadline_norIntend_norSpaceAtEnd = false) + { + if (withoutHeadline_norIntend_norSpaceAtEnd) + { + Draw_DrawPosition2DOffset_insideIndentedFoldout(firstLine_ofTooltip_forLocal, sP_drawPosOffset2D_global, sP_drawPosOffset2D_local, transformThatDefinesTheLocalSpace, displayNameOf_globalOffset, displayNameOf_localOffset); + } + else + { + string used_foldoutLabel = (overwrite_foldoutLabel == null) ? "Draw Position Offset" : overwrite_foldoutLabel; + sP_drawPosOffset2DSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_drawPosOffset2DSection_isOutfolded.boolValue, used_foldoutLabel, true); + if (sP_drawPosOffset2DSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + Draw_DrawPosition2DOffset_insideIndentedFoldout(firstLine_ofTooltip_forLocal, sP_drawPosOffset2D_global, sP_drawPosOffset2D_local, transformThatDefinesTheLocalSpace, displayNameOf_globalOffset, displayNameOf_localOffset); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + if (skipEmptyLineAtEndOfExpandedBlock == false) { GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); } + } + } + } + + void Draw_DrawPosition2DOffset_insideIndentedFoldout(string firstLine_ofTooltip_forLocal, SerializedProperty sP_drawPosOffset2D_global, SerializedProperty sP_drawPosOffset2D_local, Transform transformThatDefinesTheLocalSpace, string displayNameOf_globalOffset, string displayNameOf_localOffset) + { + string used_displayNameOf_globalOffset = (displayNameOf_globalOffset == null) ? "global" : displayNameOf_globalOffset; + string used_displayNameOf_localOffset = (displayNameOf_localOffset == null) ? "local" : displayNameOf_localOffset; + + EditorGUILayout.PropertyField(sP_drawPosOffset2D_global, new GUIContent(used_displayNameOf_globalOffset)); + EditorGUILayout.PropertyField(sP_drawPosOffset2D_local, new GUIContent(used_displayNameOf_localOffset, firstLine_ofTooltip_forLocal + Environment.NewLine + Environment.NewLine + "This may lead to wrong results if a parent has a non-uniform scale.")); + + if (UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale_2D(transformThatDefinesTheLocalSpace.parent)) + { + EditorGUILayout.HelpBox("A parent transform has a non-uniform scale. This may lead to wrong or weird results.", MessageType.Warning, true); + } + + if (UtilitiesDXXL_EngineBasics.CheckIfThisOrAParentHasANonZRotation_2D(transformThatDefinesTheLocalSpace)) + { + EditorGUILayout.HelpBox("The transform or a parent has a non-z rotation. This may lead to wrong or weird results in 2D mode.", MessageType.Warning, true); + } + } + + public void DrawZPosChooserFor2D(bool skipEmptyLineAtEndOfExpandedBlock = false) + { + SerializedProperty sP_customZPos_for2D_isOutfolded = serializedObject.FindProperty("customZPos_for2D_isOutfolded"); + sP_customZPos_for2D_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_customZPos_for2D_isOutfolded.boolValue, "Z position", true); + if (sP_customZPos_for2D_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + SerializedProperty sP_zPosSource = serializedObject.FindProperty("zPosSource"); + EditorGUILayout.PropertyField(sP_zPosSource, new GUIContent("Source of Z Position", "'Default' refers to the setting of 'DrawXXL.DrawBasics2D.Default_zPos_forDrawing'")); + switch (sP_zPosSource.enumValueIndex) + { + case (int)VisualizerParent.ZPosSource.transformPositionPlusOffset: + EditorGUILayout.PropertyField(serializedObject.FindProperty("customZPos_offsetValue"), new GUIContent("Offset from this transform", "In global units.")); + break; + case (int)VisualizerParent.ZPosSource.setAbsolute: + EditorGUILayout.PropertyField(serializedObject.FindProperty("customZPos_absValue"), new GUIContent("Absolute z position", "In global units.")); + break; + case (int)VisualizerParent.ZPosSource.defaultDrawZPosFromGlobalDrawXxlSettings: + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.FloatField(new GUIContent("Global default z position", "According to 'DrawBasics2D.Default_zPos_forDrawing'."), DrawBasics2D.Default_zPos_forDrawing); + EditorGUI.EndDisabledGroup(); + break; + default: + break; + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + + if (skipEmptyLineAtEndOfExpandedBlock == false) { GUILayout.Space(0.5f * EditorGUIUtility.singleLineHeight); } + } + } + + public void DrawCheckboxFor_drawOnlyIfSelected(string nameOfVisualizedObject) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("drawOnlyIfSelected"), new GUIContent("Draw only if selected", "When this is enabled then the " + nameOfVisualizedObject + " will only be drawn if this gameobject is selected in the editor." + Environment.NewLine + Environment.NewLine + "You can set the initial value of this for newly created components via 'DrawXXL.DrawBasics.initial_drawOnlyIfSelected_forComponents'.")); + } + + public void DrawCheckboxFor_hiddenByNearerObjects(string nameOfVisualizedObject) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("hiddenByNearerObjects"), new GUIContent("Hidden by nearer objects", "This is the same as the 'depthTest' parameter from 'Debug.DrawLine()'. It defines how much the drawn " + nameOfVisualizedObject + " shines through other objects that hide it." + Environment.NewLine + Environment.NewLine + "It has only effect in playmode.")); + } + + public void DrawSpecificationOf_customVector3_1(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isChecked, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed, bool skipHeadline = false, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition = true) + { + SerializedProperty sP_source_ofCustomVector3_1 = serializedObject.FindProperty("customVector3Configs.Array.data[0].source"); + SerializedProperty sP_customVector3_1_clipboardForManualInput = serializedObject.FindProperty("customVector3Configs.Array.data[0].clipboardForManualInput"); + SerializedProperty sP_customVector3_1_targetGameObject = serializedObject.FindProperty("customVector3Configs.Array.data[0].targetGameObject"); + SerializedProperty sP_customVector3_1_hasForcedAbsLength = serializedObject.FindProperty("customVector3Configs.Array.data[0].hasForcedAbsLength"); + SerializedProperty sP_customVector3_1_picker_isOutfolded = serializedObject.FindProperty("customVector3Configs.Array.data[0].picker_isOutfolded"); + SerializedProperty sP_forcedAbsLength_ofCustomVector3_1 = serializedObject.FindProperty("customVector3Configs.Array.data[0].forcedAbsLength"); + SerializedProperty sP_lengthRelScaleFactor_ofCustomVector3_1 = serializedObject.FindProperty("customVector3Configs.Array.data[0].lengthRelScaleFactor"); + SerializedProperty sP_vectorInterpretation_ofCustomVector3_1 = serializedObject.FindProperty("customVector3Configs.Array.data[0].vectorInterpretation"); + SerializedProperty sP_observerCamera_ofCustomVector3_1 = serializedObject.FindProperty("customVector3Configs.Array.data[0].observerCamera"); + + DrawSpecificationOf_aCustomVector3(foldoutRespCheckboxName, asCheckbox_insteadOfAsFoldout, sP_customVector3_1_picker_isOutfolded, sP_customVectorPicker_isChecked, sP_source_ofCustomVector3_1, sP_customVector3_1_clipboardForManualInput, sP_customVector3_1_targetGameObject, sP_customVector3_1_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector3_1, sP_lengthRelScaleFactor_ofCustomVector3_1, sP_vectorInterpretation_ofCustomVector3_1, sP_observerCamera_ofCustomVector3_1, visualizerParentMonoBehaviour_unserialized.Get_customVector3_1_inGlobalSpaceUnits, visualizerParentMonoBehaviour_unserialized.Get_customVector3_1_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, emptyLineAtEnd_ifCollapsed, skipHeadline, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition); + } + + public void DrawSpecificationOf_customVector3_2(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isChecked, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed, bool skipHeadline = false, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition = true) + { + SerializedProperty sP_source_ofCustomVector3_2 = serializedObject.FindProperty("customVector3Configs.Array.data[1].source"); + SerializedProperty sP_customVector3_2_clipboardForManualInput = serializedObject.FindProperty("customVector3Configs.Array.data[1].clipboardForManualInput"); + SerializedProperty sP_customVector3_2_targetGameObject = serializedObject.FindProperty("customVector3Configs.Array.data[1].targetGameObject"); + SerializedProperty sP_customVector3_2_hasForcedAbsLength = serializedObject.FindProperty("customVector3Configs.Array.data[1].hasForcedAbsLength"); + SerializedProperty sP_customVector3_2_picker_isOutfolded = serializedObject.FindProperty("customVector3Configs.Array.data[1].picker_isOutfolded"); + SerializedProperty sP_forcedAbsLength_ofCustomVector3_2 = serializedObject.FindProperty("customVector3Configs.Array.data[1].forcedAbsLength"); + SerializedProperty sP_lengthRelScaleFactor_ofCustomVector3_2 = serializedObject.FindProperty("customVector3Configs.Array.data[1].lengthRelScaleFactor"); + SerializedProperty sP_vectorInterpretation_ofCustomVector3_2 = serializedObject.FindProperty("customVector3Configs.Array.data[1].vectorInterpretation"); + SerializedProperty sP_observerCamera_ofCustomVector3_2 = serializedObject.FindProperty("customVector3Configs.Array.data[1].observerCamera"); + + DrawSpecificationOf_aCustomVector3(foldoutRespCheckboxName, asCheckbox_insteadOfAsFoldout, sP_customVector3_2_picker_isOutfolded, sP_customVectorPicker_isChecked, sP_source_ofCustomVector3_2, sP_customVector3_2_clipboardForManualInput, sP_customVector3_2_targetGameObject, sP_customVector3_2_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector3_2, sP_lengthRelScaleFactor_ofCustomVector3_2, sP_vectorInterpretation_ofCustomVector3_2, sP_observerCamera_ofCustomVector3_2, visualizerParentMonoBehaviour_unserialized.Get_customVector3_2_inGlobalSpaceUnits, visualizerParentMonoBehaviour_unserialized.Get_customVector3_2_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, emptyLineAtEnd_ifCollapsed, skipHeadline, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition); + } + + public void DrawSpecificationOf_customVector3_3(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isChecked, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed, bool skipHeadline = false, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition = true) + { + SerializedProperty sP_source_ofCustomVector3_3 = serializedObject.FindProperty("customVector3Configs.Array.data[2].source"); + SerializedProperty sP_customVector3_3_clipboardForManualInput = serializedObject.FindProperty("customVector3Configs.Array.data[2].clipboardForManualInput"); + SerializedProperty sP_customVector3_3_targetGameObject = serializedObject.FindProperty("customVector3Configs.Array.data[2].targetGameObject"); + SerializedProperty sP_customVector3_3_hasForcedAbsLength = serializedObject.FindProperty("customVector3Configs.Array.data[2].hasForcedAbsLength"); + SerializedProperty sP_customVector3_3_picker_isOutfolded = serializedObject.FindProperty("customVector3Configs.Array.data[2].picker_isOutfolded"); + SerializedProperty sP_forcedAbsLength_ofCustomVector3_3 = serializedObject.FindProperty("customVector3Configs.Array.data[2].forcedAbsLength"); + SerializedProperty sP_lengthRelScaleFactor_ofCustomVector3_3 = serializedObject.FindProperty("customVector3Configs.Array.data[2].lengthRelScaleFactor"); + SerializedProperty sP_vectorInterpretation_ofCustomVector3_3 = serializedObject.FindProperty("customVector3Configs.Array.data[2].vectorInterpretation"); + SerializedProperty sP_observerCamera_ofCustomVector3_3 = serializedObject.FindProperty("customVector3Configs.Array.data[2].observerCamera"); + + DrawSpecificationOf_aCustomVector3(foldoutRespCheckboxName, asCheckbox_insteadOfAsFoldout, sP_customVector3_3_picker_isOutfolded, sP_customVectorPicker_isChecked, sP_source_ofCustomVector3_3, sP_customVector3_3_clipboardForManualInput, sP_customVector3_3_targetGameObject, sP_customVector3_3_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector3_3, sP_lengthRelScaleFactor_ofCustomVector3_3, sP_vectorInterpretation_ofCustomVector3_3, sP_observerCamera_ofCustomVector3_3, visualizerParentMonoBehaviour_unserialized.Get_customVector3_3_inGlobalSpaceUnits, visualizerParentMonoBehaviour_unserialized.Get_customVector3_3_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, emptyLineAtEnd_ifCollapsed, skipHeadline, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition); + } + + public void DrawSpecificationOf_customVector3_4(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isChecked, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed, bool skipHeadline = false, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition = true) + { + SerializedProperty sP_source_ofCustomVector3_4 = serializedObject.FindProperty("customVector3Configs.Array.data[3].source"); + SerializedProperty sP_customVector3_4_clipboardForManualInput = serializedObject.FindProperty("customVector3Configs.Array.data[3].clipboardForManualInput"); + SerializedProperty sP_customVector3_4_targetGameObject = serializedObject.FindProperty("customVector3Configs.Array.data[3].targetGameObject"); + SerializedProperty sP_customVector3_4_hasForcedAbsLength = serializedObject.FindProperty("customVector3Configs.Array.data[3].hasForcedAbsLength"); + SerializedProperty sP_customVector3_4_picker_isOutfolded = serializedObject.FindProperty("customVector3Configs.Array.data[3].picker_isOutfolded"); + SerializedProperty sP_forcedAbsLength_ofCustomVector3_4 = serializedObject.FindProperty("customVector3Configs.Array.data[3].forcedAbsLength"); + SerializedProperty sP_lengthRelScaleFactor_ofCustomVector3_4 = serializedObject.FindProperty("customVector3Configs.Array.data[3].lengthRelScaleFactor"); + SerializedProperty sP_vectorInterpretation_ofCustomVector3_4 = serializedObject.FindProperty("customVector3Configs.Array.data[3].vectorInterpretation"); + SerializedProperty sP_observerCamera_ofCustomVector3_4 = serializedObject.FindProperty("customVector3Configs.Array.data[3].observerCamera"); + + DrawSpecificationOf_aCustomVector3(foldoutRespCheckboxName, asCheckbox_insteadOfAsFoldout, sP_customVector3_4_picker_isOutfolded, sP_customVectorPicker_isChecked, sP_source_ofCustomVector3_4, sP_customVector3_4_clipboardForManualInput, sP_customVector3_4_targetGameObject, sP_customVector3_4_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector3_4, sP_lengthRelScaleFactor_ofCustomVector3_4, sP_vectorInterpretation_ofCustomVector3_4, sP_observerCamera_ofCustomVector3_4, visualizerParentMonoBehaviour_unserialized.Get_customVector3_4_inGlobalSpaceUnits, visualizerParentMonoBehaviour_unserialized.Get_customVector3_4_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, emptyLineAtEnd_ifCollapsed, skipHeadline, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition); + } + + public void DrawSpecificationOf_customVector3ofPartnerGameobject(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isChecked, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed) + { + SerializedProperty sP_source_ofCustomVector3ofPartnerGameobject = serializedObject.FindProperty("source_ofCustomVector3ofPartnerGameobject"); + SerializedProperty sP_customVector3ofPartnerGameobject_clipboardForManualInput = serializedObject.FindProperty("customVector3ofPartnerGameobject_clipboardForManualInput"); + SerializedProperty sP_customVector3ofPartnerGameobject_targetGameObject = serializedObject.FindProperty("customVector3ofPartnerGameobject_targetGameObject"); + SerializedProperty sP_customVector3ofPartnerGameobject_hasForcedAbsLength = serializedObject.FindProperty("customVector3ofPartnerGameobject_hasForcedAbsLength"); + SerializedProperty sP_customVector3ofPartnerGameobject_picker_isOutfolded = serializedObject.FindProperty("customVector3ofPartnerGameobject_picker_isOutfolded"); + SerializedProperty sP_forcedAbsLength_ofCustomVector3ofPartnerGameobject = serializedObject.FindProperty("forcedAbsLength_ofCustomVector3ofPartnerGameobject"); + SerializedProperty sP_lengthRelScaleFactor_ofCustomVector3ofPartnerGameobject = serializedObject.FindProperty("lengthRelScaleFactor_ofCustomVector3ofPartnerGameobject"); + SerializedProperty sP_vectorInterpretation_ofCustomVector3ofPartnerGameobject = serializedObject.FindProperty("vectorInterpretation_ofCustomVector3ofPartnerGameobject"); + SerializedProperty sP_observerCamera_ofCustomVector3ofPartnerGameobject = serializedObject.FindProperty("observerCamera_ofCustomVector3ofPartnerGameobject"); + + DrawSpecificationOf_aCustomVector3(foldoutRespCheckboxName, asCheckbox_insteadOfAsFoldout, sP_customVector3ofPartnerGameobject_picker_isOutfolded, sP_customVectorPicker_isChecked, sP_source_ofCustomVector3ofPartnerGameobject, sP_customVector3ofPartnerGameobject_clipboardForManualInput, sP_customVector3ofPartnerGameobject_targetGameObject, sP_customVector3ofPartnerGameobject_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector3ofPartnerGameobject, sP_lengthRelScaleFactor_ofCustomVector3ofPartnerGameobject, sP_vectorInterpretation_ofCustomVector3ofPartnerGameobject, sP_observerCamera_ofCustomVector3ofPartnerGameobject, visualizerParentMonoBehaviour_unserialized.Get_customVector3ofPartnerGameobject_inGlobalSpaceUnits, visualizerParentMonoBehaviour_unserialized.Get_customVector3ofPartnerGameobject_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, emptyLineAtEnd_ifCollapsed, false, true); + } + + void DrawSpecificationOf_aCustomVector3(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isOutfolded, SerializedProperty sP_customVectorPicker_isChecked, SerializedProperty sP_source_ofCustomVector3, SerializedProperty sP_customVector3_clipboardForManualInput, SerializedProperty sP_customVector_targetGameObject, SerializedProperty sP_customVector_hasForcedAbsLength, SerializedProperty sP_forcedAbsLength_ofCustomVector, SerializedProperty sP_lengthRelScaleFactor_ofCustomVector, SerializedProperty sP_vectorInterpretation_ofCustomVector, SerializedProperty sP_observerCamera_ofCustomVector, VisualizerParent.FlexibleGetCustomVector3 Get_concernedCustomVector3_inGlobalSpaceUnits, VisualizerParent.FlexibleGetCustomVector3 Get_concernedCustomVector3_inLocalSpaceDefinedByParentUnits, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed, bool skipHeadline, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition) + { + if (asCheckbox_insteadOfAsFoldout) + { + GUIStyle style_ofPickerHeadline = new GUIStyle(EditorStyles.toggle); + style_ofPickerHeadline.richText = true; + sP_customVectorPicker_isChecked.boolValue = EditorGUILayout.Toggle(foldoutRespCheckboxName, sP_customVectorPicker_isChecked.boolValue, style_ofPickerHeadline); + + EditorGUI.BeginDisabledGroup(!sP_customVectorPicker_isChecked.boolValue); + DrawContentOfACustomVector3Specification(sP_source_ofCustomVector3, sP_customVector3_clipboardForManualInput, sP_customVector_targetGameObject, sP_customVector_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector, sP_lengthRelScaleFactor_ofCustomVector, sP_vectorInterpretation_ofCustomVector, sP_observerCamera_ofCustomVector, sP_customVectorPicker_isChecked, Get_concernedCustomVector3_inGlobalSpaceUnits, Get_concernedCustomVector3_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition); + EditorGUI.EndDisabledGroup(); + } + else + { + GUIStyle style_ofPickerHeadline = new GUIStyle(EditorStyles.foldout); + style_ofPickerHeadline.richText = true; + + bool used_isOutfolded = true; + if (skipHeadline == false) + { + sP_customVectorPicker_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_customVectorPicker_isOutfolded.boolValue, foldoutRespCheckboxName, true, style_ofPickerHeadline); + used_isOutfolded = sP_customVectorPicker_isOutfolded.boolValue; + } + + if (used_isOutfolded) + { + DrawContentOfACustomVector3Specification(sP_source_ofCustomVector3, sP_customVector3_clipboardForManualInput, sP_customVector_targetGameObject, sP_customVector_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector, sP_lengthRelScaleFactor_ofCustomVector, sP_vectorInterpretation_ofCustomVector, sP_observerCamera_ofCustomVector, sP_customVectorPicker_isChecked, Get_concernedCustomVector3_inGlobalSpaceUnits, Get_concernedCustomVector3_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition); + } + else + { + if (emptyLineAtEnd_ifCollapsed) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + } + } + + void DrawContentOfACustomVector3Specification(SerializedProperty sP_source_ofCustomVector3, SerializedProperty sP_customVector3_clipboardForManualInput, SerializedProperty sP_customVector_targetGameObject, SerializedProperty sP_customVector_hasForcedAbsLength, SerializedProperty sP_forcedAbsLength_ofCustomVector, SerializedProperty sP_lengthRelScaleFactor_ofCustomVector, SerializedProperty sP_vectorInterpretation_ofCustomVector, SerializedProperty sP_observerCamera_ofCustomVector, SerializedProperty sP_customVectorPicker_isChecked, VisualizerParent.FlexibleGetCustomVector3 Get_concernedCustomVector3_inGlobalSpaceUnits, VisualizerParent.FlexibleGetCustomVector3 Get_concernedCustomVector3_inLocalSpaceDefinedByParentUnits, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(sP_source_ofCustomVector3, new GUIContent("Vector source")); + + bool forceInterpretationToAlwaysGlobal; + switch (sP_source_ofCustomVector3.enumValueIndex) + { + case (int)VisualizerParent.CustomVector3Source.manualInput: + EditorGUILayout.PropertyField(sP_customVector3_clipboardForManualInput, new GUIContent("Input")); + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector3Source.toOtherGameobject: + EditorGUILayout.PropertyField(sP_customVector_targetGameObject, new GUIContent("Other GameObject")); + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.fromOtherGameobject: + EditorGUILayout.PropertyField(sP_customVector_targetGameObject, new GUIContent("Other GameObject")); + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.transformsForward: + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector3Source.transformsUp: + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector3Source.transformsRight: + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector3Source.transformsBack: + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector3Source.transformsDown: + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector3Source.transformsLeft: + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector3Source.globalForward: + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.globalUp: + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.globalRight: + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.globalBack: + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.globalDown: + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.globalLeft: + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.observerCameraForward: + EditorGUILayout.PropertyField(sP_observerCamera_ofCustomVector, new GUIContent("Camera to use")); + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.observerCameraUp: + EditorGUILayout.PropertyField(sP_observerCamera_ofCustomVector, new GUIContent("Camera to use")); + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.observerCameraRight: + EditorGUILayout.PropertyField(sP_observerCamera_ofCustomVector, new GUIContent("Camera to use")); + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.observerCameraBack: + EditorGUILayout.PropertyField(sP_observerCamera_ofCustomVector, new GUIContent("Camera to use")); + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.observerCameraDown: + EditorGUILayout.PropertyField(sP_observerCamera_ofCustomVector, new GUIContent("Camera to use")); + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.observerCameraLeft: + EditorGUILayout.PropertyField(sP_observerCamera_ofCustomVector, new GUIContent("Camera to use")); + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector3Source.observerCameraToThisGameobject: + EditorGUILayout.PropertyField(sP_observerCamera_ofCustomVector, new GUIContent("Camera to use")); + forceInterpretationToAlwaysGlobal = true; + break; + default: + forceInterpretationToAlwaysGlobal = true; + break; + } + + Draw_interpretationChooser_forGlobalOrLocal_V3(sP_vectorInterpretation_ofCustomVector, sP_customVectorPicker_isChecked, forceInterpretationToAlwaysGlobal, sP_source_ofCustomVector3, hideEverythingThatConcernsLength); + if (hideEverythingThatConcernsLength == false) + { + DrawLengthAdjustmentForCustomVector(sP_customVector_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector, sP_lengthRelScaleFactor_ofCustomVector, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition); + } + if (hideDisplayOfReadOnlyFinalVectorValues == false) + { + string displayName_ofFinalVectorGlobal = fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition ? "Final vector (global) (read only)" : "Final position (global) (read only)"; + EditorGUILayout.Vector3Field(new GUIContent(displayName_ofFinalVectorGlobal, "This is in units of the global space." + Environment.NewLine + "It is read only."), Get_concernedCustomVector3_inGlobalSpaceUnits()); + + string displayName_ofFinalVectorLocal = fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition ? "Final vector (local) (read only)" : "Final position (local) (read only)"; + EditorGUILayout.Vector3Field(new GUIContent(displayName_ofFinalVectorLocal, "This is in units of the local space defined by the parent transform." + Environment.NewLine + Environment.NewLine + "It is read only."), Get_concernedCustomVector3_inLocalSpaceDefinedByParentUnits()); + } + + if (emptyLineAtEnd_ifOutfolded) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void Draw_interpretationChooser_forGlobalOrLocal_V3(SerializedProperty sP_vectorInterpretation_ofCustomVector, SerializedProperty sP_customVectorPicker_isChecked, bool alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace, SerializedProperty sP_source_ofCustomVector3, bool hideEverythingThatConcernsLength) + { + if (hideEverythingThatConcernsLength) + { + if (sP_source_ofCustomVector3.enumValueIndex == (int)VisualizerParent.CustomVector3Source.manualInput) + { + EditorGUILayout.PropertyField(sP_vectorInterpretation_ofCustomVector, new GUIContent("Vector source interpretation")); + TryDraw_warningHelpBox_forNonUniformParentScale_V3(sP_vectorInterpretation_ofCustomVector, sP_customVectorPicker_isChecked, alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace); + } + } + else + { + if (alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace) + { + EditorGUI.BeginDisabledGroup(alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace); + } + + if (alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace) + { + EditorGUILayout.EnumPopup(new GUIContent("Vector source interpretation"), VisualizerParent.VectorInterpretation.globalSpace); + } + else + { + EditorGUILayout.PropertyField(sP_vectorInterpretation_ofCustomVector, new GUIContent("Vector source interpretation")); + } + + if (alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace) + { + EditorGUI.EndDisabledGroup(); + } + TryDraw_warningHelpBox_forNonUniformParentScale_V3(sP_vectorInterpretation_ofCustomVector, sP_customVectorPicker_isChecked, alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace); + } + } + + void TryDraw_warningHelpBox_forNonUniformParentScale_V3(SerializedProperty sP_vectorInterpretation_ofCustomVector, SerializedProperty sP_customVectorPicker_isChecked, bool alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace) + { + if (transform_onVisualizerObject.parent != null) + { + if ((sP_customVectorPicker_isChecked == null) || sP_customVectorPicker_isChecked.boolValue) + { + if (alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace == false) + { + if ((VisualizerParent.VectorInterpretation)sP_vectorInterpretation_ofCustomVector.enumValueIndex == VisualizerParent.VectorInterpretation.localSpaceDefinedByParent) + { + if (UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(transform_onVisualizerObject.parent)) + { + EditorGUILayout.HelpBox("A parent transform has a non-uniform scale. This may lead to wrong or weird results.", MessageType.Warning, true); + } + } + } + } + } + } + + public void DrawSpecificationOf_customVector2_1(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isChecked, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed, bool skipHeadline = false, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition = true, bool hideEverythingThatConcernsLocalSpace = false) + { + SerializedProperty sP_source_ofCustomVector2_1 = serializedObject.FindProperty("customVector2Configs.Array.data[0].source"); + SerializedProperty sP_customVector2_1_clipboardForManualInput = serializedObject.FindProperty("customVector2Configs.Array.data[0].clipboardForManualInput"); + SerializedProperty sP_customVector2_1_targetGameObject = serializedObject.FindProperty("customVector2Configs.Array.data[0].targetGameObject"); + SerializedProperty sP_customVector2_1_hasForcedAbsLength = serializedObject.FindProperty("customVector2Configs.Array.data[0].hasForcedAbsLength"); + SerializedProperty sP_customVector2_1_picker_isOutfolded = serializedObject.FindProperty("customVector2Configs.Array.data[0].picker_isOutfolded"); + SerializedProperty sP_rotationFromRight_ofCustomVector2_1 = serializedObject.FindProperty("customVector2Configs.Array.data[0].rotationFromRight"); + SerializedProperty sP_forcedAbsLength_ofCustomVector2_1 = serializedObject.FindProperty("customVector2Configs.Array.data[0].forcedAbsLength"); + SerializedProperty sP_lengthRelScaleFactor_ofCustomVector2_1 = serializedObject.FindProperty("customVector2Configs.Array.data[0].lengthRelScaleFactor"); + SerializedProperty sP_vectorInterpretation_ofCustomVector2_1 = serializedObject.FindProperty("customVector2Configs.Array.data[0].vectorInterpretation"); + + DrawSpecificationOf_aCustomVector2(foldoutRespCheckboxName, asCheckbox_insteadOfAsFoldout, sP_customVector2_1_picker_isOutfolded, sP_customVectorPicker_isChecked, sP_rotationFromRight_ofCustomVector2_1, sP_source_ofCustomVector2_1, sP_customVector2_1_clipboardForManualInput, sP_customVector2_1_targetGameObject, sP_customVector2_1_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector2_1, sP_lengthRelScaleFactor_ofCustomVector2_1, sP_vectorInterpretation_ofCustomVector2_1, visualizerParentMonoBehaviour_unserialized.Get_customVector2_1_inGlobalSpaceUnits, visualizerParentMonoBehaviour_unserialized.Get_customVector2_1_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, emptyLineAtEnd_ifCollapsed, skipHeadline, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition, hideEverythingThatConcernsLocalSpace); + } + + public void DrawSpecificationOf_customVector2_2(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isChecked, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed, bool skipHeadline = false, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition = true, bool hideEverythingThatConcernsLocalSpace = false) + { + SerializedProperty sP_source_ofCustomVector2_2 = serializedObject.FindProperty("customVector2Configs.Array.data[1].source"); + SerializedProperty sP_customVector2_2_clipboardForManualInput = serializedObject.FindProperty("customVector2Configs.Array.data[1].clipboardForManualInput"); + SerializedProperty sP_customVector2_2_targetGameObject = serializedObject.FindProperty("customVector2Configs.Array.data[1].targetGameObject"); + SerializedProperty sP_customVector2_2_hasForcedAbsLength = serializedObject.FindProperty("customVector2Configs.Array.data[1].hasForcedAbsLength"); + SerializedProperty sP_customVector2_2_picker_isOutfolded = serializedObject.FindProperty("customVector2Configs.Array.data[1].picker_isOutfolded"); + SerializedProperty sP_rotationFromRight_ofCustomVector2_2 = serializedObject.FindProperty("customVector2Configs.Array.data[1].rotationFromRight"); + SerializedProperty sP_forcedAbsLength_ofCustomVector2_2 = serializedObject.FindProperty("customVector2Configs.Array.data[1].forcedAbsLength"); + SerializedProperty sP_lengthRelScaleFactor_ofCustomVector2_2 = serializedObject.FindProperty("customVector2Configs.Array.data[1].lengthRelScaleFactor"); + SerializedProperty sP_vectorInterpretation_ofCustomVector2_2 = serializedObject.FindProperty("customVector2Configs.Array.data[1].vectorInterpretation"); + + DrawSpecificationOf_aCustomVector2(foldoutRespCheckboxName, asCheckbox_insteadOfAsFoldout, sP_customVector2_2_picker_isOutfolded, sP_customVectorPicker_isChecked, sP_rotationFromRight_ofCustomVector2_2, sP_source_ofCustomVector2_2, sP_customVector2_2_clipboardForManualInput, sP_customVector2_2_targetGameObject, sP_customVector2_2_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector2_2, sP_lengthRelScaleFactor_ofCustomVector2_2, sP_vectorInterpretation_ofCustomVector2_2, visualizerParentMonoBehaviour_unserialized.Get_customVector2_2_inGlobalSpaceUnits, visualizerParentMonoBehaviour_unserialized.Get_customVector2_2_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, emptyLineAtEnd_ifCollapsed, skipHeadline, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition, hideEverythingThatConcernsLocalSpace); + } + + public void DrawSpecificationOf_customVector2_3(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isChecked, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed, bool skipHeadline = false, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition = true, bool hideEverythingThatConcernsLocalSpace = false) + { + SerializedProperty sP_source_ofCustomVector2_3 = serializedObject.FindProperty("customVector2Configs.Array.data[2].source"); + SerializedProperty sP_customVector2_3_clipboardForManualInput = serializedObject.FindProperty("customVector2Configs.Array.data[2].clipboardForManualInput"); + SerializedProperty sP_customVector2_3_targetGameObject = serializedObject.FindProperty("customVector2Configs.Array.data[2].targetGameObject"); + SerializedProperty sP_customVector2_3_hasForcedAbsLength = serializedObject.FindProperty("customVector2Configs.Array.data[2].hasForcedAbsLength"); + SerializedProperty sP_customVector2_3_picker_isOutfolded = serializedObject.FindProperty("customVector2Configs.Array.data[2].picker_isOutfolded"); + SerializedProperty sP_rotationFromRight_ofCustomVector2_3 = serializedObject.FindProperty("customVector2Configs.Array.data[2].rotationFromRight"); + SerializedProperty sP_forcedAbsLength_ofCustomVector2_3 = serializedObject.FindProperty("customVector2Configs.Array.data[2].forcedAbsLength"); + SerializedProperty sP_lengthRelScaleFactor_ofCustomVector2_3 = serializedObject.FindProperty("customVector2Configs.Array.data[2].lengthRelScaleFactor"); + SerializedProperty sP_vectorInterpretation_ofCustomVector2_3 = serializedObject.FindProperty("customVector2Configs.Array.data[2].vectorInterpretation"); + + DrawSpecificationOf_aCustomVector2(foldoutRespCheckboxName, asCheckbox_insteadOfAsFoldout, sP_customVector2_3_picker_isOutfolded, sP_customVectorPicker_isChecked, sP_rotationFromRight_ofCustomVector2_3, sP_source_ofCustomVector2_3, sP_customVector2_3_clipboardForManualInput, sP_customVector2_3_targetGameObject, sP_customVector2_3_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector2_3, sP_lengthRelScaleFactor_ofCustomVector2_3, sP_vectorInterpretation_ofCustomVector2_3, visualizerParentMonoBehaviour_unserialized.Get_customVector2_3_inGlobalSpaceUnits, visualizerParentMonoBehaviour_unserialized.Get_customVector2_3_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, emptyLineAtEnd_ifCollapsed, skipHeadline, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition, hideEverythingThatConcernsLocalSpace); + } + + public void DrawSpecificationOf_customVector2_4(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isChecked, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed, bool skipHeadline = false, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition = true, bool hideEverythingThatConcernsLocalSpace = false) + { + SerializedProperty sP_source_ofCustomVector2_4 = serializedObject.FindProperty("customVector2Configs.Array.data[3].source"); + SerializedProperty sP_customVector2_4_clipboardForManualInput = serializedObject.FindProperty("customVector2Configs.Array.data[3].clipboardForManualInput"); + SerializedProperty sP_customVector2_4_targetGameObject = serializedObject.FindProperty("customVector2Configs.Array.data[3].targetGameObject"); + SerializedProperty sP_customVector2_4_hasForcedAbsLength = serializedObject.FindProperty("customVector2Configs.Array.data[3].hasForcedAbsLength"); + SerializedProperty sP_customVector2_4_picker_isOutfolded = serializedObject.FindProperty("customVector2Configs.Array.data[3].picker_isOutfolded"); + SerializedProperty sP_rotationFromRight_ofCustomVector2_4 = serializedObject.FindProperty("customVector2Configs.Array.data[3].rotationFromRight"); + SerializedProperty sP_forcedAbsLength_ofCustomVector2_4 = serializedObject.FindProperty("customVector2Configs.Array.data[3].forcedAbsLength"); + SerializedProperty sP_lengthRelScaleFactor_ofCustomVector2_4 = serializedObject.FindProperty("customVector2Configs.Array.data[3].lengthRelScaleFactor"); + SerializedProperty sP_vectorInterpretation_ofCustomVector2_4 = serializedObject.FindProperty("customVector2Configs.Array.data[3].vectorInterpretation"); + + DrawSpecificationOf_aCustomVector2(foldoutRespCheckboxName, asCheckbox_insteadOfAsFoldout, sP_customVector2_4_picker_isOutfolded, sP_customVectorPicker_isChecked, sP_rotationFromRight_ofCustomVector2_4, sP_source_ofCustomVector2_4, sP_customVector2_4_clipboardForManualInput, sP_customVector2_4_targetGameObject, sP_customVector2_4_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector2_4, sP_lengthRelScaleFactor_ofCustomVector2_4, sP_vectorInterpretation_ofCustomVector2_4, visualizerParentMonoBehaviour_unserialized.Get_customVector2_4_inGlobalSpaceUnits, visualizerParentMonoBehaviour_unserialized.Get_customVector2_4_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, emptyLineAtEnd_ifCollapsed, skipHeadline, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition, hideEverythingThatConcernsLocalSpace); + } + + public void DrawSpecificationOf_customVector2ofPartnerGameobject(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isChecked, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed) + { + SerializedProperty sP_source_ofCustomVector2ofPartnerGameobject = serializedObject.FindProperty("source_ofCustomVector2ofPartnerGameobject"); + SerializedProperty sP_customVector2ofPartnerGameobject_clipboardForManualInput = serializedObject.FindProperty("customVector2ofPartnerGameobject_clipboardForManualInput"); + SerializedProperty sP_customVector2ofPartnerGameobject_targetGameObject = serializedObject.FindProperty("customVector2ofPartnerGameobject_targetGameObject"); + SerializedProperty sP_customVector2ofPartnerGameobject_hasForcedAbsLength = serializedObject.FindProperty("customVector2ofPartnerGameobject_hasForcedAbsLength"); + SerializedProperty sP_customVector2ofPartnerGameobject_picker_isOutfolded = serializedObject.FindProperty("customVector2ofPartnerGameobject_picker_isOutfolded"); + SerializedProperty sP_rotationFromRight_ofCustomVector2ofPartnerGameobject = serializedObject.FindProperty("rotationFromRight_ofCustomVector2ofPartnerGameobject"); + SerializedProperty sP_forcedAbsLength_ofCustomVector2ofPartnerGameobject = serializedObject.FindProperty("forcedAbsLength_ofCustomVector2ofPartnerGameobject"); + SerializedProperty sP_lengthRelScaleFactor_ofCustomVector2ofPartnerGameobject = serializedObject.FindProperty("lengthRelScaleFactor_ofCustomVector2ofPartnerGameobject"); + SerializedProperty sP_vectorInterpretation_ofCustomVector2ofPartnerGameobject = serializedObject.FindProperty("vectorInterpretation_ofCustomVector2ofPartnerGameobject"); + + DrawSpecificationOf_aCustomVector2(foldoutRespCheckboxName, asCheckbox_insteadOfAsFoldout, sP_customVector2ofPartnerGameobject_picker_isOutfolded, sP_customVectorPicker_isChecked, sP_rotationFromRight_ofCustomVector2ofPartnerGameobject, sP_source_ofCustomVector2ofPartnerGameobject, sP_customVector2ofPartnerGameobject_clipboardForManualInput, sP_customVector2ofPartnerGameobject_targetGameObject, sP_customVector2ofPartnerGameobject_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector2ofPartnerGameobject, sP_lengthRelScaleFactor_ofCustomVector2ofPartnerGameobject, sP_vectorInterpretation_ofCustomVector2ofPartnerGameobject, visualizerParentMonoBehaviour_unserialized.Get_customVector2ofPartnerGameobject_inGlobalSpaceUnits, visualizerParentMonoBehaviour_unserialized.Get_customVector2ofPartnerGameobject_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, emptyLineAtEnd_ifCollapsed, false, true, false); + } + + void DrawSpecificationOf_aCustomVector2(string foldoutRespCheckboxName, bool asCheckbox_insteadOfAsFoldout, SerializedProperty sP_customVectorPicker_isOutfolded, SerializedProperty sP_customVectorPicker_isChecked, SerializedProperty sP_rotationFromRight_ofCustomVector2, SerializedProperty sP_source_ofCustomVector2, SerializedProperty sP_customVector2_clipboardForManualInput, SerializedProperty sP_customVector_targetGameObject, SerializedProperty sP_customVector_hasForcedAbsLength, SerializedProperty sP_forcedAbsLength_ofCustomVector, SerializedProperty sP_lengthRelScaleFactor_ofCustomVector, SerializedProperty sP_vectorInterpretation_ofCustomVector, VisualizerParent.FlexibleGetCustomVector2 Get_concernedCustomVector2_inGlobalSpaceUnits, VisualizerParent.FlexibleGetCustomVector2 Get_concernedCustomVector2_inLocalSpaceDefinedByParentUnits, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool emptyLineAtEnd_ifCollapsed, bool skipHeadline, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition, bool hideEverythingThatConcernsLocalSpace) + { + if (asCheckbox_insteadOfAsFoldout) + { + GUIStyle style_ofPickerHeadline = new GUIStyle(EditorStyles.toggle); + style_ofPickerHeadline.richText = true; + sP_customVectorPicker_isChecked.boolValue = EditorGUILayout.Toggle(foldoutRespCheckboxName, sP_customVectorPicker_isChecked.boolValue, style_ofPickerHeadline); + + EditorGUI.BeginDisabledGroup(!sP_customVectorPicker_isChecked.boolValue); + DrawContentOfACustomVector2Specification(sP_rotationFromRight_ofCustomVector2, sP_source_ofCustomVector2, sP_customVector2_clipboardForManualInput, sP_customVector_targetGameObject, sP_customVector_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector, sP_lengthRelScaleFactor_ofCustomVector, sP_vectorInterpretation_ofCustomVector, sP_customVectorPicker_isChecked, Get_concernedCustomVector2_inGlobalSpaceUnits, Get_concernedCustomVector2_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition, hideEverythingThatConcernsLocalSpace); + EditorGUI.EndDisabledGroup(); + } + else + { + GUIStyle style_ofPickerHeadline = new GUIStyle(EditorStyles.foldout); + style_ofPickerHeadline.richText = true; + + bool used_isOutfolded = true; + if (skipHeadline == false) + { + sP_customVectorPicker_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_customVectorPicker_isOutfolded.boolValue, foldoutRespCheckboxName, true, style_ofPickerHeadline); + used_isOutfolded = sP_customVectorPicker_isOutfolded.boolValue; + } + + if (used_isOutfolded) + { + DrawContentOfACustomVector2Specification(sP_rotationFromRight_ofCustomVector2, sP_source_ofCustomVector2, sP_customVector2_clipboardForManualInput, sP_customVector_targetGameObject, sP_customVector_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector, sP_lengthRelScaleFactor_ofCustomVector, sP_vectorInterpretation_ofCustomVector, sP_customVectorPicker_isChecked, Get_concernedCustomVector2_inGlobalSpaceUnits, Get_concernedCustomVector2_inLocalSpaceDefinedByParentUnits, hideEverythingThatConcernsLength, hideDisplayOfReadOnlyFinalVectorValues, emptyLineAtEnd_ifOutfolded, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition, hideEverythingThatConcernsLocalSpace); + } + else + { + if (emptyLineAtEnd_ifCollapsed) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + } + } + } + + void DrawContentOfACustomVector2Specification(SerializedProperty sP_rotationFromRight_ofCustomVector2, SerializedProperty sP_source_ofCustomVector2, SerializedProperty sP_customVector2_clipboardForManualInput, SerializedProperty sP_customVector_targetGameObject, SerializedProperty sP_customVector_hasForcedAbsLength, SerializedProperty sP_forcedAbsLength_ofCustomVector, SerializedProperty sP_lengthRelScaleFactor_ofCustomVector, SerializedProperty sP_vectorInterpretation_ofCustomVector, SerializedProperty sP_customVectorPicker_isChecked, VisualizerParent.FlexibleGetCustomVector2 Get_concernedCustomVector2_inGlobalSpaceUnits, VisualizerParent.FlexibleGetCustomVector2 Get_concernedCustomVector2_inLocalSpaceDefinedByParentUnits, bool hideEverythingThatConcernsLength, bool hideDisplayOfReadOnlyFinalVectorValues, bool emptyLineAtEnd_ifOutfolded, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition, bool hideEverythingThatConcernsLocalSpace) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(sP_source_ofCustomVector2, new GUIContent("Vector source")); + + bool forceInterpretationToAlwaysGlobal; + switch (sP_source_ofCustomVector2.enumValueIndex) + { + case (int)VisualizerParent.CustomVector2Source.rotationAroundZStartingFromRight: + EditorGUILayout.PropertyField(sP_rotationFromRight_ofCustomVector2, new GUIContent("Z Angle")); + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector2Source.manualInput: + EditorGUILayout.PropertyField(sP_customVector2_clipboardForManualInput, new GUIContent("Input")); + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector2Source.toOtherGameobject: + EditorGUILayout.PropertyField(sP_customVector_targetGameObject, new GUIContent("Other GameObject")); + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector2Source.fromOtherGameobject: + EditorGUILayout.PropertyField(sP_customVector_targetGameObject, new GUIContent("Other GameObject")); + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector2Source.transformsUp: + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector2Source.transformsRight: + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector2Source.transformsDown: + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector2Source.transformsLeft: + forceInterpretationToAlwaysGlobal = false; + break; + case (int)VisualizerParent.CustomVector2Source.globalUp: + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector2Source.globalRight: + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector2Source.globalDown: + forceInterpretationToAlwaysGlobal = true; + break; + case (int)VisualizerParent.CustomVector2Source.globalLeft: + forceInterpretationToAlwaysGlobal = true; + break; + default: + forceInterpretationToAlwaysGlobal = true; + break; + } + + if (hideEverythingThatConcernsLocalSpace == false) + { + Draw_interpretationChooser_forGlobalOrLocal_V2(sP_vectorInterpretation_ofCustomVector, sP_customVectorPicker_isChecked, forceInterpretationToAlwaysGlobal, sP_source_ofCustomVector2, hideEverythingThatConcernsLength); + } + + if (hideEverythingThatConcernsLength == false) + { + DrawLengthAdjustmentForCustomVector(sP_customVector_hasForcedAbsLength, sP_forcedAbsLength_ofCustomVector, sP_lengthRelScaleFactor_ofCustomVector, fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition); + } + if (hideDisplayOfReadOnlyFinalVectorValues == false) + { + string displayName_ofFinalVectorGlobal = fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition ? "Final vector (global) (read only)" : "Final position (global) (read only)"; + EditorGUILayout.Vector2Field(new GUIContent(displayName_ofFinalVectorGlobal, "This is in units of the global space." + Environment.NewLine + "It is read only."), Get_concernedCustomVector2_inGlobalSpaceUnits()); + + if (hideEverythingThatConcernsLocalSpace == false) + { + string displayName_ofFinalVectorLocal = fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition ? "Final vector (local) (read only)" : "Final position (local) (read only)"; + EditorGUILayout.Vector2Field(new GUIContent(displayName_ofFinalVectorLocal, "This is in units of the local space defined by the parent transform." + Environment.NewLine + Environment.NewLine + "It is read only."), Get_concernedCustomVector2_inLocalSpaceDefinedByParentUnits()); + } + } + if (hideEverythingThatConcernsLength == false) + { + TryDraw_warningHelpBoxes_forNonUniformParentScale_orNonZRotation_V2(sP_customVectorPicker_isChecked); + } + + if (emptyLineAtEnd_ifOutfolded) + { + GUILayout.Space(EditorGUIUtility.singleLineHeight); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void Draw_interpretationChooser_forGlobalOrLocal_V2(SerializedProperty sP_vectorInterpretation_ofCustomVector, SerializedProperty sP_customVectorPicker_isChecked, bool alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace, SerializedProperty sP_source_ofCustomVector2, bool hideEverythingThatConcernsLength) + { + if (hideEverythingThatConcernsLength) + { + if ((sP_source_ofCustomVector2.enumValueIndex == (int)VisualizerParent.CustomVector2Source.rotationAroundZStartingFromRight) || (sP_source_ofCustomVector2.enumValueIndex == (int)VisualizerParent.CustomVector2Source.manualInput)) + { + EditorGUILayout.PropertyField(sP_vectorInterpretation_ofCustomVector, new GUIContent("Vector source interpretation")); + } + } + else + { + if (alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace) + { + EditorGUI.BeginDisabledGroup(alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace); + } + + if (alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace) + { + EditorGUILayout.EnumPopup(new GUIContent("Vector source interpretation"), VisualizerParent.VectorInterpretation.globalSpace); + } + else + { + EditorGUILayout.PropertyField(sP_vectorInterpretation_ofCustomVector, new GUIContent("Vector source interpretation")); + } + + if (alwaysGreyOutAndReturnFalse_whichMeansLeaveItInGlobalSpace) + { + EditorGUI.EndDisabledGroup(); + } + } + } + + void TryDraw_warningHelpBoxes_forNonUniformParentScale_orNonZRotation_V2(SerializedProperty sP_customVectorPicker_isChecked) + { + if ((sP_customVectorPicker_isChecked == null) || sP_customVectorPicker_isChecked.boolValue) + { + if (UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale_2D(transform_onVisualizerObject.parent)) + { + EditorGUILayout.HelpBox("A parent transform has a non-uniform scale. This may lead to wrong or weird results.", MessageType.Warning, true); + } + + if (UtilitiesDXXL_EngineBasics.CheckIfThisOrAParentHasANonZRotation_2D(transform_onVisualizerObject)) + { + EditorGUILayout.HelpBox("This transform or a parent has a non-z rotation. This may lead to wrong or weird results in 2D mode.", MessageType.Warning, true); + } + } + } + + void DrawLengthAdjustmentForCustomVector(SerializedProperty sP_customVector_hasForcedAbsLength, SerializedProperty sP_forcedAbsLength_ofCustomVector, SerializedProperty sP_lengthRelScaleFactor_ofCustomVector, bool fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition) + { + GUIStyle style_ofLengthHeadline = new GUIStyle(); + //style_ofLengthHeadline.fontStyle = FontStyle.Bold; + + string displayName_ofHeadline = fieldDisplayNames_fitVectorMeaningAsDirection_notAsPosition ? "Length" : "Distance from origin"; + EditorGUILayout.LabelField(displayName_ofHeadline, style_ofLengthHeadline); + + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_customVector_hasForcedAbsLength, new GUIContent("Force absolute", "This absolute length value is in units of the space as defined by 'Vector interpretation'.")); + EditorGUI.BeginDisabledGroup(!sP_customVector_hasForcedAbsLength.boolValue); + EditorGUILayout.PropertyField(sP_forcedAbsLength_ofCustomVector, GUIContent.none); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + EditorGUI.BeginDisabledGroup(sP_customVector_hasForcedAbsLength.boolValue); + EditorGUILayout.PropertyField(sP_lengthRelScaleFactor_ofCustomVector, new GUIContent("Scale relative")); + EditorGUI.EndDisabledGroup(); + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + public void DrawTextInputInclMarkupHelper(bool inputTextAs_multiLineArea = true, bool emptyLineAtEndEvenIfCollapsed = false, string overwrite_nameOfTextField = null, bool emptyLineAtEndIfOutfolded = true, bool displaySizeScalingStyleOption = true) + { + SerializedProperty sP_text_exclGlobalMarkupTags = serializedObject.FindProperty("text_exclGlobalMarkupTags"); + SerializedProperty sP_text_inclGlobalMarkupTags = serializedObject.FindProperty("text_inclGlobalMarkupTags"); + SerializedProperty sP_textSection_isOutfolded = serializedObject.FindProperty("textSection_isOutfolded"); + SerializedProperty sP_textStyleSection_isOutfolded = serializedObject.FindProperty("textStyleSection_isOutfolded"); + SerializedProperty sP_textMarkupHelperSection_isOutfolded = serializedObject.FindProperty("textMarkupHelperSection_isOutfolded"); + + SerializedProperty sP_globalText_isBold = serializedObject.FindProperty("globalText_isBold"); + + SerializedProperty sP_globalText_isStrokeWidthModified = serializedObject.FindProperty("globalText_isStrokeWidthModified"); + SerializedProperty sP_curr_strokeWidthSize0to1_forGlobalMarkup = serializedObject.FindProperty("curr_strokeWidthSize0to1_forGlobalMarkup"); + + SerializedProperty sP_globalText_isItalic = serializedObject.FindProperty("globalText_isItalic"); + SerializedProperty sP_globalText_isUnderlined = serializedObject.FindProperty("globalText_isUnderlined"); + SerializedProperty sP_globalText_isDeleted = serializedObject.FindProperty("globalText_isDeleted"); + + SerializedProperty sP_globalText_isSizeModified = serializedObject.FindProperty("globalText_isSizeModified"); + SerializedProperty sP_curr_sizeScaleFactor_forGlobalMarkup = serializedObject.FindProperty("curr_sizeScaleFactor_forGlobalMarkup"); + + SerializedProperty sP_globalText_isColorModified = serializedObject.FindProperty("globalText_isColorModified"); + SerializedProperty sP_curr_color_forGlobalMarkup = serializedObject.FindProperty("curr_color_forGlobalMarkup"); + + if (sP_text_inclGlobalMarkupTags.stringValue == null) { sP_text_inclGlobalMarkupTags.stringValue = MarkupGlobalText(sP_text_exclGlobalMarkupTags.stringValue, sP_globalText_isBold.boolValue, sP_globalText_isItalic.boolValue, sP_globalText_isUnderlined.boolValue, sP_globalText_isDeleted.boolValue, sP_globalText_isSizeModified.boolValue, sP_globalText_isColorModified.boolValue, sP_globalText_isStrokeWidthModified.boolValue, sP_curr_sizeScaleFactor_forGlobalMarkup.floatValue, sP_curr_color_forGlobalMarkup.colorValue, sP_curr_strokeWidthSize0to1_forGlobalMarkup.floatValue); } + + GUIStyle style_forFoldoutLine = new GUIStyle(EditorStyles.foldout); + sP_textSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_textSection_isOutfolded.boolValue, "Text", true, style_forFoldoutLine); + if (sP_textSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + + string tooltip_for_inputTextField = "You can use rich text markup here, for example to make words bold."; + EditorGUI.BeginChangeCheck(); + if (inputTextAs_multiLineArea) + { + string used_textFieldName = (overwrite_nameOfTextField == null) ? "Drawn text tag:" : overwrite_nameOfTextField; + EditorGUILayout.LabelField(new GUIContent(used_textFieldName, tooltip_for_inputTextField)); + sP_text_exclGlobalMarkupTags.stringValue = EditorGUILayout.TextArea(sP_text_exclGlobalMarkupTags.stringValue); + } + else + { + string used_textFieldName = (overwrite_nameOfTextField == null) ? "Drawn text tag" : overwrite_nameOfTextField; + EditorGUILayout.PropertyField(sP_text_exclGlobalMarkupTags, new GUIContent(used_textFieldName, tooltip_for_inputTextField)); + } + bool mainInputText_changed = EditorGUI.EndChangeCheck(); + if (mainInputText_changed) { sP_text_inclGlobalMarkupTags.stringValue = MarkupGlobalText(sP_text_exclGlobalMarkupTags.stringValue, sP_globalText_isBold.boolValue, sP_globalText_isItalic.boolValue, sP_globalText_isUnderlined.boolValue, sP_globalText_isDeleted.boolValue, sP_globalText_isSizeModified.boolValue, sP_globalText_isColorModified.boolValue, sP_globalText_isStrokeWidthModified.boolValue, sP_curr_sizeScaleFactor_forGlobalMarkup.floatValue, sP_curr_color_forGlobalMarkup.colorValue, sP_curr_strokeWidthSize0to1_forGlobalMarkup.floatValue); } + + sP_textStyleSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_textStyleSection_isOutfolded.boolValue, "Style", true); + if (sP_textStyleSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + sP_text_inclGlobalMarkupTags.stringValue = DrawGlobalTextStyleOptions(sP_text_exclGlobalMarkupTags, sP_text_inclGlobalMarkupTags.stringValue, sP_globalText_isBold, sP_globalText_isStrokeWidthModified, sP_curr_strokeWidthSize0to1_forGlobalMarkup, sP_globalText_isItalic, sP_globalText_isUnderlined, sP_globalText_isDeleted, sP_globalText_isSizeModified, sP_curr_sizeScaleFactor_forGlobalMarkup, sP_globalText_isColorModified, sP_curr_color_forGlobalMarkup, displaySizeScalingStyleOption); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + sP_textMarkupHelperSection_isOutfolded.boolValue = EditorGUILayout.Foldout(sP_textMarkupHelperSection_isOutfolded.boolValue, "Markup snippet creator", true); + if (sP_textMarkupHelperSection_isOutfolded.boolValue) + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + DrawSnippetMarkupCreator(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + if (emptyLineAtEndIfOutfolded) + { + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + else + { + if (emptyLineAtEndEvenIfCollapsed) + { + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + } + } + } + + string DrawGlobalTextStyleOptions(SerializedProperty sP_text_exclGlobalMarkupTags, string text_inclGlobalMarkupTags, SerializedProperty sP_globalText_isBold, SerializedProperty sP_globalText_isStrokeWidthModified, SerializedProperty sP_curr_strokeWidthSize0to1_forGlobalMarkup, SerializedProperty sP_globalText_isItalic, SerializedProperty sP_globalText_isUnderlined, SerializedProperty sP_globalText_isDeleted, SerializedProperty sP_globalText_isSizeModified, SerializedProperty sP_curr_sizeScaleFactor_forGlobalMarkup, SerializedProperty sP_globalText_isColorModified, SerializedProperty sP_curr_color_forGlobalMarkup, bool displaySizeScalingStyleOption) + { + EditorGUI.BeginChangeCheck(); + + EditorGUILayout.PropertyField(sP_globalText_isBold, new GUIContent("Bold")); + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_globalText_isStrokeWidthModified, new GUIContent("Custom stroke width")); + EditorGUI.BeginDisabledGroup(!sP_globalText_isStrokeWidthModified.boolValue); + sP_curr_strokeWidthSize0to1_forGlobalMarkup.floatValue = EditorGUILayout.Slider(sP_curr_strokeWidthSize0to1_forGlobalMarkup.floatValue, 0.0f, 1.0f); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + EditorGUILayout.PropertyField(sP_globalText_isItalic, new GUIContent("Italic")); + + EditorGUILayout.PropertyField(sP_globalText_isUnderlined, new GUIContent("Underlined")); + + EditorGUILayout.PropertyField(sP_globalText_isDeleted, new GUIContent("Deleted")); + + if (displaySizeScalingStyleOption) + { + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_globalText_isSizeModified, new GUIContent("Size scaling")); + EditorGUI.BeginDisabledGroup(!sP_globalText_isSizeModified.boolValue); + sP_curr_sizeScaleFactor_forGlobalMarkup.floatValue = EditorGUILayout.Slider(sP_curr_sizeScaleFactor_forGlobalMarkup.floatValue, 0.1f, 20.0f); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + } + + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_globalText_isColorModified, new GUIContent("Colored")); + EditorGUI.BeginDisabledGroup(!sP_globalText_isColorModified.boolValue); + sP_curr_color_forGlobalMarkup.colorValue = EditorGUILayout.ColorField(sP_curr_color_forGlobalMarkup.colorValue); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + + bool globalMarkupConfig_changed = EditorGUI.EndChangeCheck(); + if (globalMarkupConfig_changed) { text_inclGlobalMarkupTags = MarkupGlobalText(sP_text_exclGlobalMarkupTags.stringValue, sP_globalText_isBold.boolValue, sP_globalText_isItalic.boolValue, sP_globalText_isUnderlined.boolValue, sP_globalText_isDeleted.boolValue, sP_globalText_isSizeModified.boolValue, sP_globalText_isColorModified.boolValue, sP_globalText_isStrokeWidthModified.boolValue, sP_curr_sizeScaleFactor_forGlobalMarkup.floatValue, sP_curr_color_forGlobalMarkup.colorValue, sP_curr_strokeWidthSize0to1_forGlobalMarkup.floatValue); } + + GUILayout.Space(1.0f * EditorGUIUtility.singleLineHeight); + return text_inclGlobalMarkupTags; + } + + string MarkupGlobalText(string text_withoutMarkupTags, bool globalText_isBold, bool globalText_isItalic, bool globalText_isUnderlined, bool globalText_isDeleted, bool globalText_isSizeModified, bool globalText_isColorModified, bool globalText_isStrokeWidthModified, float curr_sizeScaleFactor_forGlobalMarkup, Color curr_color_forGlobalMarkup, float curr_strokeWidthSize0to1_forGlobalMarkup) + { + string resultingText_withMarkupTags = null; + MarkupTextSnippet(false, ref resultingText_withMarkupTags, text_withoutMarkupTags, globalText_isBold, globalText_isItalic, globalText_isUnderlined, globalText_isDeleted, globalText_isSizeModified, globalText_isColorModified, globalText_isStrokeWidthModified, curr_sizeScaleFactor_forGlobalMarkup, curr_color_forGlobalMarkup, curr_strokeWidthSize0to1_forGlobalMarkup, false, false, false, false); + if (resultingText_withMarkupTags == null) { resultingText_withMarkupTags = ""; } + return resultingText_withMarkupTags; + } + + void DrawSnippetMarkupCreator() + { + SerializedProperty sP_markupSnippetText_isBold = serializedObject.FindProperty("markupSnippetText_isBold"); + SerializedProperty sP_markupSnippetText_escapesBold = serializedObject.FindProperty("markupSnippetText_escapesBold"); + + SerializedProperty sP_markupSnippetText_isStrokeWidthModified = serializedObject.FindProperty("markupSnippetText_isStrokeWidthModified"); + SerializedProperty sP_curr_strokeWidthSize0to1_forMarkupSnippet = serializedObject.FindProperty("curr_strokeWidthSize0to1_forMarkupSnippet"); + + SerializedProperty sP_markupSnippetText_isItalic = serializedObject.FindProperty("markupSnippetText_isItalic"); + SerializedProperty sP_markupSnippetText_escapesItalic = serializedObject.FindProperty("markupSnippetText_escapesItalic"); + + SerializedProperty sP_markupSnippetText_isUnderlined = serializedObject.FindProperty("markupSnippetText_isUnderlined"); + SerializedProperty sP_markupSnippetText_escapesUnderlined = serializedObject.FindProperty("markupSnippetText_escapesUnderlined"); + + SerializedProperty sP_markupSnippetText_isDeleted = serializedObject.FindProperty("markupSnippetText_isDeleted"); + SerializedProperty sP_markupSnippetText_escapesDeleted = serializedObject.FindProperty("markupSnippetText_escapesDeleted"); + + SerializedProperty sP_markupSnippetText_isSizeModified = serializedObject.FindProperty("markupSnippetText_isSizeModified"); + SerializedProperty sP_curr_sizeScaleFactor_forMarkupSnippet = serializedObject.FindProperty("curr_sizeScaleFactor_forMarkupSnippet"); + + SerializedProperty sP_markupSnippetText_isColorModified = serializedObject.FindProperty("markupSnippetText_isColorModified"); + SerializedProperty sP_curr_color_forMarkupSnippet = serializedObject.FindProperty("curr_color_forMarkupSnippet"); + + SerializedProperty sP_curr_heightOfEmptyLine_forMarkupCreator = serializedObject.FindProperty("curr_heightOfEmptyLine_forMarkupCreator"); + + EditorGUILayout.HelpBox("You can use this to easily create text snippets inside markup tags that you can copy into the drawn text field (or into your code)." + Environment.NewLine + Environment.NewLine + "With the created snippets you can have for each word (or letter) different styles that differ from to the global 'Style' settings above.", MessageType.None, true); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + + SerializedProperty sP_textSnippet_toPutInMarkupTags = serializedObject.FindProperty("textSnippet_toPutInMarkupTags"); + SerializedProperty sP_curr_iconType_forMarkupCreator = serializedObject.FindProperty("curr_iconType_forMarkupCreator"); + SerializedProperty sP_curr_textMarkupInputSnippetOptions = serializedObject.FindProperty("curr_textMarkupInputSnippetOptions"); + SerializedProperty sP_curr_logType_forMarkupCreator = serializedObject.FindProperty("curr_logType_forMarkupCreator"); + + SerializedProperty sP_resultTextSnippet_insideMarkupTags_forTextInput = serializedObject.FindProperty("resultTextSnippet_insideMarkupTags_forTextInput"); + SerializedProperty sP_resultTextSnippet_insideMarkupTags_forIconInput = serializedObject.FindProperty("resultTextSnippet_insideMarkupTags_forIconInput"); + SerializedProperty sP_resultTextSnippet_insideMarkupTags_forCustomHeightEmptyLineInput = serializedObject.FindProperty("resultTextSnippet_insideMarkupTags_forCustomHeightEmptyLineInput"); + SerializedProperty sP_resultTextSnippet_insideMarkupTags_forLogSymbolInput = serializedObject.FindProperty("resultTextSnippet_insideMarkupTags_forLogSymbolInput"); + + EditorGUI.BeginChangeCheck(); + + EditorGUILayout.PropertyField(sP_curr_textMarkupInputSnippetOptions, new GUIContent("Input type")); + + GUILayout.Space(spaceBetweenMarkupStyleOptions); + + GUIStyle style_ofSnippetCreatorSubHeadlines = new GUIStyle(); + style_ofSnippetCreatorSubHeadlines.fontStyle = FontStyle.Bold; + EditorGUILayout.LabelField("Snippet", style_ofSnippetCreatorSubHeadlines); + + switch (sP_curr_textMarkupInputSnippetOptions.enumValueIndex) + { + case ((int)VisualizerParent.TextMarkupInputSnippetOptions.text): + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(sP_textSnippet_toPutInMarkupTags, new GUIContent("Input")); + EditorGUILayout.TextField("Output", sP_resultTextSnippet_insideMarkupTags_forTextInput.stringValue); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + DrawSnippetOptionsForInputTypeOf_text(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isBold, sP_markupSnippetText_escapesBold, sP_markupSnippetText_isStrokeWidthModified, sP_curr_strokeWidthSize0to1_forMarkupSnippet, sP_markupSnippetText_isItalic, sP_markupSnippetText_escapesItalic, sP_markupSnippetText_isUnderlined, sP_markupSnippetText_escapesUnderlined, sP_markupSnippetText_isDeleted, sP_markupSnippetText_escapesDeleted, sP_markupSnippetText_isSizeModified, sP_curr_sizeScaleFactor_forMarkupSnippet, sP_markupSnippetText_isColorModified, sP_curr_color_forMarkupSnippet); + break; + case ((int)VisualizerParent.TextMarkupInputSnippetOptions.icon): + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(sP_curr_iconType_forMarkupCreator, new GUIContent("Icon type")); + EditorGUILayout.TextField("Output", sP_resultTextSnippet_insideMarkupTags_forIconInput.stringValue); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + DrawSnippetOptionsForInputTypeOf_text(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isBold, sP_markupSnippetText_escapesBold, sP_markupSnippetText_isStrokeWidthModified, sP_curr_strokeWidthSize0to1_forMarkupSnippet, sP_markupSnippetText_isItalic, sP_markupSnippetText_escapesItalic, sP_markupSnippetText_isUnderlined, sP_markupSnippetText_escapesUnderlined, sP_markupSnippetText_isDeleted, sP_markupSnippetText_escapesDeleted, sP_markupSnippetText_isSizeModified, sP_curr_sizeScaleFactor_forMarkupSnippet, sP_markupSnippetText_isColorModified, sP_curr_color_forMarkupSnippet); + break; + case ((int)VisualizerParent.TextMarkupInputSnippetOptions.customHeightEmptyLine): + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.TextField("Output", sP_resultTextSnippet_insideMarkupTags_forCustomHeightEmptyLineInput.stringValue); + DrawSnippetOptionsForInputTypeOf_customHeightEmptyLine(sP_curr_heightOfEmptyLine_forMarkupCreator); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + case ((int)VisualizerParent.TextMarkupInputSnippetOptions.logSymbol): + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(sP_curr_logType_forMarkupCreator, new GUIContent("Log type")); + EditorGUILayout.TextField("Output", sP_resultTextSnippet_insideMarkupTags_forLogSymbolInput.stringValue); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + DrawSnippetOptionsForInputTypeOf_logSymbol(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isBold, sP_markupSnippetText_escapesBold, sP_markupSnippetText_isStrokeWidthModified, sP_curr_strokeWidthSize0to1_forMarkupSnippet, sP_markupSnippetText_isItalic, sP_markupSnippetText_escapesItalic, sP_markupSnippetText_isUnderlined, sP_markupSnippetText_escapesUnderlined, sP_markupSnippetText_isDeleted, sP_markupSnippetText_escapesDeleted, sP_markupSnippetText_isSizeModified, sP_curr_sizeScaleFactor_forMarkupSnippet); + break; + case ((int)VisualizerParent.TextMarkupInputSnippetOptions.lineBreak): + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.TextField("Output", "
"); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + break; + default: + break; + } + bool markupSnippedInputConfig_changed = EditorGUI.EndChangeCheck(); + if (markupSnippedInputConfig_changed) { MarkupSnippets(ref sP_resultTextSnippet_insideMarkupTags_forTextInput, ref sP_resultTextSnippet_insideMarkupTags_forIconInput, ref sP_resultTextSnippet_insideMarkupTags_forCustomHeightEmptyLineInput, ref sP_resultTextSnippet_insideMarkupTags_forLogSymbolInput, sP_textSnippet_toPutInMarkupTags.stringValue, (DrawBasics.IconType)sP_curr_iconType_forMarkupCreator.enumValueIndex, (LogType)sP_curr_logType_forMarkupCreator.enumValueIndex, sP_curr_heightOfEmptyLine_forMarkupCreator.floatValue, sP_markupSnippetText_isBold.boolValue, sP_markupSnippetText_isItalic.boolValue, sP_markupSnippetText_isUnderlined.boolValue, sP_markupSnippetText_isDeleted.boolValue, sP_markupSnippetText_isSizeModified.boolValue, sP_markupSnippetText_isColorModified.boolValue, sP_markupSnippetText_isStrokeWidthModified.boolValue, sP_curr_sizeScaleFactor_forMarkupSnippet.floatValue, sP_curr_color_forMarkupSnippet.colorValue, sP_curr_strokeWidthSize0to1_forMarkupSnippet.floatValue, sP_markupSnippetText_escapesBold.boolValue, sP_markupSnippetText_escapesItalic.boolValue, sP_markupSnippetText_escapesUnderlined.boolValue, sP_markupSnippetText_escapesDeleted.boolValue); } + } + + void MarkupSnippets(ref SerializedProperty sP_resultTextSnippet_insideMarkupTags_forTextInput, ref SerializedProperty sP_resultTextSnippet_insideMarkupTags_forIconInput, ref SerializedProperty sP_resultTextSnippet_insideMarkupTags_forCustomHeightEmptyLineInput, ref SerializedProperty sP_resultTextSnippet_insideMarkupTags_forLogSymbolInput, string textSnippet_toPutInMarkupTags, DrawBasics.IconType curr_iconType_forMarkupCreator, LogType curr_logType_forMarkupCreator, float curr_heightOfEmptyLine_forMarkupCreator, bool markupSnippetText_isBold, bool markupSnippetText_isItalic, bool markupSnippetText_isUnderlined, bool markupSnippetText_isDeleted, bool markupSnippetText_isSizeModified, bool markupSnippetText_isColorModified, bool markupSnippetText_isStrokeWidthModified, float curr_sizeScaleFactor_forMarkupSnippet, Color curr_color_forMarkupSnippet, float curr_strokeWidthSize0to1_forMarkupSnippet, bool markupSnippetText_escapesBold, bool markupSnippetText_escapesItalic, bool markupSnippetText_escapesUnderlined, bool markupSnippetText_escapesDeleted) + { + string resultTextSnippet_insideMarkupTags_forTextInput = null; + MarkupTextSnippet(true, ref resultTextSnippet_insideMarkupTags_forTextInput, textSnippet_toPutInMarkupTags, markupSnippetText_isBold, markupSnippetText_isItalic, markupSnippetText_isUnderlined, markupSnippetText_isDeleted, markupSnippetText_isSizeModified, markupSnippetText_isColorModified, markupSnippetText_isStrokeWidthModified, curr_sizeScaleFactor_forMarkupSnippet, curr_color_forMarkupSnippet, curr_strokeWidthSize0to1_forMarkupSnippet, markupSnippetText_escapesBold, markupSnippetText_escapesItalic, markupSnippetText_escapesUnderlined, markupSnippetText_escapesDeleted); + if (resultTextSnippet_insideMarkupTags_forTextInput == null) { resultTextSnippet_insideMarkupTags_forTextInput = ""; } + sP_resultTextSnippet_insideMarkupTags_forTextInput.stringValue = resultTextSnippet_insideMarkupTags_forTextInput; + + string resultTextSnippet_insideMarkupTags_forIconInput = null; + MarkupTextSnippet(true, ref resultTextSnippet_insideMarkupTags_forIconInput, DrawText.MarkupIcon(curr_iconType_forMarkupCreator), markupSnippetText_isBold, markupSnippetText_isItalic, markupSnippetText_isUnderlined, markupSnippetText_isDeleted, markupSnippetText_isSizeModified, markupSnippetText_isColorModified, markupSnippetText_isStrokeWidthModified, curr_sizeScaleFactor_forMarkupSnippet, curr_color_forMarkupSnippet, curr_strokeWidthSize0to1_forMarkupSnippet, markupSnippetText_escapesBold, markupSnippetText_escapesItalic, markupSnippetText_escapesUnderlined, markupSnippetText_escapesDeleted); + if (resultTextSnippet_insideMarkupTags_forIconInput == null) { resultTextSnippet_insideMarkupTags_forIconInput = ""; } + sP_resultTextSnippet_insideMarkupTags_forIconInput.stringValue = resultTextSnippet_insideMarkupTags_forIconInput; + + string resultTextSnippet_insideMarkupTags_forLogSymbolInput = null; + MarkupTextSnippet(true, ref resultTextSnippet_insideMarkupTags_forLogSymbolInput, DrawText.MarkupLogSymbol(curr_logType_forMarkupCreator), markupSnippetText_isBold, markupSnippetText_isItalic, markupSnippetText_isUnderlined, markupSnippetText_isDeleted, markupSnippetText_isSizeModified, false, markupSnippetText_isStrokeWidthModified, curr_sizeScaleFactor_forMarkupSnippet, default(Color), curr_strokeWidthSize0to1_forMarkupSnippet, markupSnippetText_escapesBold, markupSnippetText_escapesItalic, markupSnippetText_escapesUnderlined, markupSnippetText_escapesDeleted); + if (resultTextSnippet_insideMarkupTags_forLogSymbolInput == null) { resultTextSnippet_insideMarkupTags_forLogSymbolInput = ""; } + sP_resultTextSnippet_insideMarkupTags_forLogSymbolInput.stringValue = resultTextSnippet_insideMarkupTags_forLogSymbolInput; + + sP_resultTextSnippet_insideMarkupTags_forCustomHeightEmptyLineInput.stringValue = DrawText.MarkupCustomHeightEmptyLine(curr_heightOfEmptyLine_forMarkupCreator); + } + + void MarkupTextSnippet(bool isForMarkupSnippet, ref string stringToFill, string text_withoutMarkupTags, bool isBold, bool isItalic, bool isUnderlined, bool isDeleted, bool isSizeModified, bool isColorModified, bool isStrokeWidthModified, float sizeScaleFactor, Color color, float strokeWidthSizeInPPMofSize, bool markupSnippetText_escapesBold, bool markupSnippetText_escapesItalic, bool markupSnippetText_escapesUnderlined, bool markupSnippetText_escapesDeleted) + { + if (text_withoutMarkupTags != null && text_withoutMarkupTags != "") + { + stringToFill = "" + text_withoutMarkupTags; + + if (isBold) + { + stringToFill = DrawText.MarkupBold(stringToFill); + } + else + { + if (isForMarkupSnippet) + { + if (markupSnippetText_escapesBold) + { + stringToFill = DrawText.MarkupBoldEscape(stringToFill); + } + } + } + + if (isItalic) + { + stringToFill = DrawText.MarkupItalic(stringToFill); + } + else + { + if (isForMarkupSnippet) + { + if (markupSnippetText_escapesItalic) + { + stringToFill = DrawText.MarkupItalicEscape(stringToFill); + } + } + } + + if (isUnderlined) + { + stringToFill = DrawText.MarkupUnderlined(stringToFill); + } + else + { + if (isForMarkupSnippet) + { + if (markupSnippetText_escapesUnderlined) + { + stringToFill = DrawText.MarkupUnderlinedEscape(stringToFill); + } + } + } + + if (isDeleted) + { + stringToFill = DrawText.MarkupDeleted(stringToFill); + } + else + { + if (isForMarkupSnippet) + { + if (markupSnippetText_escapesDeleted) + { + stringToFill = DrawText.MarkupDeletedEscape(stringToFill); + } + } + } + + if (isSizeModified) + { + stringToFill = DrawText.MarkupSize(stringToFill, sizeScaleFactor); + } + + if (isColorModified) + { + stringToFill = DrawText.MarkupColor(stringToFill, color); + } + + if (isStrokeWidthModified) + { + stringToFill = DrawText.MarkupStrokeWidth(stringToFill, Float0to1_to_intStrokeWidthInPPMofSize(strokeWidthSizeInPPMofSize)); + } + } + } + + int Float0to1_to_intStrokeWidthInPPMofSize(float float0to1) + { + return Mathf.RoundToInt(float0to1 * UtilitiesDXXL_Text.maxRelStrokeWidth_inPPMofSize); + } + + float spaceBetweenMarkupStyleOptions = 0.5f * EditorGUIUtility.singleLineHeight; + void DrawSnippetOptionsForInputTypeOf_text(GUIStyle style_ofSnippetCreatorSubHeadlines, SerializedProperty sP_markupSnippetText_isBold, SerializedProperty sP_markupSnippetText_escapesBold, SerializedProperty sP_markupSnippetText_isStrokeWidthModified, SerializedProperty sP_curr_strokeWidthSize0to1_forMarkupSnippet, SerializedProperty sP_markupSnippetText_isItalic, SerializedProperty sP_markupSnippetText_escapesItalic, SerializedProperty sP_markupSnippetText_isUnderlined, SerializedProperty sP_markupSnippetText_escapesUnderlined, SerializedProperty sP_markupSnippetText_isDeleted, SerializedProperty sP_markupSnippetText_escapesDeleted, SerializedProperty sP_markupSnippetText_isSizeModified, SerializedProperty sP_curr_sizeScaleFactor_forMarkupSnippet, SerializedProperty sP_markupSnippetText_isColorModified, SerializedProperty sP_curr_color_forMarkupSnippet) + { + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_bold(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isBold, sP_markupSnippetText_escapesBold); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_strokeWidth(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isStrokeWidthModified, sP_curr_strokeWidthSize0to1_forMarkupSnippet); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_italic(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isItalic, sP_markupSnippetText_escapesItalic); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_underlined(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isUnderlined, sP_markupSnippetText_escapesUnderlined); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_deleted(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isDeleted, sP_markupSnippetText_escapesDeleted); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_sizeScaling(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isSizeModified, sP_curr_sizeScaleFactor_forMarkupSnippet); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_color(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isColorModified, sP_curr_color_forMarkupSnippet); + } + + void DrawSnippetOptionsForInputTypeOf_customHeightEmptyLine(SerializedProperty sP_curr_heightOfEmptyLine_forMarkupCreator) + { + EditorGUILayout.PropertyField(sP_curr_heightOfEmptyLine_forMarkupCreator, new GUIContent("Gap size", "A value of 1 means the gap has the height of 1 line.")); + } + + void DrawSnippetOptionsForInputTypeOf_logSymbol(GUIStyle style_ofSnippetCreatorSubHeadlines, SerializedProperty sP_markupSnippetText_isBold, SerializedProperty sP_markupSnippetText_escapesBold, SerializedProperty sP_markupSnippetText_isStrokeWidthModified, SerializedProperty sP_curr_strokeWidthSize0to1_forMarkupSnippet, SerializedProperty sP_markupSnippetText_isItalic, SerializedProperty sP_markupSnippetText_escapesItalic, SerializedProperty sP_markupSnippetText_isUnderlined, SerializedProperty sP_markupSnippetText_escapesUnderlined, SerializedProperty sP_markupSnippetText_isDeleted, SerializedProperty sP_markupSnippetText_escapesDeleted, SerializedProperty sP_markupSnippetText_isSizeModified, SerializedProperty sP_curr_sizeScaleFactor_forMarkupSnippet) + { + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_bold(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isBold, sP_markupSnippetText_escapesBold); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_strokeWidth(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isStrokeWidthModified, sP_curr_strokeWidthSize0to1_forMarkupSnippet); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_italic(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isItalic, sP_markupSnippetText_escapesItalic); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_underlined(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isUnderlined, sP_markupSnippetText_escapesUnderlined); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_deleted(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isDeleted, sP_markupSnippetText_escapesDeleted); + GUILayout.Space(spaceBetweenMarkupStyleOptions); + DrawSnippetOption_sizeScaling(style_ofSnippetCreatorSubHeadlines, sP_markupSnippetText_isSizeModified, sP_curr_sizeScaleFactor_forMarkupSnippet); + } + + void DrawSnippetOption_bold(GUIStyle style_ofSnippetCreatorSubHeadlines, SerializedProperty sP_markupSnippetText_isBold, SerializedProperty sP_markupSnippetText_escapesBold) + { + EditorGUILayout.LabelField("Bold", style_ofSnippetCreatorSubHeadlines); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUI.BeginDisabledGroup(sP_markupSnippetText_escapesBold.boolValue); + EditorGUILayout.PropertyField(sP_markupSnippetText_isBold, new GUIContent("Enable")); + EditorGUI.EndDisabledGroup(); + GUIContent guiContent_for_escapeToggle = new GUIContent("Escape enclosing", "If you copy the created snippet into a text that is already bold, then this will remove the enclosing bold style from the snippet." + Environment.NewLine + Environment.NewLine + "Warning: If the enclosing text is NOT bold this will lead to a confusing faulty final text."); + EditorGUILayout.PropertyField(sP_markupSnippetText_escapesBold, guiContent_for_escapeToggle); + if (sP_markupSnippetText_escapesBold.boolValue) { sP_markupSnippetText_isBold.boolValue = false; } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawSnippetOption_strokeWidth(GUIStyle style_ofSnippetCreatorSubHeadlines, SerializedProperty sP_markupSnippetText_isStrokeWidthModified, SerializedProperty sP_curr_strokeWidthSize0to1_forMarkupSnippet) + { + EditorGUILayout.LabelField("Stroke width", style_ofSnippetCreatorSubHeadlines); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_markupSnippetText_isStrokeWidthModified, new GUIContent("Enable")); + EditorGUI.BeginDisabledGroup(!sP_markupSnippetText_isStrokeWidthModified.boolValue); + sP_curr_strokeWidthSize0to1_forMarkupSnippet.floatValue = EditorGUILayout.Slider(sP_curr_strokeWidthSize0to1_forMarkupSnippet.floatValue, 0.0f, 1.0f); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawSnippetOption_italic(GUIStyle style_ofSnippetCreatorSubHeadlines, SerializedProperty sP_markupSnippetText_isItalic, SerializedProperty sP_markupSnippetText_escapesItalic) + { + EditorGUILayout.LabelField("Italic", style_ofSnippetCreatorSubHeadlines); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUI.BeginDisabledGroup(sP_markupSnippetText_escapesItalic.boolValue); + EditorGUILayout.PropertyField(sP_markupSnippetText_isItalic, new GUIContent("Enable")); + EditorGUI.EndDisabledGroup(); + GUIContent guiContent_for_escapeToggle = new GUIContent("Escape enclosing", "If you copy the created snippet into a text that is already italic, then this will remove the enclosing italic style from the snippet." + Environment.NewLine + Environment.NewLine + "Warning: If the enclosing text is NOT italic this will lead to a confusing faulty final text."); + EditorGUILayout.PropertyField(sP_markupSnippetText_escapesItalic, guiContent_for_escapeToggle); + if (sP_markupSnippetText_escapesItalic.boolValue) { sP_markupSnippetText_isItalic.boolValue = false; } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawSnippetOption_underlined(GUIStyle style_ofSnippetCreatorSubHeadlines, SerializedProperty sP_markupSnippetText_isUnderlined, SerializedProperty sP_markupSnippetText_escapesUnderlined) + { + EditorGUILayout.LabelField("Underlined", style_ofSnippetCreatorSubHeadlines); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUI.BeginDisabledGroup(sP_markupSnippetText_escapesUnderlined.boolValue); + EditorGUILayout.PropertyField(sP_markupSnippetText_isUnderlined, new GUIContent("Enable")); + EditorGUI.EndDisabledGroup(); + GUIContent guiContent_for_escapeToggle = new GUIContent("Escape enclosing", "If you copy the created snippet into a text that is already underlined, then this will remove the enclosing underlined style from the snippet." + Environment.NewLine + Environment.NewLine + "Warning: If the enclosing text is NOT underlined this will lead to a confusing faulty final text."); + EditorGUILayout.PropertyField(sP_markupSnippetText_escapesUnderlined, guiContent_for_escapeToggle); + if (sP_markupSnippetText_escapesUnderlined.boolValue) { sP_markupSnippetText_isUnderlined.boolValue = false; } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawSnippetOption_deleted(GUIStyle style_ofSnippetCreatorSubHeadlines, SerializedProperty sP_markupSnippetText_isDeleted, SerializedProperty sP_markupSnippetText_escapesDeleted) + { + EditorGUILayout.LabelField("Deleted", style_ofSnippetCreatorSubHeadlines); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUI.BeginDisabledGroup(sP_markupSnippetText_escapesDeleted.boolValue); + EditorGUILayout.PropertyField(sP_markupSnippetText_isDeleted, new GUIContent("Enable")); + EditorGUI.EndDisabledGroup(); + GUIContent guiContent_for_escapeToggle = new GUIContent("Escape enclosing", "If you copy the created snippet into a text that is already deleted, then this will remove the enclosing deleted style from the snippet." + Environment.NewLine + Environment.NewLine + "Warning: If the enclosing text is NOT deleted this will lead to a confusing faulty final text."); + EditorGUILayout.PropertyField(sP_markupSnippetText_escapesDeleted, guiContent_for_escapeToggle); + if (sP_markupSnippetText_escapesDeleted.boolValue) { sP_markupSnippetText_isDeleted.boolValue = false; } + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawSnippetOption_sizeScaling(GUIStyle style_ofSnippetCreatorSubHeadlines, SerializedProperty sP_markupSnippetText_isSizeModified, SerializedProperty sP_curr_sizeScaleFactor_forMarkupSnippet) + { + EditorGUILayout.LabelField("Size scaling", style_ofSnippetCreatorSubHeadlines); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_markupSnippetText_isSizeModified, new GUIContent("Enable")); + EditorGUI.BeginDisabledGroup(!sP_markupSnippetText_isSizeModified.boolValue); + sP_curr_sizeScaleFactor_forMarkupSnippet.floatValue = EditorGUILayout.Slider(sP_curr_sizeScaleFactor_forMarkupSnippet.floatValue, 0.1f, 20.0f); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + void DrawSnippetOption_color(GUIStyle style_ofSnippetCreatorSubHeadlines, SerializedProperty sP_markupSnippetText_isColorModified, SerializedProperty sP_curr_color_forMarkupSnippet) + { + EditorGUILayout.LabelField("Color", style_ofSnippetCreatorSubHeadlines); + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + GUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sP_markupSnippetText_isColorModified, new GUIContent("Enable")); + EditorGUI.BeginDisabledGroup(!sP_markupSnippetText_isColorModified.boolValue); + sP_curr_color_forMarkupSnippet.colorValue = EditorGUILayout.ColorField(sP_curr_color_forMarkupSnippet.colorValue); + EditorGUI.EndDisabledGroup(); + GUILayout.EndHorizontal(); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/VisualizerParentInspector.cs.meta b/Editor/DrawDebugLibrary/VisualizerParentInspector.cs.meta new file mode 100644 index 0000000..71ac2de --- /dev/null +++ b/Editor/DrawDebugLibrary/VisualizerParentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: efd8084923da7964681f4c555a2abb1e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/VisualizerScreenspaceParentInspector.cs b/Editor/DrawDebugLibrary/VisualizerScreenspaceParentInspector.cs new file mode 100644 index 0000000..9fe4795 --- /dev/null +++ b/Editor/DrawDebugLibrary/VisualizerScreenspaceParentInspector.cs @@ -0,0 +1,87 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + [CustomEditor(typeof(VisualizerScreenspaceParent))] + [CanEditMultipleObjects] + public class VisualizerScreenspaceParentInspector : VisualizerParentInspector + { + public string tooltip_explaining_relativeToViewPortHeight = "This is relative to the viewport height."; + public VisualizerScreenspaceParent visualizerScreenspaceParentMonoBehaviour_unserialized; + void OnEnable() + { + OnEnable_base(); + OnEnable_ofScreenspaceParent(); + } + + public void OnEnable_ofScreenspaceParent() + { + visualizerScreenspaceParentMonoBehaviour_unserialized = (VisualizerScreenspaceParent)target; + } + + public bool DrawCameraChooser(bool drawWarningBox_forDisabledCamComponents) + { + SerializedProperty sP_screenspaceDefiningCamera = serializedObject.FindProperty("screenspaceDefiningCamera"); + SerializedProperty sP_usedCameraIsAvailable = serializedObject.FindProperty("usedCameraIsAvailable"); + EditorGUILayout.PropertyField(sP_screenspaceDefiningCamera, new GUIContent("Camera for drawing", "The viewport space of this camera is used for drawing.")); + + switch (sP_screenspaceDefiningCamera.enumValueIndex) + { + case (int)VisualizerScreenspaceParent.ScreenspaceDefiningCameras.cameraAtThisGameobject: + if (sP_usedCameraIsAvailable.boolValue == false) + { + EditorGUILayout.HelpBox("Drawing is skipped: There is no camera component attached to this gameobject.", MessageType.Warning, true); + return false; + } + break; + case (int)VisualizerScreenspaceParent.ScreenspaceDefiningCameras.manuallyAssignedCamera: + SerializedProperty sP_manuallyAssignedCamera = serializedObject.FindProperty("manuallyAssignedCamera"); + EditorGUILayout.PropertyField(sP_manuallyAssignedCamera, new GUIContent("Manually assigned camera")); + if (sP_manuallyAssignedCamera.objectReferenceValue == null) + { + EditorGUILayout.HelpBox("Assign a camera to start drawing.", MessageType.Info, true); + return false; + } + break; + case (int)VisualizerScreenspaceParent.ScreenspaceDefiningCameras.automaticallySearchForMainGameViewCamera: + if (sP_usedCameraIsAvailable.boolValue == false) + { + EditorGUILayout.HelpBox("Drawing is skipped: No camera could be found.", MessageType.Warning, true); + return false; + } + break; + case (int)VisualizerScreenspaceParent.ScreenspaceDefiningCameras.sceneViewCamera: + if (sP_usedCameraIsAvailable.boolValue == false) + { + EditorGUILayout.HelpBox("Drawing is skipped: There is no Scene View Window available.", MessageType.Warning, true); + return false; + } + else + { + EditorGUI.indentLevel = EditorGUI.indentLevel + 1; + EditorGUILayout.PropertyField(serializedObject.FindProperty("alwaysChangeToCurrentlyActiveSceneView_insteadOfStayingAtTheSelectedOne"), new GUIContent("Always change to the currently active Scene View.", "Always change to the currently active Scene View:" + Environment.NewLine + Environment.NewLine + "This affects the situation when there is more then one Scene View window docked in the Editor." + Environment.NewLine + Environment.NewLine + "If it is disabled:" + Environment.NewLine + "The visualized camera will always remain the one of the same Scene View window, also if the focus changes between multiple Scene View windows." + Environment.NewLine + Environment.NewLine + "If it is enabled:" + Environment.NewLine + "The visualized camera will ongoingly switch to be the one of the Scene View window that has focus.")); + EditorGUI.indentLevel = EditorGUI.indentLevel - 1; + } + break; + default: + break; + } + + if (drawWarningBox_forDisabledCamComponents) + { + if (visualizerScreenspaceParentMonoBehaviour_unserialized.CheckIf_usedCameraIsActiveAndEnabled() == false) + { + EditorGUILayout.HelpBox("The drawing may be invisible, because the used camera component is inactive or disabled.", MessageType.Warning, true); + } + } + + return true; + } + + } +#endif +} diff --git a/Editor/DrawDebugLibrary/VisualizerScreenspaceParentInspector.cs.meta b/Editor/DrawDebugLibrary/VisualizerScreenspaceParentInspector.cs.meta new file mode 100644 index 0000000..5dfeef4 --- /dev/null +++ b/Editor/DrawDebugLibrary/VisualizerScreenspaceParentInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 659ec197b9a568846aad9c7a9692b8fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets.meta b/Editor/DrawDebugLibrary/code snippets.meta new file mode 100644 index 0000000..1afadb0 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 519c3eebaeba63646922f49219629a8a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawBasics.snippet b/Editor/DrawDebugLibrary/code snippets/drawBasics.snippet new file mode 100644 index 0000000..ba8b7b2 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawBasics.snippet @@ -0,0 +1,2890 @@ + + + +
+ drawLine + drawLine + Draw a Line in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Line + line + + + +
+ + +
+ drawRay + drawRay + Draw a Ray in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ray + ray + + + +
+ + +
+ drawLineFrom + drawLineFrom + Draw a LineFrom in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineFrom + lineFrom + + + +
+ + +
+ drawLineTo + drawLineTo + Draw a LineTo in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineTo + lineTo + + + +
+ + +
+ drawLineColFade + drawLineColFade + Draw a LineColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineColFade + lineColFade + + + +
+ + +
+ drawRayColFade + drawRayColFade + Draw a RayColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayColFade + rayColFade + + + +
+ + +
+ drawLineFromColFade + drawLineFromColFade + Draw a LineFromColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineFromColFade + lineFromColFade + + + +
+ + +
+ drawLineToColFade + drawLineToColFade + Draw a LineToColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineToColFade + lineToColFade + + + +
+ + +
+ drawLineCircled_vecToVec + drawLineCircled_vecToVec + Draw a LineCircled in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + lineCircled + + + +
+ + +
+ drawLineCircled_fromQuatUp + drawLineCircled_fromQuatUp + Draw a LineCircled in the Unity Editor. (quaternion-forward defines turnAxis, line starts at quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + lineCircled + + + +
+ + +
+ drawLineCircled_relToQuatUp + drawLineCircled_relToQuatUp + Draw a LineCircled in the Unity Editor. (quaternion-forward defines turnAxis, start and end angles measured relative to quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + lineCircled + + + +
+ + +
+ drawLineCircled_aroundRayAxis + drawLineCircled_aroundRayAxis + Draw a LineCircled in the Unity Editor. (via ray as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + lineCircled + + + +
+ + +
+ drawLineCircled_aroundVecAxis + drawLineCircled_aroundVecAxis + Draw a LineCircled in the Unity Editor. (via vector as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + lineCircled + + + +
+ + +
+ drawCircleSegment_vecToVec + drawCircleSegment_vecToVec + Draw a CircleSegment in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + circleSegment + + + +
+ + +
+ drawCircleSegment_fromQuatUp + drawCircleSegment_fromQuatUp + Draw a CircleSegment in the Unity Editor. (quaternion-forward defines turnAxis, segment starts at quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + circleSegment + + + +
+ + +
+ drawCircleSegment_relToQuatUp + drawCircleSegment_relToQuatUp + Draw a CircleSegment in the Unity Editor. (quaternion-forward defines turnAxis, start and end angles measured relative to quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + circleSegment + + + +
+ + +
+ drawCircleSegment_aroundRayAxis + drawCircleSegment_aroundRayAxis + Draw a CircleSegment in the Unity Editor. (via ray as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + circleSegment + + + +
+ + +
+ drawCircleSegment_aroundVecAxis + drawCircleSegment_aroundVecAxis + Draw a CircleSegment in the Unity Editor. (via vector as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + circleSegment + + + +
+ + +
+ drawLineString_array + drawLineString_array + Draw a LineString in the Unity Editor. (via points from array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineString + lineString + + + +
+ + +
+ drawLineString_list + drawLineString_list + Draw a LineString in the Unity Editor. (via points from list) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + bool closeGapBetweenLastAndFirstPoint_of_$name$ = false; + float width_of_$name$ = 0.0f; + string text_of_$name$ = null; + DrawBasics.LineStyle style_of_$name$ = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor_of_$name$ = 1.0f; + bool textBlockAboveLine_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics.LineString(points_of_$name$, color_of_$name$, closeGapBetweenLastAndFirstPoint_of_$name$, width_of_$name$, text_of_$name$, style_of_$name$, stylePatternScaleFactor_of_$name$, textBlockAboveLine_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn LineString + lineString + + + +
+ + +
+ drawLineStringColFade_array + drawLineStringColFade_array + Draw a LineStringColFade in the Unity Editor. (via points from array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineStringColFade + lineStringColFade + + + +
+ + +
+ drawLineStringColFade_list + drawLineStringColFade_list + Draw a LineStringColFade in the Unity Editor. (via points from list) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color startColor_of_$name$ = ; + Color endColor_of_$name$ = ; + bool closeGapBetweenLastAndFirstPoint_of_$name$ = false; + float width_of_$name$ = 0.0f; + string text_of_$name$ = null; + DrawBasics.LineStyle style_of_$name$ = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor_of_$name$ = 1.0f; + bool textBlockAboveLine_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics.LineStringColorFade(points_of_$name$, startColor_of_$name$, endColor_of_$name$, closeGapBetweenLastAndFirstPoint_of_$name$, width_of_$name$, text_of_$name$, style_of_$name$, stylePatternScaleFactor_of_$name$, textBlockAboveLine_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn LineStringColFade + lineStringColFade + + + +
+ + +
+ drawPointArray + drawPointArray + Draw a PointArray in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointArray + pointArray + + + +
+ + +
+ drawPointList + drawPointList + Draw a PointList in the Unity Editor. + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + float sizeOfMarkingCross_of_$name$ = 1.0f; + float markingCrossLinesWidth_of_$name$ = 0.0f; + bool drawCoordsAsText_of_$name$ = true; + bool hideZDir_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics.PointList(points_of_$name$, color_of_$name$, sizeOfMarkingCross_of_$name$, markingCrossLinesWidth_of_$name$, drawCoordsAsText_of_$name$, hideZDir_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn PointList + pointList + + + +
+ + +
+ drawPoint + drawPoint + Draw a Point in the Unity Editor. (pointMarking has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Point + point + + + +
+ + +
+ drawPoint_prioText + drawPoint_prioText + Draw a Point in the Unity Editor. (text parameter has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Point + point + + + +
+ + +
+ drawPointLocalArray_transformAsParent + drawPointLocalArray_transformAsParent + Draw a PointLocalArray in the Unity Editor. (local space is defined by transform as parent) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocalArray + pointLocalArray + + + +
+ + +
+ drawPointLocalList_transformAsParent + drawPointLocalList_transformAsParent + Draw a PointLocalList in the Unity Editor. (local space is defined by transform as parent) + Draw XXL +
+ + + localPoints_of_$name$ = $end$; + Transform parentTransform_of_$name$ = ; + Color color_of_$name$ = default(Color); + float sizeOfMarkingCross_global_of_$name$ = 1.0f; + float markingCrossLinesWidth_of_$name$ = 0.0f; + bool drawCoordsAsText_of_$name$ = true; + bool additionallyDrawGlobalCoords_of_$name$ = false; + bool drawLocalOrigin_of_$name$ = true; + bool hideZDir_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics.PointLocalList(localPoints_of_$name$, parentTransform_of_$name$, color_of_$name$, sizeOfMarkingCross_global_of_$name$, markingCrossLinesWidth_of_$name$, drawCoordsAsText_of_$name$, additionallyDrawGlobalCoords_of_$name$, drawLocalOrigin_of_$name$, hideZDir_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn PointLocalList + pointLocalList + + + +
+ + +
+ drawPointLocalArray_vecAsParent + drawPointLocalArray_vecAsParent + Draw a PointLocalArray in the Unity Editor. (local space is defined by vectors as parent) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocalArray + pointLocalArray + + + +
+ + +
+ drawPointLocalList_vecAsParent + drawPointLocalList_vecAsParent + Draw a PointLocalList in the Unity Editor. (local space is defined by vectors as parent) + Draw XXL +
+ + + localPoints_of_$name$ = $end$; + Vector3 parentPositionGlobal_of_$name$ = ; + Quaternion parentRotationGlobal_of_$name$ = ; + Vector3 parentScaleGlobal_of_$name$ = ; + Color color_of_$name$ = default(Color); + float sizeOfMarkingCross_global_of_$name$ = 1.0f; + float markingCrossLinesWidth_of_$name$ = 0.0f; + bool drawCoordsAsText_of_$name$ = true; + bool additionallyDrawGlobalCoords_of_$name$ = false; + bool drawLocalOrigin_of_$name$ = true; + bool hideZDir_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics.PointLocalList(localPoints_of_$name$, parentPositionGlobal_of_$name$, parentRotationGlobal_of_$name$, parentScaleGlobal_of_$name$, color_of_$name$, sizeOfMarkingCross_global_of_$name$, markingCrossLinesWidth_of_$name$, drawCoordsAsText_of_$name$, additionallyDrawGlobalCoords_of_$name$, drawLocalOrigin_of_$name$, hideZDir_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn PointLocalList + pointLocalList + + + +
+ + +
+ drawPointLocal_transformAsParent + drawPointLocal_transformAsParent + Draw a PointLocal in the Unity Editor. (local space is defined by transform as parent) (pointMarking has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocal + pointLocal + + + +
+ + +
+ drawPointLocal_transformAsParent_prioText + drawPointLocal_transformAsParent_prioText + Draw a PointLocal in the Unity Editor. (local space is defined by transform as parent) (text parameter has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocal + pointLocal + + + +
+ + +
+ drawPointLocal_vecAsParent + drawPointLocal_vecAsParent + Draw a PointLocal in the Unity Editor. (local space is defined by vectors as parent) (pointMarking has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocal + pointLocal + + + +
+ + +
+ drawPointLocal_vecAsParent_prioText + drawPointLocal_vecAsParent_prioText + Draw a PointLocal in the Unity Editor. (local space is defined by vectors as parent) (text parameter has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocal + pointLocal + + + +
+ + +
+ drawPointTag + drawPointTag + Draw a PointTag in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointTag + pointTag + + + +
+ + +
+ drawVector + drawVector + Draw a Vector in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Vector + vector + + + +
+ + +
+ drawVectorFrom + drawVectorFrom + Draw a VectorFrom in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorFrom + vectorFrom + + + +
+ + +
+ drawVectorTo + drawVectorTo + Draw a VectorTo in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorTo + vectorTo + + + +
+ + +
+ drawVectorCircled_vecToVec + drawVectorCircled_vecToVec + Draw a VectorCircled in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + vectorCircled + + + +
+ + +
+ drawVectorCircled_fromQuatUp + drawVectorCircled_fromQuatUp + Draw a VectorCircled in the Unity Editor. (quaternion-forward defines turnAxis, vector starts at quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + vectorCircled + + + +
+ + +
+ drawVectorCircled_relToQuatUp + drawVectorCircled_relToQuatUp + Draw a VectorCircled in the Unity Editor. (quaternion-forward defines turnAxis, start and end angles measured relative to quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + vectorCircled + + + +
+ + +
+ drawVectorCircled_aroundRayAxis + drawVectorCircled_aroundRayAxis + Draw a VectorCircled in the Unity Editor. (via Ray as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + vectorCircled + + + +
+ + +
+ drawVectorCircled_aroundVecAxis + drawVectorCircled_aroundVecAxis + Draw a VectorCircled in the Unity Editor. (via Vector as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + vectorCircled + + + +
+ + +
+ drawIcon_rotViaVec + drawIcon_rotViaVec + Draw an Icon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Icon + icon + + + +
+ + +
+ drawIcon_rotViaQuat + drawIcon_rotViaQuat + Draw an Icon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Icon + icon + + + +
+ + +
+ drawDot + drawDot + Draw a Dot in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Dot + dot + + + +
+ + +
+ drawMovingArrowsRay + drawMovingArrowsRay + Draw a MovingArrowsRay in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn MovingArrowsRay + movingArrowsRay + + + +
+ + +
+ drawMovingArrowsLine + drawMovingArrowsLine + Draw a MovingArrowsLine in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn MovingArrowsLine + movingArrowsLine + + + +
+ + +
+ drawRayWithAlternatingColors + drawRayWithAlternatingColors + Draw a RayWithAlternatingColors in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayWithAlternatingColors + rayWithAlternatingColors + + + +
+ + +
+ drawLineWithAlternatingColors + drawLineWithAlternatingColors + Draw a LineWithAlternatingColors in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineWithAlternatingColors + lineWithAlternatingColors + + + +
+ + +
+ drawBlinkingRay + drawBlinkingRay + Draw a BlinkingRay in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BlinkingRay + blinkingRay + + + +
+ + +
+ drawBlinkingLine + drawBlinkingLine + Draw a BlinkingLine in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BlinkingLine + blinkingLine + + + +
+ + +
+ drawRayUnderTension + drawRayUnderTension + Draw a RayUnderTension in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayUnderTension + rayUnderTension + + + +
+ + +
+ drawLineUnderTension + drawLineUnderTension + Draw a LineUnderTension in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineUnderTension + lineUnderTension + + + +
+ + +
+ drawBezierSegmentQuadratic_go_go + drawBezierSegmentQuadratic_go_go + Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 2 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + bezierSegmentQuadratic + + + +
+ + +
+ drawBezierSegmentQuadratic_tr_tr + drawBezierSegmentQuadratic_tr_tr + Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 2 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + bezierSegmentQuadratic + + + +
+ + +
+ drawBezierSegmentQuadratic_go_go_go + drawBezierSegmentQuadratic_go_go_go + Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 3 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + bezierSegmentQuadratic + + + +
+ + +
+ drawBezierSegmentQuadratic_tr_tr_tr + drawBezierSegmentQuadratic_tr_tr_tr + Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 3 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + bezierSegmentQuadratic + + + +
+ + +
+ drawBezierSegmentQuadratic_vec + drawBezierSegmentQuadratic_vec + Draw a BezierSegmentQuadratic in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + bezierSegmentQuadratic + + + +
+ + +
+ drawBezierSegmentCubic_go_go + drawBezierSegmentCubic_go_go + Draw a BezierSegmentCubic in the Unity Editor. (defined by 2 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + bezierSegmentCubic + + + +
+ + +
+ drawBezierSegmentCubic_tr_tr + drawBezierSegmentCubic_tr_tr + Draw a BezierSegmentCubic in the Unity Editor. (defined by 2 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + bezierSegmentCubic + + + +
+ + +
+ drawBezierSegmentCubic_go_go_go + drawBezierSegmentCubic_go_go_go + Draw a BezierSegmentCubic in the Unity Editor. (defined by 3 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + bezierSegmentCubic + + + +
+ + +
+ drawBezierSegmentCubic_tr_tr_tr + drawBezierSegmentCubic_tr_tr_tr + Draw a BezierSegmentCubic in the Unity Editor. (defined by 3 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + bezierSegmentCubic + + + +
+ + +
+ drawBezierSegmentCubic_vec + drawBezierSegmentCubic_vec + Draw a BezierSegmentCubic in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + bezierSegmentCubic + + + +
+ + +
+ drawBezierSpline_goArray + drawBezierSpline_goArray + Draw a BezierSpline in the Unity Editor. (control points from array of gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ + +
+ drawBezierSpline_goList + drawBezierSpline_goList + Draw a BezierSpline in the Unity Editor. (control points from list of gameobjects) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList_of_$name$ = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned; + string text_of_$name$ = null; + float width_of_$name$ = 0.0f; + bool closeGapFromEndToStart_of_$name$ = false; + int straightSubDivisionsPerSegment_of_$name$ = 50; + float textSize_of_$name$ = 0.1f; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics.BezierSpline(points_of_$name$, color_of_$name$, interpretationOfList_of_$name$, text_of_$name$, width_of_$name$, closeGapFromEndToStart_of_$name$, straightSubDivisionsPerSegment_of_$name$, textSize_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ + +
+ drawBezierSpline_trArray + drawBezierSpline_trArray + Draw a BezierSpline in the Unity Editor. (control points from array of transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ + +
+ drawBezierSpline_trList + drawBezierSpline_trList + Draw a BezierSpline in the Unity Editor. (control points from list of transforms) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList_of_$name$ = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned; + string text_of_$name$ = null; + float width_of_$name$ = 0.0f; + bool closeGapFromEndToStart_of_$name$ = false; + int straightSubDivisionsPerSegment_of_$name$ = 50; + float textSize_of_$name$ = 0.1f; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics.BezierSpline(points_of_$name$, color_of_$name$, interpretationOfList_of_$name$, text_of_$name$, width_of_$name$, closeGapFromEndToStart_of_$name$, straightSubDivisionsPerSegment_of_$name$, textSize_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ + +
+ drawBezierSpline_vecArray + drawBezierSpline_vecArray + Draw a BezierSpline in the Unity Editor. (control points from array of vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ + +
+ drawBezierSpline_vecList + drawBezierSpline_vecList + Draw a BezierSpline in the Unity Editor. (control points from list of vectors) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList_of_$name$ = DrawBasics.BezierPosInterpretation.start_control1_control2_endIsNextStart; + string text_of_$name$ = null; + float width_of_$name$ = 0.0f; + bool closeGapFromEndToStart_of_$name$ = false; + int straightSubDivisionsPerSegment_of_$name$ = 50; + float textSize_of_$name$ = 0.1f; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics.BezierSpline(points_of_$name$, color_of_$name$, interpretationOfList_of_$name$, text_of_$name$, width_of_$name$, closeGapFromEndToStart_of_$name$, straightSubDivisionsPerSegment_of_$name$, textSize_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawBasics.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawBasics.snippet.meta new file mode 100644 index 0000000..903398a --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawBasics.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a6372d521eb9ee34e93d5bc4660977e8 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawBasics2D.snippet b/Editor/DrawDebugLibrary/code snippets/drawBasics2D.snippet new file mode 100644 index 0000000..1f76d0e --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawBasics2D.snippet @@ -0,0 +1,2642 @@ + + + +
+ drawLine2D + drawLine2D + Draw a Line in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Line + line + + + +
+ + +
+ drawRay2D + drawRay2D + Draw a Ray in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ray + ray + + + +
+ + +
+ drawLineFrom2D + drawLineFrom2D + Draw a LineFrom in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineFrom + lineFrom + + + +
+ + +
+ drawLineTo2D + drawLineTo2D + Draw a LineTo in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineTo + lineTo + + + +
+ + +
+ drawLineColFade2D + drawLineColFade2D + Draw a LineColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineColFade + lineColFade + + + +
+ + +
+ drawRayColFade2D + drawRayColFade2D + Draw a RayColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayColFade + rayColFade + + + +
+ + +
+ drawLineFromColFade2D + drawLineFromColFade2D + Draw a LineFromColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineFromColFade + lineFromColFade + + + +
+ + +
+ drawLineToColFade2D + drawLineToColFade2D + Draw a LineToColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineToColFade + lineToColFade + + + +
+ + +
+ drawLineCircled2D_vecToVec + drawLineCircled2D_vecToVec + Draw a LineCircled in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + lineCircled + + + +
+ + +
+ drawLineCircled2D_angleFromStartPos + drawLineCircled2D_angleFromStartPos + Draw a LineCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + lineCircled + + + +
+ + +
+ drawLineCircled2D_angleToAngle + drawLineCircled2D_angleToAngle + Draw a LineCircled in the Unity Editor. (turnCenter defined as position, angles relative to up-vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + lineCircled + + + +
+ + +
+ drawCircleSegment2D_vecToVec + drawCircleSegment2D_vecToVec + Draw a CircleSegment in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + circleSegment + + + +
+ + +
+ drawCircleSegment2D_angleFromStartPos + drawCircleSegment2D_angleFromStartPos + Draw a CircleSegment in the Unity Editor. (turnCenter and startPositionOnPerimeter defined as positions, angle as float) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + circleSegment + + + +
+ + +
+ drawCircleSegment2D_angleToAngle + drawCircleSegment2D_angleToAngle + Draw a CircleSegment in the Unity Editor. (turnCenter defined as position, angles relative to up-vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + circleSegment + + + +
+ + +
+ drawLineString2D_array + drawLineString2D_array + Draw a LineString in the Unity Editor. (via points from array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineString + lineString + + + +
+ + +
+ drawLineString2D_list + drawLineString2D_list + Draw a LineString in the Unity Editor. (via points from list) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + bool closeGapBetweenLastAndFirstPoint_of_$name$ = false; + float width_of_$name$ = 0.0f; + string text_of_$name$ = null; + DrawBasics.LineStyle style_of_$name$ = DrawBasics.LineStyle.solid; + float custom_zPos_of_$name$ = float.PositiveInfinity; + float stylePatternScaleFactor_of_$name$ = 1.0f; + bool textBlockAboveLine_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics2D.LineString(points_of_$name$, color_of_$name$, closeGapBetweenLastAndFirstPoint_of_$name$, width_of_$name$, text_of_$name$, style_of_$name$, custom_zPos_of_$name$, stylePatternScaleFactor_of_$name$, textBlockAboveLine_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn LineString + lineString + + + +
+ + +
+ drawLineStringColFade2D_array + drawLineStringColFade2D_array + Draw a LineStringColFade in the Unity Editor. (via points from array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineStringColFade + lineStringColFade + + + +
+ + +
+ drawLineStringColFade2D_list + drawLineStringColFade2D_list + Draw a LineStringColFade in the Unity Editor. (via points from list) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color startColor_of_$name$ = ; + Color endColor_of_$name$ = ; + bool closeGapBetweenLastAndFirstPoint_of_$name$ = false; + float width_of_$name$ = 0.0f; + string text_of_$name$ = null; + DrawBasics.LineStyle style_of_$name$ = DrawBasics.LineStyle.solid; + float custom_zPos_of_$name$ = float.PositiveInfinity; + float stylePatternScaleFactor_of_$name$ = 1.0f; + bool textBlockAboveLine_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics2D.LineStringColorFade(points_of_$name$, startColor_of_$name$, endColor_of_$name$, closeGapBetweenLastAndFirstPoint_of_$name$, width_of_$name$, text_of_$name$, style_of_$name$, custom_zPos_of_$name$, stylePatternScaleFactor_of_$name$, textBlockAboveLine_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn LineStringColFade + lineStringColFade + + + +
+ + +
+ drawPointArray2D + drawPointArray2D + Draw a PointArray in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointArray + pointArray + + + +
+ + +
+ drawPointList2D + drawPointList2D + Draw a PointList in the Unity Editor. + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + float sizeOfMarkingCross_of_$name$ = 1.0f; + float markingCrossLinesWidth_of_$name$ = 0.0f; + bool drawCoordsAsText_of_$name$ = true; + float custom_zPos_of_$name$ = float.PositiveInfinity; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics2D.PointList(points_of_$name$, color_of_$name$, sizeOfMarkingCross_of_$name$, markingCrossLinesWidth_of_$name$, drawCoordsAsText_of_$name$, custom_zPos_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn PointList + pointList + + + +
+ + +
+ drawPoint2D + drawPoint2D + Draw a Point in the Unity Editor. (pointMarking has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Point + point + + + +
+ + +
+ drawPoint2D_prioText + drawPoint2D_prioText + Draw a Point in the Unity Editor. (text parameter has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Point + point + + + +
+ + +
+ drawPointTag2D + drawPointTag2D + Draw a PointTag in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointTag + pointTag + + + +
+ + +
+ drawVector2D + drawVector2D + Draw a Vector in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Vector + vector + + + +
+ + +
+ drawVectorFrom2D + drawVectorFrom2D + Draw a VectorFrom in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorFrom + vectorFrom + + + +
+ + +
+ drawVectorTo2D + drawVectorTo2D + Draw a VectorTo in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorTo + vectorTo + + + +
+ + +
+ drawVectorCircled2D_vecToVec + drawVectorCircled2D_vecToVec + Draw a VectorCircled in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + vectorCircled + + + +
+ + +
+ drawVectorCircled2D_angleFromStartPos + drawVectorCircled2D_angleFromStartPos + Draw a VectorCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + vectorCircled + + + +
+ + +
+ drawVectorCircled2D_angleToAngle + drawVectorCircled2D_angleToAngle + Draw a VectorCircled in the Unity Editor. (turnCenter defined as position, angles relative to up-vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + vectorCircled + + + +
+ + +
+ drawMovingArrowsRay2D + drawMovingArrowsRay2D + Draw a MovingArrowsRay in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn MovingArrowsRay + movingArrowsRay + + + +
+ + +
+ drawMovingArrowsLine2D + drawMovingArrowsLine2D + Draw a MovingArrowsLine in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn MovingArrowsLine + movingArrowsLine + + + +
+ + +
+ drawRayWithAlternatingColors2D + drawRayWithAlternatingColors2D + Draw a RayWithAlternatingColors in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayWithAlternatingColors + rayWithAlternatingColors + + + +
+ + +
+ drawLineWithAlternatingColors2D + drawLineWithAlternatingColors2D + Draw a LineWithAlternatingColors in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineWithAlternatingColors + lineWithAlternatingColors + + + +
+ + +
+ drawBlinkingRay2D + drawBlinkingRay2D + Draw a BlinkingRay in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BlinkingRay + blinkingRay + + + +
+ + +
+ drawBlinkingLine2D + drawBlinkingLine2D + Draw a BlinkingLine in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BlinkingLine + blinkingLine + + + +
+ + +
+ drawRayUnderTension2D + drawRayUnderTension2D + Draw a RayUnderTension in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayUnderTension + rayUnderTension + + + +
+ + +
+ drawLineUnderTension2D + drawLineUnderTension2D + Draw a LineUnderTension in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineUnderTension + lineUnderTension + + + +
+ + +
+ drawIcon2D + drawIcon2D + Draw an Icon in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Icon + icon + + + +
+ + +
+ drawShape2D_rect_defaultZ + drawShape2D_rect_defaultZ + Draw a Shape in the Unity Editor. (extent via rect struct) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Shape + shape + + + +
+ + +
+ drawShape2D_vec_defaultZ + drawShape2D_vec_defaultZ + Draw a Shape in the Unity Editor. (extent via vectors) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Shape + shape + + + +
+ + +
+ drawDot2D + drawDot2D + Draw a Dot in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Dot + dot + + + +
+ + +
+ drawBox2D_rect_defaultZ + drawBox2D_rect_defaultZ + Draw a Box in the Unity Editor. (defined via rect struct) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Box + box + + + +
+ + +
+ drawBox2D_vec_defaultZ + drawBox2D_vec_defaultZ + Draw a Box in the Unity Editor. (defined via vectors) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Box + box + + + +
+ + +
+ drawCircle2D_rect_defaultZ + drawCircle2D_rect_defaultZ + Draw a Circle in the Unity Editor. (defined via rect struct) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle + circle + + + +
+ + +
+ drawCircle2D_vecRad_defaultZ + drawCircle2D_vecRad_defaultZ + Draw a Circle in the Unity Editor. (defined via vector and float as radius) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle + circle + + + +
+ + +
+ drawCapsule2D_vecC1C2Pos_defaultZ + drawCapsule2D_vecC1C2Pos_defaultZ + Draw a Capsule in the Unity Editor. (defined via position of circle1 and circle2) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + capsule + + + +
+ + +
+ drawCapsule2D_rect_defaultZ + drawCapsule2D_rect_defaultZ + Draw a Capsule in the Unity Editor. (defined via rect struct) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + capsule + + + +
+ + +
+ drawCapsule2D_vecPosSize_defaultZ + drawCapsule2D_vecPosSize_defaultZ + Draw a Capsule in the Unity Editor. (defined via center position and size from vector) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + capsule + + + +
+ + +
+ drawBezierSegmentQuadratic2D_go_go + drawBezierSegmentQuadratic2D_go_go + Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 2 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + bezierSegmentQuadratic + + + +
+ + +
+ drawBezierSegmentQuadratic2D_tr_tr + drawBezierSegmentQuadratic2D_tr_tr + Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 2 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + bezierSegmentQuadratic + + + +
+ + +
+ drawBezierSegmentQuadratic2D_go_go_go + drawBezierSegmentQuadratic2D_go_go_go + Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 3 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + bezierSegmentQuadratic + + + +
+ + +
+ drawBezierSegmentQuadratic2D_tr_tr_tr + drawBezierSegmentQuadratic2D_tr_tr_tr + Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 3 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + bezierSegmentQuadratic + + + +
+ + +
+ drawBezierSegmentQuadratic2D_vec + drawBezierSegmentQuadratic2D_vec + Draw a BezierSegmentQuadratic in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + bezierSegmentQuadratic + + + +
+ + +
+ drawBezierSegmentCubic2D_go_go + drawBezierSegmentCubic2D_go_go + Draw a BezierSegmentCubic in the Unity Editor. (defined by 2 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + bezierSegmentCubic + + + +
+ + +
+ drawBezierSegmentCubic2D_tr_tr + drawBezierSegmentCubic2D_tr_tr + Draw a BezierSegmentCubic in the Unity Editor. (defined by 2 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + bezierSegmentCubic + + + +
+ + +
+ drawBezierSegmentCubic2D_go_go_go + drawBezierSegmentCubic2D_go_go_go + Draw a BezierSegmentCubic in the Unity Editor. (defined by 3 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + bezierSegmentCubic + + + +
+ + +
+ drawBezierSegmentCubic2D_tr_tr_tr + drawBezierSegmentCubic2D_tr_tr_tr + Draw a BezierSegmentCubic in the Unity Editor. (defined by 3 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + bezierSegmentCubic + + + +
+ + +
+ drawBezierSegmentCubic2D_vec + drawBezierSegmentCubic2D_vec + Draw a BezierSegmentCubic in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + bezierSegmentCubic + + + +
+ + +
+ drawBezierSpline2D_goArray + drawBezierSpline2D_goArray + Draw a BezierSpline in the Unity Editor. (control points from array of gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ + +
+ drawBezierSpline2D_goList + drawBezierSpline2D_goList + Draw a BezierSpline in the Unity Editor. (control points from list of gameobjects) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList_of_$name$ = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned; + string text_of_$name$ = null; + float width_of_$name$ = 0.0f; + bool closeGapFromEndToStart_of_$name$ = false; + int straightSubDivisionsPerSegment_of_$name$ = 50; + float custom_zPos_of_$name$ = float.PositiveInfinity; + float textSize_of_$name$ = 0.1f; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics2D.BezierSpline(points_of_$name$, color_of_$name$, interpretationOfList_of_$name$, text_of_$name$, width_of_$name$, closeGapFromEndToStart_of_$name$, straightSubDivisionsPerSegment_of_$name$, custom_zPos_of_$name$, textSize_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ + +
+ drawBezierSpline2D_trArray + drawBezierSpline2D_trArray + Draw a BezierSpline in the Unity Editor. (control points from array of transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ + +
+ drawBezierSpline2D_trList + drawBezierSpline2D_trList + Draw a BezierSpline in the Unity Editor. (control points from list of transforms) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList_of_$name$ = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned; + string text_of_$name$ = null; + float width_of_$name$ = 0.0f; + bool closeGapFromEndToStart_of_$name$ = false; + int straightSubDivisionsPerSegment_of_$name$ = 50; + float custom_zPos_of_$name$ = float.PositiveInfinity; + float textSize_of_$name$ = 0.1f; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics2D.BezierSpline(points_of_$name$, color_of_$name$, interpretationOfList_of_$name$, text_of_$name$, width_of_$name$, closeGapFromEndToStart_of_$name$, straightSubDivisionsPerSegment_of_$name$, custom_zPos_of_$name$, textSize_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ + +
+ drawBezierSpline2D_vecArray + drawBezierSpline2D_vecArray + Draw a BezierSpline in the Unity Editor. (control points from array of vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ + +
+ drawBezierSpline2D_vecList + drawBezierSpline2D_vecList + Draw a BezierSpline in the Unity Editor. (control points from list of vectors) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList_of_$name$ = DrawBasics.BezierPosInterpretation.start_control1_control2_endIsNextStart; + string text_of_$name$ = null; + float width_of_$name$ = 0.0f; + bool closeGapFromEndToStart_of_$name$ = false; + int straightSubDivisionsPerSegment_of_$name$ = 50; + float custom_zPos_of_$name$ = float.PositiveInfinity; + float textSize_of_$name$ = 0.1f; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawBasics2D.BezierSpline(points_of_$name$, color_of_$name$, interpretationOfList_of_$name$, text_of_$name$, width_of_$name$, closeGapFromEndToStart_of_$name$, straightSubDivisionsPerSegment_of_$name$, custom_zPos_of_$name$, textSize_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + bezierSpline + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawBasics2D.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawBasics2D.snippet.meta new file mode 100644 index 0000000..d52686e --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawBasics2D.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8cb1d067fc00471419f6d383bb689668 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawBasics2D_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawBasics2D_func.snippet new file mode 100644 index 0000000..d062a53 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawBasics2D_func.snippet @@ -0,0 +1,2834 @@ + + + +
+ drawLine2D_func + drawLine2D_func + Encapsulated in a function: Draw a Line in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Line + WithThisName + + + +
+ + +
+ drawRay2D_func + drawRay2D_func + Encapsulated in a function: Draw a Ray in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ray + WithThisName + + + +
+ + +
+ drawLineFrom2D_func + drawLineFrom2D_func + Encapsulated in a function: Draw a LineFrom in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineFrom + WithThisName + + + +
+ + +
+ drawLineTo2D_func + drawLineTo2D_func + Encapsulated in a function: Draw a LineTo in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineTo + WithThisName + + + +
+ + +
+ drawLineColFade2D_func + drawLineColFade2D_func + Encapsulated in a function: Draw a LineColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineColFade + WithThisName + + + +
+ + +
+ drawRayColFade2D_func + drawRayColFade2D_func + Encapsulated in a function: Draw a RayColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayColFade + WithThisName + + + +
+ + +
+ drawLineFromColFade2D_func + drawLineFromColFade2D_func + Encapsulated in a function: Draw a LineFromColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineFromColFade + WithThisName + + + +
+ + +
+ drawLineToColFade2D_func + drawLineToColFade2D_func + Encapsulated in a function: Draw a LineToColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineToColFade + WithThisName + + + +
+ + +
+ drawLineCircled2D_vecToVec_func + drawLineCircled2D_vecToVec_func + Encapsulated in a function: Draw a LineCircled in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + WithThisName + + + +
+ + +
+ drawLineCircled2D_angleFromStartPos_func + drawLineCircled2D_angleFromStartPos_func + Encapsulated in a function: Draw a LineCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + WithThisName + + + +
+ + +
+ drawLineCircled2D_angleToAngle_func + drawLineCircled2D_angleToAngle_func + Encapsulated in a function: Draw a LineCircled in the Unity Editor. (turnCenter defined as position, angles relative to up-vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + WithThisName + + + +
+ + +
+ drawCircleSegment2D_vecToVec_func + drawCircleSegment2D_vecToVec_func + Encapsulated in a function: Draw a CircleSegment in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + WithThisName + + + +
+ + +
+ drawCircleSegment2D_angleFromStartPos_func + drawCircleSegment2D_angleFromStartPos_func + Encapsulated in a function: Draw a CircleSegment in the Unity Editor. (turnCenter and startPositionOnPerimeter defined as positions, angle as float) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + WithThisName + + + +
+ + +
+ drawCircleSegment2D_angleToAngle_func + drawCircleSegment2D_angleToAngle_func + Encapsulated in a function: Draw a CircleSegment in the Unity Editor. (turnCenter defined as position, angles relative to up-vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + WithThisName + + + +
+ + +
+ drawLineString2D_array_func + drawLineString2D_array_func + Encapsulated in a function: Draw a LineString in the Unity Editor. (via points from array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineString + WithThisName + + + +
+ + +
+ drawLineString2D_list_func + drawLineString2D_list_func + Encapsulated in a function: Draw a LineString in the Unity Editor. (via points from list) + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + bool closeGapBetweenLastAndFirstPoint = false; + float width = 0.0f; + string text = null; + DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + float custom_zPos = float.PositiveInfinity; + float stylePatternScaleFactor = 1.0f; + bool textBlockAboveLine = false; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics2D.LineString(points, color, closeGapBetweenLastAndFirstPoint, width, text, style, custom_zPos, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn LineString + WithThisName + + + +
+ + +
+ drawLineStringColFade2D_array_func + drawLineStringColFade2D_array_func + Encapsulated in a function: Draw a LineStringColFade in the Unity Editor. (via points from array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineStringColFade + WithThisName + + + +
+ + +
+ drawLineStringColFade2D_list_func + drawLineStringColFade2D_list_func + Encapsulated in a function: Draw a LineStringColFade in the Unity Editor. (via points from list) + Draw XXL +
+ + + points = $end$; + Color startColor = ; + Color endColor = ; + bool closeGapBetweenLastAndFirstPoint = false; + float width = 0.0f; + string text = null; + DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + float custom_zPos = float.PositiveInfinity; + float stylePatternScaleFactor = 1.0f; + bool textBlockAboveLine = false; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics2D.LineStringColorFade(points, startColor, endColor, closeGapBetweenLastAndFirstPoint, width, text, style, custom_zPos, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn LineStringColFade + WithThisName + + + +
+ + +
+ drawPointArray2D_func + drawPointArray2D_func + Encapsulated in a function: Draw a PointArray in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointArray + WithThisName + + + +
+ + +
+ drawPointList2D_func + drawPointList2D_func + Encapsulated in a function: Draw a PointList in the Unity Editor. + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + float sizeOfMarkingCross = 1.0f; + float markingCrossLinesWidth = 0.0f; + bool drawCoordsAsText = true; + float custom_zPos = float.PositiveInfinity; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics2D.PointList(points, color, sizeOfMarkingCross, markingCrossLinesWidth, drawCoordsAsText, custom_zPos, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn PointList + WithThisName + + + +
+ + +
+ drawPoint2D_func + drawPoint2D_func + Encapsulated in a function: Draw a Point in the Unity Editor. (pointMarking has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Point + WithThisName + + + +
+ + +
+ drawPoint2D_prioText_func + drawPoint2D_prioText_func + Encapsulated in a function: Draw a Point in the Unity Editor. (text parameter has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Point + WithThisName + + + +
+ + +
+ drawPointTag2D_func + drawPointTag2D_func + Encapsulated in a function: Draw a PointTag in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointTag + WithThisName + + + +
+ + +
+ drawVector2D_func + drawVector2D_func + Encapsulated in a function: Draw a Vector in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Vector + WithThisName + + + +
+ + +
+ drawVectorFrom2D_func + drawVectorFrom2D_func + Encapsulated in a function: Draw a VectorFrom in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorFrom + WithThisName + + + +
+ + +
+ drawVectorTo2D_func + drawVectorTo2D_func + Encapsulated in a function: Draw a VectorTo in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorTo + WithThisName + + + +
+ + +
+ drawVectorCircled2D_vecToVec_func + drawVectorCircled2D_vecToVec_func + Encapsulated in a function: Draw a VectorCircled in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + WithThisName + + + +
+ + +
+ drawVectorCircled2D_angleFromStartPos_func + drawVectorCircled2D_angleFromStartPos_func + Encapsulated in a function: Draw a VectorCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + WithThisName + + + +
+ + +
+ drawVectorCircled2D_angleToAngle_func + drawVectorCircled2D_angleToAngle_func + Encapsulated in a function: Draw a VectorCircled in the Unity Editor. (turnCenter defined as position, angles relative to up-vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + WithThisName + + + +
+ + +
+ drawMovingArrowsRay2D_func + drawMovingArrowsRay2D_func + Encapsulated in a function: Draw a MovingArrowsRay in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn MovingArrowsRay + WithThisName + + + +
+ + +
+ drawMovingArrowsLine2D_func + drawMovingArrowsLine2D_func + Encapsulated in a function: Draw a MovingArrowsLine in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn MovingArrowsLine + WithThisName + + + +
+ + +
+ drawRayWithAlternatingColors2D_func + drawRayWithAlternatingColors2D_func + Encapsulated in a function: Draw a RayWithAlternatingColors in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayWithAlternatingColors + WithThisName + + + +
+ + +
+ drawLineWithAlternatingColors2D_func + drawLineWithAlternatingColors2D_func + Encapsulated in a function: Draw a LineWithAlternatingColors in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineWithAlternatingColors + WithThisName + + + +
+ + +
+ drawBlinkingRay2D_func + drawBlinkingRay2D_func + Encapsulated in a function: Draw a BlinkingRay in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BlinkingRay + WithThisName + + + +
+ + +
+ drawBlinkingLine2D_func + drawBlinkingLine2D_func + Encapsulated in a function: Draw a BlinkingLine in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BlinkingLine + WithThisName + + + +
+ + +
+ drawRayUnderTension2D_func + drawRayUnderTension2D_func + Encapsulated in a function: Draw a RayUnderTension in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayUnderTension + WithThisName + + + +
+ + +
+ drawLineUnderTension2D_func + drawLineUnderTension2D_func + Encapsulated in a function: Draw a LineUnderTension in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineUnderTension + WithThisName + + + +
+ + +
+ drawIcon2D_func + drawIcon2D_func + Encapsulated in a function: Draw an Icon in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Icon + WithThisName + + + +
+ + +
+ drawShape2D_rect_defaultZ_func + drawShape2D_rect_defaultZ_func + Encapsulated in a function: Draw a Shape in the Unity Editor. (extent via rect struct) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Shape + WithThisName + + + +
+ + +
+ drawShape2D_vec_defaultZ_func + drawShape2D_vec_defaultZ_func + Encapsulated in a function: Draw a Shape in the Unity Editor. (extent via vectors) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Shape + WithThisName + + + +
+ + +
+ drawDot2D_func + drawDot2D_func + Encapsulated in a function: Draw a Dot in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Dot + WithThisName + + + +
+ + +
+ drawBox2D_rect_defaultZ_func + drawBox2D_rect_defaultZ_func + Encapsulated in a function: Draw a Box in the Unity Editor. (defined via rect struct) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Box + WithThisName + + + +
+ + +
+ drawBox2D_vec_defaultZ_func + drawBox2D_vec_defaultZ_func + Encapsulated in a function: Draw a Box in the Unity Editor. (defined via vectors) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Box + WithThisName + + + +
+ + +
+ drawCircle2D_rect_defaultZ_func + drawCircle2D_rect_defaultZ_func + Encapsulated in a function: Draw a Circle in the Unity Editor. (defined via rect struct) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle + WithThisName + + + +
+ + +
+ drawCircle2D_vecRad_defaultZ_func + drawCircle2D_vecRad_defaultZ_func + Encapsulated in a function: Draw a Circle in the Unity Editor. (defined via vector and float as radius) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle + WithThisName + + + +
+ + +
+ drawCapsule2D_vecC1C2Pos_defaultZ_func + drawCapsule2D_vecC1C2Pos_defaultZ_func + Encapsulated in a function: Draw a Capsule in the Unity Editor. (defined via position of circle1 and circle2) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + WithThisName + + + +
+ + +
+ drawCapsule2D_rect_defaultZ_func + drawCapsule2D_rect_defaultZ_func + Encapsulated in a function: Draw a Capsule in the Unity Editor. (defined via rect struct) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + WithThisName + + + +
+ + +
+ drawCapsule2D_vecPosSize_defaultZ_func + drawCapsule2D_vecPosSize_defaultZ_func + Encapsulated in a function: Draw a Capsule in the Unity Editor. (defined via center position and size from vector) (z pos from DrawBasics2D.Default_zPos_forDrawing) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + WithThisName + + + +
+ + +
+ drawBezierSegmentQuadratic2D_go_go_func + drawBezierSegmentQuadratic2D_go_go_func + Encapsulated in a function: Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 2 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + WithThisName + + + +
+ + +
+ drawBezierSegmentQuadratic2D_tr_tr_func + drawBezierSegmentQuadratic2D_tr_tr_func + Encapsulated in a function: Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 2 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + WithThisName + + + +
+ + +
+ drawBezierSegmentQuadratic2D_go_go_go_func + drawBezierSegmentQuadratic2D_go_go_go_func + Encapsulated in a function: Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 3 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + WithThisName + + + +
+ + +
+ drawBezierSegmentQuadratic2D_tr_tr_tr_func + drawBezierSegmentQuadratic2D_tr_tr_tr_func + Encapsulated in a function: Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 3 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + WithThisName + + + +
+ + +
+ drawBezierSegmentQuadratic2D_vec_func + drawBezierSegmentQuadratic2D_vec_func + Encapsulated in a function: Draw a BezierSegmentQuadratic in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + WithThisName + + + +
+ + +
+ drawBezierSegmentCubic2D_go_go_func + drawBezierSegmentCubic2D_go_go_func + Encapsulated in a function: Draw a BezierSegmentCubic in the Unity Editor. (defined by 2 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + WithThisName + + + +
+ + +
+ drawBezierSegmentCubic2D_tr_tr_func + drawBezierSegmentCubic2D_tr_tr_func + Encapsulated in a function: Draw a BezierSegmentCubic in the Unity Editor. (defined by 2 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + WithThisName + + + +
+ + +
+ drawBezierSegmentCubic2D_go_go_go_func + drawBezierSegmentCubic2D_go_go_go_func + Encapsulated in a function: Draw a BezierSegmentCubic in the Unity Editor. (defined by 3 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + WithThisName + + + +
+ + +
+ drawBezierSegmentCubic2D_tr_tr_tr_func + drawBezierSegmentCubic2D_tr_tr_tr_func + Encapsulated in a function: Draw a BezierSegmentCubic in the Unity Editor. (defined by 3 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + WithThisName + + + +
+ + +
+ drawBezierSegmentCubic2D_vec_func + drawBezierSegmentCubic2D_vec_func + Encapsulated in a function: Draw a BezierSegmentCubic in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + WithThisName + + + +
+ + +
+ drawBezierSpline2D_goArray_func + drawBezierSpline2D_goArray_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from array of gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ + +
+ drawBezierSpline2D_goList_func + drawBezierSpline2D_goList_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from list of gameobjects) + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned; + string text = null; + float width = 0.0f; + bool closeGapFromEndToStart = false; + int straightSubDivisionsPerSegment = 50; + float custom_zPos = float.PositiveInfinity; + float textSize = 0.1f; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics2D.BezierSpline(points, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, custom_zPos, textSize, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ + +
+ drawBezierSpline2D_trArray_func + drawBezierSpline2D_trArray_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from array of transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ + +
+ drawBezierSpline2D_trList_func + drawBezierSpline2D_trList_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from list of transforms) + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned; + string text = null; + float width = 0.0f; + bool closeGapFromEndToStart = false; + int straightSubDivisionsPerSegment = 50; + float custom_zPos = float.PositiveInfinity; + float textSize = 0.1f; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics2D.BezierSpline(points, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, custom_zPos, textSize, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ + +
+ drawBezierSpline2D_vecArray_func + drawBezierSpline2D_vecArray_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from array of vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ + +
+ drawBezierSpline2D_vecList_func + drawBezierSpline2D_vecList_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from list of vectors) + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList = DrawBasics.BezierPosInterpretation.start_control1_control2_endIsNextStart; + string text = null; + float width = 0.0f; + bool closeGapFromEndToStart = false; + int straightSubDivisionsPerSegment = 50; + float custom_zPos = float.PositiveInfinity; + float textSize = 0.1f; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics2D.BezierSpline(points, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, custom_zPos, textSize, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawBasics2D_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawBasics2D_func.snippet.meta new file mode 100644 index 0000000..f54f79f --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawBasics2D_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1a9b78b35e605f04fbc3af2d9d34f401 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawBasics_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawBasics_func.snippet new file mode 100644 index 0000000..8720fde --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawBasics_func.snippet @@ -0,0 +1,3100 @@ + + + +
+ drawLine_func + drawLine_func + Encapsulated in a function: Draw a Line in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Line + WithThisName + + + +
+ + +
+ drawRay_func + drawRay_func + Encapsulated in a function: Draw a Ray in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ray + WithThisName + + + +
+ + +
+ drawLineFrom_func + drawLineFrom_func + Encapsulated in a function: Draw a LineFrom in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineFrom + WithThisName + + + +
+ + +
+ drawLineTo_func + drawLineTo_func + Encapsulated in a function: Draw a LineTo in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineTo + WithThisName + + + +
+ + +
+ drawLineColFade_func + drawLineColFade_func + Encapsulated in a function: Draw a LineColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineColFade + WithThisName + + + +
+ + +
+ drawRayColFade_func + drawRayColFade_func + Encapsulated in a function: Draw a RayColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayColFade + WithThisName + + + +
+ + +
+ drawLineFromColFade_func + drawLineFromColFade_func + Encapsulated in a function: Draw a LineFromColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineFromColFade + WithThisName + + + +
+ + +
+ drawLineToColFade_func + drawLineToColFade_func + Encapsulated in a function: Draw a LineToColFade in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineToColFade + WithThisName + + + +
+ + +
+ drawLineCircled_vecToVec_func + drawLineCircled_vecToVec_func + Encapsulated in a function: Draw a LineCircled in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + WithThisName + + + +
+ + +
+ drawLineCircled_fromQuatUp_func + drawLineCircled_fromQuatUp_func + Encapsulated in a function: Draw a LineCircled in the Unity Editor. (quaternion-forward defines turnAxis, line starts at quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + WithThisName + + + +
+ + +
+ drawLineCircled_relToQuatUp_func + drawLineCircled_relToQuatUp_func + Encapsulated in a function: Draw a LineCircled in the Unity Editor. (quaternion-forward defines turnAxis, start and end angles measured relative to quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + WithThisName + + + +
+ + +
+ drawLineCircled_aroundRayAxis_func + drawLineCircled_aroundRayAxis_func + Encapsulated in a function: Draw a LineCircled in the Unity Editor. (via ray as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + WithThisName + + + +
+ + +
+ drawLineCircled_aroundVecAxis_func + drawLineCircled_aroundVecAxis_func + Encapsulated in a function: Draw a LineCircled in the Unity Editor. (via vector as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineCircled + WithThisName + + + +
+ + +
+ drawCircleSegment_vecToVec_func + drawCircleSegment_vecToVec_func + Encapsulated in a function: Draw a CircleSegment in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + WithThisName + + + +
+ + +
+ drawCircleSegment_fromQuatUp_func + drawCircleSegment_fromQuatUp_func + Encapsulated in a function: Draw a CircleSegment in the Unity Editor. (quaternion-forward defines turnAxis, segment starts at quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + WithThisName + + + +
+ + +
+ drawCircleSegment_relToQuatUp_func + drawCircleSegment_relToQuatUp_func + Encapsulated in a function: Draw a CircleSegment in the Unity Editor. (quaternion-forward defines turnAxis, start and end angles measured relative to quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + WithThisName + + + +
+ + +
+ drawCircleSegment_aroundRayAxis_func + drawCircleSegment_aroundRayAxis_func + Encapsulated in a function: Draw a CircleSegment in the Unity Editor. (via ray as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + WithThisName + + + +
+ + +
+ drawCircleSegment_aroundVecAxis_func + drawCircleSegment_aroundVecAxis_func + Encapsulated in a function: Draw a CircleSegment in the Unity Editor. (via vector as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleSegment + WithThisName + + + +
+ + +
+ drawLineString_array_func + drawLineString_array_func + Encapsulated in a function: Draw a LineString in the Unity Editor. (via points from array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineString + WithThisName + + + +
+ + +
+ drawLineString_list_func + drawLineString_list_func + Encapsulated in a function: Draw a LineString in the Unity Editor. (via points from list) + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + bool closeGapBetweenLastAndFirstPoint = false; + float width = 0.0f; + string text = null; + DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor = 1.0f; + bool textBlockAboveLine = false; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics.LineString(points, color, closeGapBetweenLastAndFirstPoint, width, text, style, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn LineString + WithThisName + + + +
+ + +
+ drawLineStringColFade_array_func + drawLineStringColFade_array_func + Encapsulated in a function: Draw a LineStringColFade in the Unity Editor. (via points from array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineStringColFade + WithThisName + + + +
+ + +
+ drawLineStringColFade_list_func + drawLineStringColFade_list_func + Encapsulated in a function: Draw a LineStringColFade in the Unity Editor. (via points from list) + Draw XXL +
+ + + points = $end$; + Color startColor = ; + Color endColor = ; + bool closeGapBetweenLastAndFirstPoint = false; + float width = 0.0f; + string text = null; + DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor = 1.0f; + bool textBlockAboveLine = false; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics.LineStringColorFade(points, startColor, endColor, closeGapBetweenLastAndFirstPoint, width, text, style, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn LineStringColFade + WithThisName + + + +
+ + +
+ drawPointArray_func + drawPointArray_func + Encapsulated in a function: Draw a PointArray in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointArray + WithThisName + + + +
+ + +
+ drawPointList_func + drawPointList_func + Encapsulated in a function: Draw a PointList in the Unity Editor. + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + float sizeOfMarkingCross = 1.0f; + float markingCrossLinesWidth = 0.0f; + bool drawCoordsAsText = true; + bool hideZDir = false; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics.PointList(points, color, sizeOfMarkingCross, markingCrossLinesWidth, drawCoordsAsText, hideZDir, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn PointList + WithThisName + + + +
+ + +
+ drawPoint_func + drawPoint_func + Encapsulated in a function: Draw a Point in the Unity Editor. (pointMarking has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Point + WithThisName + + + +
+ + +
+ drawPoint_prioText_func + drawPoint_prioText_func + Encapsulated in a function: Draw a Point in the Unity Editor. (text parameter has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Point + WithThisName + + + +
+ + +
+ drawPointLocalArray_transformAsParent_func + drawPointLocalArray_transformAsParent_func + Encapsulated in a function: Draw a PointLocalArray in the Unity Editor. (local space is defined by transform as parent) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocalArray + WithThisName + + + +
+ + +
+ drawPointLocalList_transformAsParent_func + drawPointLocalList_transformAsParent_func + Encapsulated in a function: Draw a PointLocalList in the Unity Editor. (local space is defined by transform as parent) + Draw XXL +
+ + + localPoints = $end$; + Transform parentTransform = ; + Color color = default(Color); + float sizeOfMarkingCross_global = 1.0f; + float markingCrossLinesWidth = 0.0f; + bool drawCoordsAsText = true; + bool additionallyDrawGlobalCoords = false; + bool drawLocalOrigin = true; + bool hideZDir = false; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics.PointLocalList(localPoints, parentTransform, color, sizeOfMarkingCross_global, markingCrossLinesWidth, drawCoordsAsText, additionallyDrawGlobalCoords, drawLocalOrigin, hideZDir, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn PointLocalList + WithThisName + + + +
+ + +
+ drawPointLocalArray_vecAsParent_func + drawPointLocalArray_vecAsParent_func + Encapsulated in a function: Draw a PointLocalArray in the Unity Editor. (local space is defined by vectors as parent) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocalArray + WithThisName + + + +
+ + +
+ drawPointLocalList_vecAsParent_func + drawPointLocalList_vecAsParent_func + Encapsulated in a function: Draw a PointLocalList in the Unity Editor. (local space is defined by vectors as parent) + Draw XXL +
+ + + localPoints = $end$; + Vector3 parentPositionGlobal = ; + Quaternion parentRotationGlobal = ; + Vector3 parentScaleGlobal = ; + Color color = default(Color); + float sizeOfMarkingCross_global = 1.0f; + float markingCrossLinesWidth = 0.0f; + bool drawCoordsAsText = true; + bool additionallyDrawGlobalCoords = false; + bool drawLocalOrigin = true; + bool hideZDir = false; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics.PointLocalList(localPoints, parentPositionGlobal, parentRotationGlobal, parentScaleGlobal, color, sizeOfMarkingCross_global, markingCrossLinesWidth, drawCoordsAsText, additionallyDrawGlobalCoords, drawLocalOrigin, hideZDir, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn PointLocalList + WithThisName + + + +
+ + +
+ drawPointLocal_transformAsParent_func + drawPointLocal_transformAsParent_func + Encapsulated in a function: Draw a PointLocal in the Unity Editor. (local space is defined by transform as parent) (pointMarking has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocal + WithThisName + + + +
+ + +
+ drawPointLocal_transformAsParent_prioText_func + drawPointLocal_transformAsParent_prioText_func + Encapsulated in a function: Draw a PointLocal in the Unity Editor. (local space is defined by transform as parent) (text parameter has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocal + WithThisName + + + +
+ + +
+ drawPointLocal_vecAsParent_func + drawPointLocal_vecAsParent_func + Encapsulated in a function: Draw a PointLocal in the Unity Editor. (local space is defined by vectors as parent) (pointMarking has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocal + WithThisName + + + +
+ + +
+ drawPointLocal_vecAsParent_prioText_func + drawPointLocal_vecAsParent_prioText_func + Encapsulated in a function: Draw a PointLocal in the Unity Editor. (local space is defined by vectors as parent) (text parameter has raised priority) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointLocal + WithThisName + + + +
+ + +
+ drawPointTag_func + drawPointTag_func + Encapsulated in a function: Draw a PointTag in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PointTag + WithThisName + + + +
+ + +
+ drawVector_func + drawVector_func + Encapsulated in a function: Draw a Vector in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Vector + WithThisName + + + +
+ + +
+ drawVectorFrom_func + drawVectorFrom_func + Encapsulated in a function: Draw a VectorFrom in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorFrom + WithThisName + + + +
+ + +
+ drawVectorTo_func + drawVectorTo_func + Encapsulated in a function: Draw a VectorTo in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorTo + WithThisName + + + +
+ + +
+ drawVectorCircled_vecToVec_func + drawVectorCircled_vecToVec_func + Encapsulated in a function: Draw a VectorCircled in the Unity Editor. (via toStartVector and toEndVector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + WithThisName + + + +
+ + +
+ drawVectorCircled_fromQuatUp_func + drawVectorCircled_fromQuatUp_func + Encapsulated in a function: Draw a VectorCircled in the Unity Editor. (quaternion-forward defines turnAxis, vector starts at quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + WithThisName + + + +
+ + +
+ drawVectorCircled_relToQuatUp_func + drawVectorCircled_relToQuatUp_func + Encapsulated in a function: Draw a VectorCircled in the Unity Editor. (quaternion-forward defines turnAxis, start and end angles measured relative to quaternion-up) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + WithThisName + + + +
+ + +
+ drawVectorCircled_aroundRayAxis_func + drawVectorCircled_aroundRayAxis_func + Encapsulated in a function: Draw a VectorCircled in the Unity Editor. (via Ray as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + WithThisName + + + +
+ + +
+ drawVectorCircled_aroundVecAxis_func + drawVectorCircled_aroundVecAxis_func + Encapsulated in a function: Draw a VectorCircled in the Unity Editor. (via Vector as turnAxis) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorCircled + WithThisName + + + +
+ + +
+ drawIcon_rotViaVec_func + drawIcon_rotViaVec_func + Encapsulated in a function: Draw an Icon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Icon + WithThisName + + + +
+ + +
+ drawIcon_rotViaQuat_func + drawIcon_rotViaQuat_func + Encapsulated in a function: Draw an Icon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Icon + WithThisName + + + +
+ + +
+ drawDot_func + drawDot_func + Encapsulated in a function: Draw a Dot in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Dot + WithThisName + + + +
+ + +
+ drawMovingArrowsRay_func + drawMovingArrowsRay_func + Encapsulated in a function: Draw a MovingArrowsRay in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn MovingArrowsRay + WithThisName + + + +
+ + +
+ drawMovingArrowsLine_func + drawMovingArrowsLine_func + Encapsulated in a function: Draw a MovingArrowsLine in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn MovingArrowsLine + WithThisName + + + +
+ + +
+ drawRayWithAlternatingColors_func + drawRayWithAlternatingColors_func + Encapsulated in a function: Draw a RayWithAlternatingColors in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayWithAlternatingColors + WithThisName + + + +
+ + +
+ drawLineWithAlternatingColors_func + drawLineWithAlternatingColors_func + Encapsulated in a function: Draw a LineWithAlternatingColors in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineWithAlternatingColors + WithThisName + + + +
+ + +
+ drawBlinkingRay_func + drawBlinkingRay_func + Encapsulated in a function: Draw a BlinkingRay in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BlinkingRay + WithThisName + + + +
+ + +
+ drawBlinkingLine_func + drawBlinkingLine_func + Encapsulated in a function: Draw a BlinkingLine in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BlinkingLine + WithThisName + + + +
+ + +
+ drawRayUnderTension_func + drawRayUnderTension_func + Encapsulated in a function: Draw a RayUnderTension in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayUnderTension + WithThisName + + + +
+ + +
+ drawLineUnderTension_func + drawLineUnderTension_func + Encapsulated in a function: Draw a LineUnderTension in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LineUnderTension + WithThisName + + + +
+ + +
+ drawBezierSegmentQuadratic_go_go_func + drawBezierSegmentQuadratic_go_go_func + Encapsulated in a function: Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 2 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + WithThisName + + + +
+ + +
+ drawBezierSegmentQuadratic_tr_tr_func + drawBezierSegmentQuadratic_tr_tr_func + Encapsulated in a function: Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 2 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + WithThisName + + + +
+ + +
+ drawBezierSegmentQuadratic_go_go_go_func + drawBezierSegmentQuadratic_go_go_go_func + Encapsulated in a function: Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 3 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + WithThisName + + + +
+ + +
+ drawBezierSegmentQuadratic_tr_tr_tr_func + drawBezierSegmentQuadratic_tr_tr_tr_func + Encapsulated in a function: Draw a BezierSegmentQuadratic in the Unity Editor. (defined by 3 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + WithThisName + + + +
+ + +
+ drawBezierSegmentQuadratic_vec_func + drawBezierSegmentQuadratic_vec_func + Encapsulated in a function: Draw a BezierSegmentQuadratic in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentQuadratic + WithThisName + + + +
+ + +
+ drawBezierSegmentCubic_go_go_func + drawBezierSegmentCubic_go_go_func + Encapsulated in a function: Draw a BezierSegmentCubic in the Unity Editor. (defined by 2 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + WithThisName + + + +
+ + +
+ drawBezierSegmentCubic_tr_tr_func + drawBezierSegmentCubic_tr_tr_func + Encapsulated in a function: Draw a BezierSegmentCubic in the Unity Editor. (defined by 2 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + WithThisName + + + +
+ + +
+ drawBezierSegmentCubic_go_go_go_func + drawBezierSegmentCubic_go_go_go_func + Encapsulated in a function: Draw a BezierSegmentCubic in the Unity Editor. (defined by 3 gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + WithThisName + + + +
+ + +
+ drawBezierSegmentCubic_tr_tr_tr_func + drawBezierSegmentCubic_tr_tr_tr_func + Encapsulated in a function: Draw a BezierSegmentCubic in the Unity Editor. (defined by 3 transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + WithThisName + + + +
+ + +
+ drawBezierSegmentCubic_vec_func + drawBezierSegmentCubic_vec_func + Encapsulated in a function: Draw a BezierSegmentCubic in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSegmentCubic + WithThisName + + + +
+ + +
+ drawBezierSpline_goArray_func + drawBezierSpline_goArray_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from array of gameobjects) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ + +
+ drawBezierSpline_goList_func + drawBezierSpline_goList_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from list of gameobjects) + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned; + string text = null; + float width = 0.0f; + bool closeGapFromEndToStart = false; + int straightSubDivisionsPerSegment = 50; + float textSize = 0.1f; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics.BezierSpline(points, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ + +
+ drawBezierSpline_trArray_func + drawBezierSpline_trArray_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from array of transforms) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ + +
+ drawBezierSpline_trList_func + drawBezierSpline_trList_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from list of transforms) + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned; + string text = null; + float width = 0.0f; + bool closeGapFromEndToStart = false; + int straightSubDivisionsPerSegment = 50; + float textSize = 0.1f; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics.BezierSpline(points, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ + +
+ drawBezierSpline_vecArray_func + drawBezierSpline_vecArray_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from array of vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ + +
+ drawBezierSpline_vecList_func + drawBezierSpline_vecList_func + Encapsulated in a function: Draw a BezierSpline in the Unity Editor. (control points from list of vectors) + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + DrawBasics.BezierPosInterpretation interpretationOfList = DrawBasics.BezierPosInterpretation.start_control1_control2_endIsNextStart; + string text = null; + float width = 0.0f; + bool closeGapFromEndToStart = false; + int straightSubDivisionsPerSegment = 50; + float textSize = 0.1f; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawBasics.BezierSpline(points, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn BezierSpline + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawBasics_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawBasics_func.snippet.meta new file mode 100644 index 0000000..93731f9 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawBasics_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 52e17f1fc31243c44b5e129039562168 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawEngineBasics.snippet b/Editor/DrawDebugLibrary/code snippets/drawEngineBasics.snippet new file mode 100644 index 0000000..339c662 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawEngineBasics.snippet @@ -0,0 +1,4633 @@ + + + +
+ drawVectorVisualization + drawVectorVisualization + Draw a VectorVisualization in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorVisualization + vectorVisualization + + + +
+ + +
+ drawVectorFromVisualization + drawVectorFromVisualization + Draw a VectorFromVisualization in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorFromVisualization + vectorFromVisualization + + + +
+ + +
+ drawVectorToVisualization + drawVectorToVisualization + Draw a VectorToVisualization in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorToVisualization + vectorToVisualization + + + +
+ + +
+ drawPositionVisualization_go + drawPositionVisualization_go + Draw a PositionVisualization in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualization + positionVisualization + + + +
+ + +
+ drawPositionVisualization_tr + drawPositionVisualization_tr + Draw a PositionVisualization in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualization + positionVisualization + + + +
+ + +
+ drawPositionVisualization_vec + drawPositionVisualization_vec + Draw a PositionVisualization in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualization + positionVisualization + + + +
+ + +
+ drawVectorVisualizationLocal + drawVectorVisualizationLocal + Draw a VectorVisualizationLocal in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorVisualizationLocal + vectorVisualizationLocal + + + +
+ + +
+ drawVectorFromVisualizationLocal + drawVectorFromVisualizationLocal + Draw a VectorFromVisualizationLocal in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorFromVisualizationLocal + vectorFromVisualizationLocal + + + +
+ + +
+ drawVectorToVisualizationLocal + drawVectorToVisualizationLocal + Draw a VectorToVisualizationLocal in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorToVisualizationLocal + vectorToVisualizationLocal + + + +
+ + +
+ drawPositionVisualizationLocal_go + drawPositionVisualizationLocal_go + Draw a PositionVisualizationLocal in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualizationLocal + positionVisualizationLocal + + + +
+ + +
+ drawPositionVisualizationLocal_tr + drawPositionVisualizationLocal_tr + Draw a PositionVisualizationLocal in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualizationLocal + positionVisualizationLocal + + + +
+ + +
+ drawPositionVisualizationLocal_vec + drawPositionVisualizationLocal_vec + Draw a PositionVisualizationLocal in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualizationLocal + positionVisualizationLocal + + + +
+ + +
+ drawScale_go + drawScale_go + Draw a Scale in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Scale + scale + + + +
+ + +
+ drawScale_tr + drawScale_tr + Draw a Scale in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Scale + scale + + + +
+ + +
+ drawScale_vec + drawScale_vec + Draw a Scale in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Scale + scale + + + +
+ + +
+ drawLocalScale_go + drawLocalScale_go + Draw a LocalScale in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalScale + localScale + + + +
+ + +
+ drawLocalScale_tr + drawLocalScale_tr + Draw a LocalScale in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalScale + localScale + + + +
+ + +
+ drawLocalScale_vec + drawLocalScale_vec + Draw a LocalScale in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalScale + localScale + + + +
+ + +
+ drawQuaternion_go + drawQuaternion_go + Draw a Quaternion in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Quaternion + quaternion + + + +
+ + +
+ drawQuaternion_tr + drawQuaternion_tr + Draw a Quaternion in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Quaternion + quaternion + + + +
+ + +
+ drawQuaternion_quat + drawQuaternion_quat + Draw a Quaternion in the Unity Editor. (of quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Quaternion + quaternion + + + +
+ + +
+ drawQuaternionLocal_go + drawQuaternionLocal_go + Draw a QuaternionLocal in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn QuaternionLocal + quaternionLocal + + + +
+ + +
+ drawQuaternionLocal_tr + drawQuaternionLocal_tr + Draw a QuaternionLocal in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn QuaternionLocal + quaternionLocal + + + +
+ + +
+ drawQuaternionLocal_quat + drawQuaternionLocal_quat + Draw a QuaternionLocal in the Unity Editor. (of quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn QuaternionLocal + quaternionLocal + + + +
+ + +
+ drawEuler_go + drawEuler_go + Draw an Euler in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Euler + euler + + + +
+ + +
+ drawEuler_tr + drawEuler_tr + Draw an Euler in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Euler + euler + + + +
+ + +
+ drawEuler_vec + drawEuler_vec + Draw an Euler in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Euler + euler + + + +
+ + +
+ drawEuler_quat + drawEuler_quat + Draw an Euler in the Unity Editor. (of quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Euler + euler + + + +
+ + +
+ drawEulerLocal_go + drawEulerLocal_go + Draw an EulerLocal in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EulerLocal + eulerLocal + + + +
+ + +
+ drawEulerLocal_tr + drawEulerLocal_tr + Draw an EulerLocal in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EulerLocal + eulerLocal + + + +
+ + +
+ drawEulerLocal_vec + drawEulerLocal_vec + Draw an EulerLocal in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EulerLocal + eulerLocal + + + +
+ + +
+ drawEulerLocal_quat + drawEulerLocal_quat + Draw an EulerLocal in the Unity Editor. (of quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EulerLocal + eulerLocal + + + +
+ + +
+ drawBounds_go + drawBounds_go + Draw Bounds in the Unity Editor. (of mesh on gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bounds + bounds + + + +
+ + +
+ drawLocalBounds_go + drawLocalBounds_go + Draw LocalBounds in the Unity Editor. (of mesh on gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalBounds + localBounds + + + +
+ + +
+ drawBounds_tr + drawBounds_tr + Draw Bounds in the Unity Editor. (of mesh on transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bounds + bounds + + + +
+ + +
+ drawLocalBounds_tr + drawLocalBounds_tr + Draw LocalBounds in the Unity Editor. (of mesh on transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalBounds + localBounds + + + +
+ + +
+ drawBounds_b + drawBounds_b + Draw Bounds in the Unity Editor. (of bounds struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bounds + bounds + + + +
+ + +
+ drawLocalBounds_b + drawLocalBounds_b + Draw LocalBounds in the Unity Editor. (of bounds struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalBounds + localBounds + + + +
+ + +
+ drawDotProduct + drawDotProduct + Draw a DotProduct in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DotProduct + dotProduct + + + +
+ + +
+ drawCrossProduct + drawCrossProduct + Draw a CrossProduct in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CrossProduct + crossProduct + + + +
+ + +
+ drawTagGameObject + drawTagGameObject + Draw TagGameObject in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TagGameObject + tagGameObject + + + +
+ + +
+ drawTagGameObjectScreenspace + drawTagGameObjectScreenspace + Draw TagGameObjectScreenspace in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TagGameObjectScreenspace + tagGameObjectScreenspace + + + +
+ + +
+ drawTagGameObjectScreenspace_cam + drawTagGameObjectScreenspace_cam + Draw TagGameObjectScreenspace in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TagGameObjectScreenspace + tagGameObjectScreenspace + + + +
+ + +
+ drawCamera_rotViaQuat + drawCamera_rotViaQuat + Draw a Camera in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Camera + camera + + + +
+ + +
+ drawCamera_rotViaVec + drawCamera_rotViaVec + Draw a Camera in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Camera + camera + + + +
+ + +
+ drawCamera_cam + drawCamera_cam + Draw a Camera in the Unity Editor. (explicitly defining the visualized camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Camera + camera + + + +
+ + +
+ drawCamFrustum_rotViaQuat + drawCamFrustum_rotViaQuat + Draw a CamFrustum in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CamFrustum + camFrustum + + + +
+ + +
+ drawCamFrustum_rotViaVec + drawCamFrustum_rotViaVec + Draw a CamFrustum in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CamFrustum + camFrustum + + + +
+ + +
+ drawCamFrustum_cam + drawCamFrustum_cam + Draw a CamFrustum in the Unity Editor. (explicitly defining the visualized camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CamFrustum + camFrustum + + + +
+ + +
+ drawBoolDisplayer2D + drawBoolDisplayer2D + Draw a BoolDisplayer2D in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayer2D + boolDisplayer2D + + + +
+ + +
+ drawBoolDisplayer + drawBoolDisplayer + Draw a BoolDisplayer in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayer + boolDisplayer + + + +
+ + +
+ drawBoolDisplayerScreenspace_3Dpos + drawBoolDisplayerScreenspace_3Dpos + Draw a BoolDisplayerScreenspace in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayerScreenspace + boolDisplayerScreenspace + + + +
+ + +
+ drawBoolDisplayerScreenspace_3Dpos_cam + drawBoolDisplayerScreenspace_3Dpos_cam + Draw a BoolDisplayerScreenspace in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayerScreenspace + boolDisplayerScreenspace + + + +
+ + +
+ drawBoolDisplayerScreenspace_2Dpos + drawBoolDisplayerScreenspace_2Dpos + Draw a BoolDisplayerScreenspace in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayerScreenspace + boolDisplayerScreenspace + + + +
+ + +
+ drawBoolDisplayerScreenspace_2Dpos_cam + drawBoolDisplayerScreenspace_2Dpos_cam + Draw a BoolDisplayerScreenspace in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayerScreenspace + boolDisplayerScreenspace + + + +
+ + +
+ drawRayLineExtended_ray + drawRayLineExtended_ray + Draw a RayLineExtended in the Unity Editor. (defined by ray) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtended + rayLineExtended + + + +
+ + +
+ drawRayLineExtended_vec + drawRayLineExtended_vec + Draw a RayLineExtended in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtended + rayLineExtended + + + +
+ + +
+ drawRayLineExtended2D_ray + drawRayLineExtended2D_ray + Draw a RayLineExtended2D in the Unity Editor. (defined by ray) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtended2D + rayLineExtended2D + + + +
+ + +
+ drawRayLineExtended2D_vec + drawRayLineExtended2D_vec + Draw a RayLineExtended2D in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtended2D + rayLineExtended2D + + + +
+ + +
+ drawRayLineExtendedScreenspace + drawRayLineExtendedScreenspace + Draw a RayLineExtendedScreenspace in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtendedScreenspace + rayLineExtendedScreenspace + + + +
+ + +
+ drawRayLineExtendedScreenspace_cam + drawRayLineExtendedScreenspace_cam + Draw a RayLineExtendedScreenspace in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtendedScreenspace + rayLineExtendedScreenspace + + + +
+ + +
+ drawCoordinateAxesGizmo + drawCoordinateAxesGizmo + Draw a CoordinateAxesGizmo in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CoordinateAxesGizmo + coordinateAxesGizmo + + + +
+ + +
+ drawCoordinateAxesGizmoLocal_go + drawCoordinateAxesGizmoLocal_go + Draw a CoordinateAxesGizmoLocal in the Unity Editor. (local space is defined by gameobject as parent) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CoordinateAxesGizmoLocal + coordinateAxesGizmoLocal + + + +
+ + +
+ drawCoordinateAxesGizmoLocal_tr + drawCoordinateAxesGizmoLocal_tr + Draw a CoordinateAxesGizmoLocal in the Unity Editor. (local space is defined by transform as parent) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CoordinateAxesGizmoLocal + coordinateAxesGizmoLocal + + + +
+ + +
+ drawCoordinateAxesGizmoLocal_vecQuat + drawCoordinateAxesGizmoLocal_vecQuat + Draw a CoordinateAxesGizmoLocal in the Unity Editor. (local space is defined via vectors and quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CoordinateAxesGizmoLocal + coordinateAxesGizmoLocal + + + +
+ + +
+ drawGridPlanes_tr + drawGridPlanes_tr + Draw GridPlanes in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanes + gridPlanes + + + +
+ + +
+ drawGridPlanes_vec + drawGridPlanes_vec + Draw GridPlanes in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanes + gridPlanes + + + +
+ + +
+ drawXGridPlanes_tr + drawXGridPlanes_tr + Draw XGridPlanes in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanes + xGridPlanes + + + +
+ + +
+ drawXGridPlanes_vec + drawXGridPlanes_vec + Draw XGridPlanes in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanes + xGridPlanes + + + +
+ + +
+ drawYGridPlanes_tr + drawYGridPlanes_tr + Draw YGridPlanes in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanes + yGridPlanes + + + +
+ + +
+ drawYGridPlanes_vec + drawYGridPlanes_vec + Draw YGridPlanes in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanes + yGridPlanes + + + +
+ + +
+ drawZGridPlanes_tr + drawZGridPlanes_tr + Draw ZGridPlanes in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanes + zGridPlanes + + + +
+ + +
+ drawZGridPlanes_vec + drawZGridPlanes_vec + Draw ZGridPlanes in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanes + zGridPlanes + + + +
+ + +
+ drawGridPlanesLocal_parentSpace_trPos + drawGridPlanesLocal_parentSpace_trPos + Draw GridPlanesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanesLocal + gridPlanesLocal + + + +
+ + +
+ drawGridPlanesLocal_trSpace_vecPos + drawGridPlanesLocal_trSpace_vecPos + Draw GridPlanesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanesLocal + gridPlanesLocal + + + +
+ + +
+ drawXGridPlanesLocal_parentSpace_trPos + drawXGridPlanesLocal_parentSpace_trPos + Draw XGridPlanesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanesLocal + xGridPlanesLocal + + + +
+ + +
+ drawXGridPlanesLocal_trSpace_vecPos + drawXGridPlanesLocal_trSpace_vecPos + Draw XGridPlanesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanesLocal + xGridPlanesLocal + + + +
+ + +
+ drawYGridPlanesLocal_parentSpace_trPos + drawYGridPlanesLocal_parentSpace_trPos + Draw YGridPlanesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanesLocal + yGridPlanesLocal + + + +
+ + +
+ drawYGridPlanesLocal_trSpace_vecPos + drawYGridPlanesLocal_trSpace_vecPos + Draw YGridPlanesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanesLocal + yGridPlanesLocal + + + +
+ + +
+ drawZGridPlanesLocal_parentSpace_trPos + drawZGridPlanesLocal_parentSpace_trPos + Draw ZGridPlanesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanesLocal + zGridPlanesLocal + + + +
+ + +
+ drawZGridPlanesLocal_trSpace_vecPos + drawZGridPlanesLocal_trSpace_vecPos + Draw ZGridPlanesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanesLocal + zGridPlanesLocal + + + +
+ + +
+ drawGridPlanesLocal_vecQuatSpace_trPos + drawGridPlanesLocal_vecQuatSpace_trPos + Draw GridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanesLocal + gridPlanesLocal + + + +
+ + +
+ drawGridPlanesLocal_vecQuatSpace_vecPos + drawGridPlanesLocal_vecQuatSpace_vecPos + Draw GridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanesLocal + gridPlanesLocal + + + +
+ + +
+ drawXGridPlanesLocal_vecQuatSpace_trPos + drawXGridPlanesLocal_vecQuatSpace_trPos + Draw XGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanesLocal + xGridPlanesLocal + + + +
+ + +
+ drawXGridPlanesLocal_vecQuatSpace_vecPos + drawXGridPlanesLocal_vecQuatSpace_vecPos + Draw XGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanesLocal + xGridPlanesLocal + + + +
+ + +
+ drawYGridPlanesLocal_vecQuatSpace_trPos + drawYGridPlanesLocal_vecQuatSpace_trPos + Draw YGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanesLocal + yGridPlanesLocal + + + +
+ + +
+ drawYGridPlanesLocal_vecQuatSpace_vecPos + drawYGridPlanesLocal_vecQuatSpace_vecPos + Draw YGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanesLocal + yGridPlanesLocal + + + +
+ + +
+ drawZGridPlanesLocal_vecQuatSpace_trPos + drawZGridPlanesLocal_vecQuatSpace_trPos + Draw ZGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanesLocal + zGridPlanesLocal + + + +
+ + +
+ drawZGridPlanesLocal_vecQuatSpace_vecPos + drawZGridPlanesLocal_vecQuatSpace_vecPos + Draw ZGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanesLocal + zGridPlanesLocal + + + +
+ + +
+ drawGridLines_tr + drawGridLines_tr + Draw GridLines in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLines + gridLines + + + +
+ + +
+ drawGridLines_vec + drawGridLines_vec + Draw GridLines in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLines + gridLines + + + +
+ + +
+ drawXGridLines_tr + drawXGridLines_tr + Draw XGridLines in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLines + xGridLines + + + +
+ + +
+ drawXGridLines_vec + drawXGridLines_vec + Draw XGridLines in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLines + xGridLines + + + +
+ + +
+ drawYGridLines_tr + drawYGridLines_tr + Draw YGridLines in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLines + yGridLines + + + +
+ + +
+ drawYGridLines_vec + drawYGridLines_vec + Draw YGridLines in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLines + yGridLines + + + +
+ + +
+ drawZGridLines_tr + drawZGridLines_tr + Draw ZGridLines in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLines + zGridLines + + + +
+ + +
+ drawZGridLines_vec + drawZGridLines_vec + Draw ZGridLines in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLines + zGridLines + + + +
+ + +
+ drawGridLinesLocal_parentSpace_trPos + drawGridLinesLocal_parentSpace_trPos + Draw GridLinesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLinesLocal + gridLinesLocal + + + +
+ + +
+ drawGridLinesLocal_trSpace_vecPos + drawGridLinesLocal_trSpace_vecPos + Draw GridLinesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLinesLocal + gridLinesLocal + + + +
+ + +
+ drawXGridLinesLocal_parentSpace_trPos + drawXGridLinesLocal_parentSpace_trPos + Draw XGridLinesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLinesLocal + xGridLinesLocal + + + +
+ + +
+ drawXGridLinesLocal_trSpace_vecPos + drawXGridLinesLocal_trSpace_vecPos + Draw XGridLinesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLinesLocal + xGridLinesLocal + + + +
+ + +
+ drawYGridLinesLocal_parentSpace_trPos + drawYGridLinesLocal_parentSpace_trPos + Draw YGridLinesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLinesLocal + yGridLinesLocal + + + +
+ + +
+ drawYGridLinesLocal_trSpace_vecPos + drawYGridLinesLocal_trSpace_vecPos + Draw YGridLinesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLinesLocal + yGridLinesLocal + + + +
+ + +
+ drawZGridLinesLocal_parentSpace_trPos + drawZGridLinesLocal_parentSpace_trPos + Draw ZGridLinesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLinesLocal + zGridLinesLocal + + + +
+ + +
+ drawZGridLinesLocal_trSpace_vecPos + drawZGridLinesLocal_trSpace_vecPos + Draw ZGridLinesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLinesLocal + zGridLinesLocal + + + +
+ + +
+ drawGridLinesLocal_vecQuatSpace_trPos + drawGridLinesLocal_vecQuatSpace_trPos + Draw GridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLinesLocal + gridLinesLocal + + + +
+ + +
+ drawGridLinesLocal_vecQuatSpace_vecPos + drawGridLinesLocal_vecQuatSpace_vecPos + Draw GridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLinesLocal + gridLinesLocal + + + +
+ + +
+ drawXGridLinesLocal_vecQuatSpace_trPos + drawXGridLinesLocal_vecQuatSpace_trPos + Draw XGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLinesLocal + xGridLinesLocal + + + +
+ + +
+ drawXGridLinesLocal_vecQuatSpace_vecPos + drawXGridLinesLocal_vecQuatSpace_vecPos + Draw XGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLinesLocal + xGridLinesLocal + + + +
+ + +
+ drawYGridLinesLocal_vecQuatSpace_trPos + drawYGridLinesLocal_vecQuatSpace_trPos + Draw YGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLinesLocal + yGridLinesLocal + + + +
+ + +
+ drawYGridLinesLocal_vecQuatSpace_vecPos + drawYGridLinesLocal_vecQuatSpace_vecPos + Draw YGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLinesLocal + yGridLinesLocal + + + +
+ + +
+ drawZGridLinesLocal_vecQuatSpace_trPos + drawZGridLinesLocal_vecQuatSpace_trPos + Draw ZGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLinesLocal + zGridLinesLocal + + + +
+ + +
+ drawZGridLinesLocal_vecQuatSpace_vecPos + drawZGridLinesLocal_vecQuatSpace_vecPos + Draw ZGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLinesLocal + zGridLinesLocal + + + +
+ + +
+ drawGridScreenspace + drawGridScreenspace + Draw GridScreenspace in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridScreenspace + gridScreenspace + + + +
+ + +
+ drawGridScreenspace_cam + drawGridScreenspace_cam + Draw GridScreenspace in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridScreenspace + gridScreenspace + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawEngineBasics.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawEngineBasics.snippet.meta new file mode 100644 index 0000000..ff6af61 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawEngineBasics.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0a9e57153cb40714da59a87a4d0c7b28 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawEngineBasics_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawEngineBasics_func.snippet new file mode 100644 index 0000000..883c5d7 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawEngineBasics_func.snippet @@ -0,0 +1,4978 @@ + + + +
+ drawVectorVisualization_func + drawVectorVisualization_func + Encapsulated in a function: Draw a VectorVisualization in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorVisualization + WithThisName + + + +
+ + +
+ drawVectorFromVisualization_func + drawVectorFromVisualization_func + Encapsulated in a function: Draw a VectorFromVisualization in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorFromVisualization + WithThisName + + + +
+ + +
+ drawVectorToVisualization_func + drawVectorToVisualization_func + Encapsulated in a function: Draw a VectorToVisualization in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorToVisualization + WithThisName + + + +
+ + +
+ drawPositionVisualization_go_func + drawPositionVisualization_go_func + Encapsulated in a function: Draw a PositionVisualization in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualization + WithThisName + + + +
+ + +
+ drawPositionVisualization_tr_func + drawPositionVisualization_tr_func + Encapsulated in a function: Draw a PositionVisualization in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualization + WithThisName + + + +
+ + +
+ drawPositionVisualization_vec_func + drawPositionVisualization_vec_func + Encapsulated in a function: Draw a PositionVisualization in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualization + WithThisName + + + +
+ + +
+ drawVectorVisualizationLocal_func + drawVectorVisualizationLocal_func + Encapsulated in a function: Draw a VectorVisualizationLocal in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorVisualizationLocal + WithThisName + + + +
+ + +
+ drawVectorFromVisualizationLocal_func + drawVectorFromVisualizationLocal_func + Encapsulated in a function: Draw a VectorFromVisualizationLocal in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorFromVisualizationLocal + WithThisName + + + +
+ + +
+ drawVectorToVisualizationLocal_func + drawVectorToVisualizationLocal_func + Encapsulated in a function: Draw a VectorToVisualizationLocal in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn VectorToVisualizationLocal + WithThisName + + + +
+ + +
+ drawPositionVisualizationLocal_go_func + drawPositionVisualizationLocal_go_func + Encapsulated in a function: Draw a PositionVisualizationLocal in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualizationLocal + WithThisName + + + +
+ + +
+ drawPositionVisualizationLocal_tr_func + drawPositionVisualizationLocal_tr_func + Encapsulated in a function: Draw a PositionVisualizationLocal in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualizationLocal + WithThisName + + + +
+ + +
+ drawPositionVisualizationLocal_vec_func + drawPositionVisualizationLocal_vec_func + Encapsulated in a function: Draw a PositionVisualizationLocal in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn PositionVisualizationLocal + WithThisName + + + +
+ + +
+ drawScale_go_func + drawScale_go_func + Encapsulated in a function: Draw a Scale in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Scale + WithThisName + + + +
+ + +
+ drawScale_tr_func + drawScale_tr_func + Encapsulated in a function: Draw a Scale in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Scale + WithThisName + + + +
+ + +
+ drawScale_vec_func + drawScale_vec_func + Encapsulated in a function: Draw a Scale in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Scale + WithThisName + + + +
+ + +
+ drawLocalScale_go_func + drawLocalScale_go_func + Encapsulated in a function: Draw a LocalScale in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalScale + WithThisName + + + +
+ + +
+ drawLocalScale_tr_func + drawLocalScale_tr_func + Encapsulated in a function: Draw a LocalScale in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalScale + WithThisName + + + +
+ + +
+ drawLocalScale_vec_func + drawLocalScale_vec_func + Encapsulated in a function: Draw a LocalScale in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalScale + WithThisName + + + +
+ + +
+ drawQuaternion_go_func + drawQuaternion_go_func + Encapsulated in a function: Draw a Quaternion in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Quaternion + WithThisName + + + +
+ + +
+ drawQuaternion_tr_func + drawQuaternion_tr_func + Encapsulated in a function: Draw a Quaternion in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Quaternion + WithThisName + + + +
+ + +
+ drawQuaternion_quat_func + drawQuaternion_quat_func + Encapsulated in a function: Draw a Quaternion in the Unity Editor. (of quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Quaternion + WithThisName + + + +
+ + +
+ drawQuaternionLocal_go_func + drawQuaternionLocal_go_func + Encapsulated in a function: Draw a QuaternionLocal in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn QuaternionLocal + WithThisName + + + +
+ + +
+ drawQuaternionLocal_tr_func + drawQuaternionLocal_tr_func + Encapsulated in a function: Draw a QuaternionLocal in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn QuaternionLocal + WithThisName + + + +
+ + +
+ drawQuaternionLocal_quat_func + drawQuaternionLocal_quat_func + Encapsulated in a function: Draw a QuaternionLocal in the Unity Editor. (of quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn QuaternionLocal + WithThisName + + + +
+ + +
+ drawEuler_go_func + drawEuler_go_func + Encapsulated in a function: Draw an Euler in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Euler + WithThisName + + + +
+ + +
+ drawEuler_tr_func + drawEuler_tr_func + Encapsulated in a function: Draw an Euler in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Euler + WithThisName + + + +
+ + +
+ drawEuler_vec_func + drawEuler_vec_func + Encapsulated in a function: Draw an Euler in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Euler + WithThisName + + + +
+ + +
+ drawEuler_quat_func + drawEuler_quat_func + Encapsulated in a function: Draw an Euler in the Unity Editor. (of quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Euler + WithThisName + + + +
+ + +
+ drawEulerLocal_go_func + drawEulerLocal_go_func + Encapsulated in a function: Draw an EulerLocal in the Unity Editor. (of gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EulerLocal + WithThisName + + + +
+ + +
+ drawEulerLocal_tr_func + drawEulerLocal_tr_func + Encapsulated in a function: Draw an EulerLocal in the Unity Editor. (of transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EulerLocal + WithThisName + + + +
+ + +
+ drawEulerLocal_vec_func + drawEulerLocal_vec_func + Encapsulated in a function: Draw an EulerLocal in the Unity Editor. (of vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EulerLocal + WithThisName + + + +
+ + +
+ drawEulerLocal_quat_func + drawEulerLocal_quat_func + Encapsulated in a function: Draw an EulerLocal in the Unity Editor. (of quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EulerLocal + WithThisName + + + +
+ + +
+ drawBounds_go_func + drawBounds_go_func + Encapsulated in a function: Draw Bounds in the Unity Editor. (of mesh on gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bounds + WithThisName + + + +
+ + +
+ drawLocalBounds_go_func + drawLocalBounds_go_func + Encapsulated in a function: Draw LocalBounds in the Unity Editor. (of mesh on gameobject) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalBounds + WithThisName + + + +
+ + +
+ drawBounds_tr_func + drawBounds_tr_func + Encapsulated in a function: Draw Bounds in the Unity Editor. (of mesh on transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bounds + WithThisName + + + +
+ + +
+ drawLocalBounds_tr_func + drawLocalBounds_tr_func + Encapsulated in a function: Draw LocalBounds in the Unity Editor. (of mesh on transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalBounds + WithThisName + + + +
+ + +
+ drawBounds_b_func + drawBounds_b_func + Encapsulated in a function: Draw Bounds in the Unity Editor. (of bounds struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bounds + WithThisName + + + +
+ + +
+ drawLocalBounds_b_func + drawLocalBounds_b_func + Encapsulated in a function: Draw LocalBounds in the Unity Editor. (of bounds struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LocalBounds + WithThisName + + + +
+ + +
+ drawDotProduct_func + drawDotProduct_func + Encapsulated in a function: Draw a DotProduct in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DotProduct + WithThisName + + + +
+ + +
+ drawCrossProduct_func + drawCrossProduct_func + Encapsulated in a function: Draw a CrossProduct in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CrossProduct + WithThisName + + + +
+ + +
+ drawTagGameObject_func + drawTagGameObject_func + Encapsulated in a function: Draw TagGameObject in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TagGameObject + WithThisName + + + +
+ + +
+ drawTagGameObjectScreenspace_func + drawTagGameObjectScreenspace_func + Encapsulated in a function: Draw TagGameObjectScreenspace in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TagGameObjectScreenspace + WithThisName + + + +
+ + +
+ drawTagGameObjectScreenspace_cam_func + drawTagGameObjectScreenspace_cam_func + Encapsulated in a function: Draw TagGameObjectScreenspace in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TagGameObjectScreenspace + WithThisName + + + +
+ + +
+ drawCamera_rotViaQuat_func + drawCamera_rotViaQuat_func + Encapsulated in a function: Draw a Camera in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Camera + WithThisName + + + +
+ + +
+ drawCamera_rotViaVec_func + drawCamera_rotViaVec_func + Encapsulated in a function: Draw a Camera in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Camera + WithThisName + + + +
+ + +
+ drawCamera_cam_func + drawCamera_cam_func + Encapsulated in a function: Draw a Camera in the Unity Editor. (explicitly defining the visualized camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Camera + WithThisName + + + +
+ + +
+ drawCamFrustum_rotViaQuat_func + drawCamFrustum_rotViaQuat_func + Encapsulated in a function: Draw a CamFrustum in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CamFrustum + WithThisName + + + +
+ + +
+ drawCamFrustum_rotViaVec_func + drawCamFrustum_rotViaVec_func + Encapsulated in a function: Draw a CamFrustum in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CamFrustum + WithThisName + + + +
+ + +
+ drawCamFrustum_cam_func + drawCamFrustum_cam_func + Encapsulated in a function: Draw a CamFrustum in the Unity Editor. (explicitly defining the visualized camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CamFrustum + WithThisName + + + +
+ + +
+ drawBoolDisplayer2D_func + drawBoolDisplayer2D_func + Encapsulated in a function: Draw a BoolDisplayer2D in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayer2D + WithThisName + + + +
+ + +
+ drawBoolDisplayer_func + drawBoolDisplayer_func + Encapsulated in a function: Draw a BoolDisplayer in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayer + WithThisName + + + +
+ + +
+ drawBoolDisplayerScreenspace_3Dpos_func + drawBoolDisplayerScreenspace_3Dpos_func + Encapsulated in a function: Draw a BoolDisplayerScreenspace in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayerScreenspace + WithThisName + + + +
+ + +
+ drawBoolDisplayerScreenspace_3Dpos_cam_func + drawBoolDisplayerScreenspace_3Dpos_cam_func + Encapsulated in a function: Draw a BoolDisplayerScreenspace in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayerScreenspace + WithThisName + + + +
+ + +
+ drawBoolDisplayerScreenspace_2Dpos_func + drawBoolDisplayerScreenspace_2Dpos_func + Encapsulated in a function: Draw a BoolDisplayerScreenspace in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayerScreenspace + WithThisName + + + +
+ + +
+ drawBoolDisplayerScreenspace_2Dpos_cam_func + drawBoolDisplayerScreenspace_2Dpos_cam_func + Encapsulated in a function: Draw a BoolDisplayerScreenspace in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoolDisplayerScreenspace + WithThisName + + + +
+ + +
+ drawRayLineExtended_ray_func + drawRayLineExtended_ray_func + Encapsulated in a function: Draw a RayLineExtended in the Unity Editor. (defined by ray) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtended + WithThisName + + + +
+ + +
+ drawRayLineExtended_vec_func + drawRayLineExtended_vec_func + Encapsulated in a function: Draw a RayLineExtended in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtended + WithThisName + + + +
+ + +
+ drawRayLineExtended2D_ray_func + drawRayLineExtended2D_ray_func + Encapsulated in a function: Draw a RayLineExtended2D in the Unity Editor. (defined by ray) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtended2D + WithThisName + + + +
+ + +
+ drawRayLineExtended2D_vec_func + drawRayLineExtended2D_vec_func + Encapsulated in a function: Draw a RayLineExtended2D in the Unity Editor. (defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtended2D + WithThisName + + + +
+ + +
+ drawRayLineExtendedScreenspace_func + drawRayLineExtendedScreenspace_func + Encapsulated in a function: Draw a RayLineExtendedScreenspace in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtendedScreenspace + WithThisName + + + +
+ + +
+ drawRayLineExtendedScreenspace_cam_func + drawRayLineExtendedScreenspace_cam_func + Encapsulated in a function: Draw a RayLineExtendedScreenspace in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RayLineExtendedScreenspace + WithThisName + + + +
+ + +
+ drawCoordinateAxesGizmo_func + drawCoordinateAxesGizmo_func + Encapsulated in a function: Draw a CoordinateAxesGizmo in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CoordinateAxesGizmo + WithThisName + + + +
+ + +
+ drawCoordinateAxesGizmoLocal_go_func + drawCoordinateAxesGizmoLocal_go_func + Encapsulated in a function: Draw a CoordinateAxesGizmoLocal in the Unity Editor. (local space is defined by gameobject as parent) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CoordinateAxesGizmoLocal + WithThisName + + + +
+ + +
+ drawCoordinateAxesGizmoLocal_tr_func + drawCoordinateAxesGizmoLocal_tr_func + Encapsulated in a function: Draw a CoordinateAxesGizmoLocal in the Unity Editor. (local space is defined by transform as parent) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CoordinateAxesGizmoLocal + WithThisName + + + +
+ + +
+ drawCoordinateAxesGizmoLocal_vecQuat_func + drawCoordinateAxesGizmoLocal_vecQuat_func + Encapsulated in a function: Draw a CoordinateAxesGizmoLocal in the Unity Editor. (local space is defined via vectors and quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CoordinateAxesGizmoLocal + WithThisName + + + +
+ + +
+ drawGridPlanes_tr_func + drawGridPlanes_tr_func + Encapsulated in a function: Draw GridPlanes in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanes + WithThisName + + + +
+ + +
+ drawGridPlanes_vec_func + drawGridPlanes_vec_func + Encapsulated in a function: Draw GridPlanes in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanes + WithThisName + + + +
+ + +
+ drawXGridPlanes_tr_func + drawXGridPlanes_tr_func + Encapsulated in a function: Draw XGridPlanes in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanes + WithThisName + + + +
+ + +
+ drawXGridPlanes_vec_func + drawXGridPlanes_vec_func + Encapsulated in a function: Draw XGridPlanes in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanes + WithThisName + + + +
+ + +
+ drawYGridPlanes_tr_func + drawYGridPlanes_tr_func + Encapsulated in a function: Draw YGridPlanes in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanes + WithThisName + + + +
+ + +
+ drawYGridPlanes_vec_func + drawYGridPlanes_vec_func + Encapsulated in a function: Draw YGridPlanes in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanes + WithThisName + + + +
+ + +
+ drawZGridPlanes_tr_func + drawZGridPlanes_tr_func + Encapsulated in a function: Draw ZGridPlanes in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanes + WithThisName + + + +
+ + +
+ drawZGridPlanes_vec_func + drawZGridPlanes_vec_func + Encapsulated in a function: Draw ZGridPlanes in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanes + WithThisName + + + +
+ + +
+ drawGridPlanesLocal_parentSpace_trPos_func + drawGridPlanesLocal_parentSpace_trPos_func + Encapsulated in a function: Draw GridPlanesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanesLocal + WithThisName + + + +
+ + +
+ drawGridPlanesLocal_trSpace_vecPos_func + drawGridPlanesLocal_trSpace_vecPos_func + Encapsulated in a function: Draw GridPlanesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanesLocal + WithThisName + + + +
+ + +
+ drawXGridPlanesLocal_parentSpace_trPos_func + drawXGridPlanesLocal_parentSpace_trPos_func + Encapsulated in a function: Draw XGridPlanesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanesLocal + WithThisName + + + +
+ + +
+ drawXGridPlanesLocal_trSpace_vecPos_func + drawXGridPlanesLocal_trSpace_vecPos_func + Encapsulated in a function: Draw XGridPlanesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanesLocal + WithThisName + + + +
+ + +
+ drawYGridPlanesLocal_parentSpace_trPos_func + drawYGridPlanesLocal_parentSpace_trPos_func + Encapsulated in a function: Draw YGridPlanesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanesLocal + WithThisName + + + +
+ + +
+ drawYGridPlanesLocal_trSpace_vecPos_func + drawYGridPlanesLocal_trSpace_vecPos_func + Encapsulated in a function: Draw YGridPlanesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanesLocal + WithThisName + + + +
+ + +
+ drawZGridPlanesLocal_parentSpace_trPos_func + drawZGridPlanesLocal_parentSpace_trPos_func + Encapsulated in a function: Draw ZGridPlanesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanesLocal + WithThisName + + + +
+ + +
+ drawZGridPlanesLocal_trSpace_vecPos_func + drawZGridPlanesLocal_trSpace_vecPos_func + Encapsulated in a function: Draw ZGridPlanesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanesLocal + WithThisName + + + +
+ + +
+ drawGridPlanesLocal_vecQuatSpace_trPos_func + drawGridPlanesLocal_vecQuatSpace_trPos_func + Encapsulated in a function: Draw GridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanesLocal + WithThisName + + + +
+ + +
+ drawGridPlanesLocal_vecQuatSpace_vecPos_func + drawGridPlanesLocal_vecQuatSpace_vecPos_func + Encapsulated in a function: Draw GridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridPlanesLocal + WithThisName + + + +
+ + +
+ drawXGridPlanesLocal_vecQuatSpace_trPos_func + drawXGridPlanesLocal_vecQuatSpace_trPos_func + Encapsulated in a function: Draw XGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanesLocal + WithThisName + + + +
+ + +
+ drawXGridPlanesLocal_vecQuatSpace_vecPos_func + drawXGridPlanesLocal_vecQuatSpace_vecPos_func + Encapsulated in a function: Draw XGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridPlanesLocal + WithThisName + + + +
+ + +
+ drawYGridPlanesLocal_vecQuatSpace_trPos_func + drawYGridPlanesLocal_vecQuatSpace_trPos_func + Encapsulated in a function: Draw YGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanesLocal + WithThisName + + + +
+ + +
+ drawYGridPlanesLocal_vecQuatSpace_vecPos_func + drawYGridPlanesLocal_vecQuatSpace_vecPos_func + Encapsulated in a function: Draw YGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridPlanesLocal + WithThisName + + + +
+ + +
+ drawZGridPlanesLocal_vecQuatSpace_trPos_func + drawZGridPlanesLocal_vecQuatSpace_trPos_func + Encapsulated in a function: Draw ZGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanesLocal + WithThisName + + + +
+ + +
+ drawZGridPlanesLocal_vecQuatSpace_vecPos_func + drawZGridPlanesLocal_vecQuatSpace_vecPos_func + Encapsulated in a function: Draw ZGridPlanesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridPlanesLocal + WithThisName + + + +
+ + +
+ drawGridLines_tr_func + drawGridLines_tr_func + Encapsulated in a function: Draw GridLines in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLines + WithThisName + + + +
+ + +
+ drawGridLines_vec_func + drawGridLines_vec_func + Encapsulated in a function: Draw GridLines in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLines + WithThisName + + + +
+ + +
+ drawXGridLines_tr_func + drawXGridLines_tr_func + Encapsulated in a function: Draw XGridLines in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLines + WithThisName + + + +
+ + +
+ drawXGridLines_vec_func + drawXGridLines_vec_func + Encapsulated in a function: Draw XGridLines in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLines + WithThisName + + + +
+ + +
+ drawYGridLines_tr_func + drawYGridLines_tr_func + Encapsulated in a function: Draw YGridLines in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLines + WithThisName + + + +
+ + +
+ drawYGridLines_vec_func + drawYGridLines_vec_func + Encapsulated in a function: Draw YGridLines in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLines + WithThisName + + + +
+ + +
+ drawZGridLines_tr_func + drawZGridLines_tr_func + Encapsulated in a function: Draw ZGridLines in the Unity Editor. (around transform's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLines + WithThisName + + + +
+ + +
+ drawZGridLines_vec_func + drawZGridLines_vec_func + Encapsulated in a function: Draw ZGridLines in the Unity Editor. (around vector's position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLines + WithThisName + + + +
+ + +
+ drawGridLinesLocal_parentSpace_trPos_func + drawGridLinesLocal_parentSpace_trPos_func + Encapsulated in a function: Draw GridLinesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLinesLocal + WithThisName + + + +
+ + +
+ drawGridLinesLocal_trSpace_vecPos_func + drawGridLinesLocal_trSpace_vecPos_func + Encapsulated in a function: Draw GridLinesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLinesLocal + WithThisName + + + +
+ + +
+ drawXGridLinesLocal_parentSpace_trPos_func + drawXGridLinesLocal_parentSpace_trPos_func + Encapsulated in a function: Draw XGridLinesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLinesLocal + WithThisName + + + +
+ + +
+ drawXGridLinesLocal_trSpace_vecPos_func + drawXGridLinesLocal_trSpace_vecPos_func + Encapsulated in a function: Draw XGridLinesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLinesLocal + WithThisName + + + +
+ + +
+ drawYGridLinesLocal_parentSpace_trPos_func + drawYGridLinesLocal_parentSpace_trPos_func + Encapsulated in a function: Draw YGridLinesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLinesLocal + WithThisName + + + +
+ + +
+ drawYGridLinesLocal_trSpace_vecPos_func + drawYGridLinesLocal_trSpace_vecPos_func + Encapsulated in a function: Draw YGridLinesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLinesLocal + WithThisName + + + +
+ + +
+ drawZGridLinesLocal_parentSpace_trPos_func + drawZGridLinesLocal_parentSpace_trPos_func + Encapsulated in a function: Draw ZGridLinesLocal in the Unity Editor. (local space from transfrom parent, position from transfrom itself) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLinesLocal + WithThisName + + + +
+ + +
+ drawZGridLinesLocal_trSpace_vecPos_func + drawZGridLinesLocal_trSpace_vecPos_func + Encapsulated in a function: Draw ZGridLinesLocal in the Unity Editor. (local space from transfrom, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLinesLocal + WithThisName + + + +
+ + +
+ drawGridLinesLocal_vecQuatSpace_trPos_func + drawGridLinesLocal_vecQuatSpace_trPos_func + Encapsulated in a function: Draw GridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLinesLocal + WithThisName + + + +
+ + +
+ drawGridLinesLocal_vecQuatSpace_vecPos_func + drawGridLinesLocal_vecQuatSpace_vecPos_func + Encapsulated in a function: Draw GridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridLinesLocal + WithThisName + + + +
+ + +
+ drawXGridLinesLocal_vecQuatSpace_trPos_func + drawXGridLinesLocal_vecQuatSpace_trPos_func + Encapsulated in a function: Draw XGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLinesLocal + WithThisName + + + +
+ + +
+ drawXGridLinesLocal_vecQuatSpace_vecPos_func + drawXGridLinesLocal_vecQuatSpace_vecPos_func + Encapsulated in a function: Draw XGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn XGridLinesLocal + WithThisName + + + +
+ + +
+ drawYGridLinesLocal_vecQuatSpace_trPos_func + drawYGridLinesLocal_vecQuatSpace_trPos_func + Encapsulated in a function: Draw YGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLinesLocal + WithThisName + + + +
+ + +
+ drawYGridLinesLocal_vecQuatSpace_vecPos_func + drawYGridLinesLocal_vecQuatSpace_vecPos_func + Encapsulated in a function: Draw YGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn YGridLinesLocal + WithThisName + + + +
+ + +
+ drawZGridLinesLocal_vecQuatSpace_trPos_func + drawZGridLinesLocal_vecQuatSpace_trPos_func + Encapsulated in a function: Draw ZGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLinesLocal + WithThisName + + + +
+ + +
+ drawZGridLinesLocal_vecQuatSpace_vecPos_func + drawZGridLinesLocal_vecQuatSpace_vecPos_func + Encapsulated in a function: Draw ZGridLinesLocal in the Unity Editor. (local space from vectors+quaternion, position from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ZGridLinesLocal + WithThisName + + + +
+ + +
+ drawGridScreenspace_func + drawGridScreenspace_func + Encapsulated in a function: Draw GridScreenspace in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridScreenspace + WithThisName + + + +
+ + +
+ drawGridScreenspace_cam_func + drawGridScreenspace_cam_func + Encapsulated in a function: Draw GridScreenspace in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GridScreenspace + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawEngineBasics_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawEngineBasics_func.snippet.meta new file mode 100644 index 0000000..dc996c8 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawEngineBasics_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c44f4a6761c0c9647a71a90238fb32f8 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawLogs.snippet b/Editor/DrawDebugLibrary/code snippets/drawLogs.snippet new file mode 100644 index 0000000..f1780cf --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawLogs.snippet @@ -0,0 +1,202 @@ + + + +
+ drawLogsAtGameObject + drawLogsAtGameObject + Draw LogsAtGameObject in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LogsAtGameObject + logsAtGameObject + + + +
+ + +
+ drawLogsAtGameObjectScreenspace + drawLogsAtGameObjectScreenspace + Draw LogsAtGameObjectScreenspace in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LogsAtGameObjectScreenspace + logsAtGameObjectScreenspace + + + +
+ + +
+ drawLogsAtGameObjectScreenspace_cam + drawLogsAtGameObjectScreenspace_cam + Draw LogsAtGameObjectScreenspace in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LogsAtGameObjectScreenspace + logsAtGameObjectScreenspace + + + +
+ + +
+ drawLogsOnScreen + drawLogsOnScreen + Draw LogsOnScreen in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LogsOnScreen + logsOnScreen + + + +
+ + +
+ drawLogsOnScreen_cam + drawLogsOnScreen_cam + Draw LogsOnScreen in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LogsOnScreen + logsOnScreen + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawLogs.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawLogs.snippet.meta new file mode 100644 index 0000000..2ce8718 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawLogs.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 25816cd2b1986ac4cb001ea0a3802d79 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawLogs_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawLogs_func.snippet new file mode 100644 index 0000000..7aa4617 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawLogs_func.snippet @@ -0,0 +1,217 @@ + + + +
+ drawLogsAtGameObject_func + drawLogsAtGameObject_func + Encapsulated in a function: Draw LogsAtGameObject in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LogsAtGameObject + WithThisName + + + +
+ + +
+ drawLogsAtGameObjectScreenspace_func + drawLogsAtGameObjectScreenspace_func + Encapsulated in a function: Draw LogsAtGameObjectScreenspace in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LogsAtGameObjectScreenspace + WithThisName + + + +
+ + +
+ drawLogsAtGameObjectScreenspace_cam_func + drawLogsAtGameObjectScreenspace_cam_func + Encapsulated in a function: Draw LogsAtGameObjectScreenspace in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LogsAtGameObjectScreenspace + WithThisName + + + +
+ + +
+ drawLogsOnScreen_func + drawLogsOnScreen_func + Encapsulated in a function: Draw LogsOnScreen in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LogsOnScreen + WithThisName + + + +
+ + +
+ drawLogsOnScreen_cam_func + drawLogsOnScreen_cam_func + Encapsulated in a function: Draw LogsOnScreen in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LogsOnScreen + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawLogs_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawLogs_func.snippet.meta new file mode 100644 index 0000000..6520364 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawLogs_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 767574db6964a3d45b3e8c4e720b39f7 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawMeasurements.snippet b/Editor/DrawDebugLibrary/code snippets/drawMeasurements.snippet new file mode 100644 index 0000000..aac3f7a --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawMeasurements.snippet @@ -0,0 +1,940 @@ + + + +
+ drawDistance + drawDistance + Draw a Distance in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Distance + distance + + + +
+ + +
+ drawAngle + drawAngle + Draw an Angle in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Angle + angle + + + +
+ + +
+ drawAngleSpan + drawAngleSpan + Draw an AngleSpan in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleSpan + angleSpan + + + +
+ + +
+ drawDistancePointToLine_ray + drawDistancePointToLine_ray + Draw a DistancePointToLine in the Unity Editor. (line defined by ray) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToLine + distancePointToLine + + + +
+ + +
+ drawDistancePointToLine_vec + drawDistancePointToLine_vec + Draw a DistancePointToLine in the Unity Editor. (line defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToLine + distancePointToLine + + + +
+ + +
+ drawDistanceLineToLine_ray + drawDistanceLineToLine_ray + Draw a DistanceLineToLine in the Unity Editor. (lines defined by rays) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceLineToLine + distanceLineToLine + + + +
+ + +
+ drawDistanceLineToLine_vec + drawDistanceLineToLine_vec + Draw a DistanceLineToLine in the Unity Editor. (lines defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceLineToLine + distanceLineToLine + + + +
+ + +
+ drawDistancePerpToOrthoViewDir + drawDistancePerpToOrthoViewDir + Draw a DistancePerpToOrthoViewDir in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePerpToOrthoViewDir + distancePerpToOrthoViewDir + + + +
+ + +
+ drawDistanceAlongOrthoViewDir + drawDistanceAlongOrthoViewDir + Draw a DistanceAlongOrthoViewDir in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceAlongOrthoViewDir + distanceAlongOrthoViewDir + + + +
+ + +
+ drawDistancePointToPlane_tr + drawDistancePointToPlane_tr + Draw a DistancePointToPlane in the Unity Editor. (plane defined by transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToPlane + distancePointToPlane + + + +
+ + +
+ drawDistancePointToPlane_pl + drawDistancePointToPlane_pl + Draw a DistancePointToPlane in the Unity Editor. (plane defined by plane struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToPlane + distancePointToPlane + + + +
+ + +
+ drawDistancePointToPlane_vec + drawDistancePointToPlane_vec + Draw a DistancePointToPlane in the Unity Editor. (plane defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToPlane + distancePointToPlane + + + +
+ + +
+ drawAngleLineToPlane_ray_tr + drawAngleLineToPlane_ray_tr + Draw an AngleLineToPlane in the Unity Editor. (line defined by ray, plane defined by transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + angleLineToPlane + + + +
+ + +
+ drawAngleLineToPlane_ray_pl + drawAngleLineToPlane_ray_pl + Draw an AngleLineToPlane in the Unity Editor. (line defined by ray, plane defined by plane struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + angleLineToPlane + + + +
+ + +
+ drawAngleLineToPlane_ray_vec + drawAngleLineToPlane_ray_vec + Draw an AngleLineToPlane in the Unity Editor. (line defined by ray, plane defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + angleLineToPlane + + + +
+ + +
+ drawAngleLineToPlane_vec_tr + drawAngleLineToPlane_vec_tr + Draw an AngleLineToPlane in the Unity Editor. (line defined by vectors, plane defined by transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + angleLineToPlane + + + +
+ + +
+ drawAngleLineToPlane_vec_pl + drawAngleLineToPlane_vec_pl + Draw an AngleLineToPlane in the Unity Editor. (line defined by vectors, plane defined by plane struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + angleLineToPlane + + + +
+ + +
+ drawAngleLineToPlane_vec_vec + drawAngleLineToPlane_vec_vec + Draw an AngleLineToPlane in the Unity Editor. (line defined by vectors, plane defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + angleLineToPlane + + + +
+ + +
+ drawAnglePlaneToPlane_tr + drawAnglePlaneToPlane_tr + Draw an AnglePlaneToPlane in the Unity Editor. (planes defined by transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AnglePlaneToPlane + anglePlaneToPlane + + + +
+ + +
+ drawAnglePlaneToPlane_pl + drawAnglePlaneToPlane_pl + Draw an AnglePlaneToPlane in the Unity Editor. (planes defined by plane structs) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AnglePlaneToPlane + anglePlaneToPlane + + + +
+ + +
+ drawAnglePlaneToPlane_vec + drawAnglePlaneToPlane_vec + Draw an AnglePlaneToPlane in the Unity Editor. (planes defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AnglePlaneToPlane + anglePlaneToPlane + + + +
+ + +
+ drawDistanceThreshold + drawDistanceThreshold + Draw DistanceThreshold in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceThreshold + distanceThreshold + + + +
+ + +
+ drawDistanceThresholds + drawDistanceThresholds + Draw DistanceThresholds in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceThresholds + distanceThresholds + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawMeasurements.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawMeasurements.snippet.meta new file mode 100644 index 0000000..a5a7464 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawMeasurements.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6cee829548990bd408da0d379f8bf9fd +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D.snippet b/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D.snippet new file mode 100644 index 0000000..e832384 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D.snippet @@ -0,0 +1,383 @@ + + + +
+ drawDistance2D + drawDistance2D + Draw a Distance in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Distance + distance + + + +
+ + +
+ drawAngle2D + drawAngle2D + Draw an Angle in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Angle + angle + + + +
+ + +
+ drawAngleSpan2D + drawAngleSpan2D + Draw an AngleSpan in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleSpan + angleSpan + + + +
+ + +
+ drawDistancePointToLine2D_ray + drawDistancePointToLine2D_ray + Draw a DistancePointToLine in the Unity Editor. (line defined by ray) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToLine + distancePointToLine + + + +
+ + +
+ drawDistancePointToLine2D_vec + drawDistancePointToLine2D_vec + Draw a DistancePointToLine in the Unity Editor. (line defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToLine + distancePointToLine + + + +
+ + +
+ drawAngleLineToLine2D_ray + drawAngleLineToLine2D_ray + Draw an AngleLineToLine in the Unity Editor. (lines defined by rays) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToLine + angleLineToLine + + + +
+ + +
+ drawAngleLineToLine2D_vec + drawAngleLineToLine2D_vec + Draw an AngleLineToLine in the Unity Editor. (lines defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToLine + angleLineToLine + + + +
+ + +
+ drawDistanceThreshold2D + drawDistanceThreshold2D + Draw DistanceThreshold in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceThreshold + distanceThreshold + + + +
+ + +
+ drawDistanceThresholds2D + drawDistanceThresholds2D + Draw DistanceThresholds in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceThresholds + distanceThresholds + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D.snippet.meta new file mode 100644 index 0000000..d558762 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 340017e511c8ac74e94c66e44717e95f +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D_func.snippet new file mode 100644 index 0000000..dc7e316 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D_func.snippet @@ -0,0 +1,410 @@ + + + +
+ drawDistance2D_func + drawDistance2D_func + Encapsulated in a function: Draw a Distance in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Distance + WithThisName + + + +
+ + +
+ drawAngle2D_func + drawAngle2D_func + Encapsulated in a function: Draw an Angle in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Angle + WithThisName + + + +
+ + +
+ drawAngleSpan2D_func + drawAngleSpan2D_func + Encapsulated in a function: Draw an AngleSpan in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleSpan + WithThisName + + + +
+ + +
+ drawDistancePointToLine2D_ray_func + drawDistancePointToLine2D_ray_func + Encapsulated in a function: Draw a DistancePointToLine in the Unity Editor. (line defined by ray) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToLine + WithThisName + + + +
+ + +
+ drawDistancePointToLine2D_vec_func + drawDistancePointToLine2D_vec_func + Encapsulated in a function: Draw a DistancePointToLine in the Unity Editor. (line defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToLine + WithThisName + + + +
+ + +
+ drawAngleLineToLine2D_ray_func + drawAngleLineToLine2D_ray_func + Encapsulated in a function: Draw an AngleLineToLine in the Unity Editor. (lines defined by rays) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToLine + WithThisName + + + +
+ + +
+ drawAngleLineToLine2D_vec_func + drawAngleLineToLine2D_vec_func + Encapsulated in a function: Draw an AngleLineToLine in the Unity Editor. (lines defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToLine + WithThisName + + + +
+ + +
+ drawDistanceThreshold2D_func + drawDistanceThreshold2D_func + Encapsulated in a function: Draw DistanceThreshold in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceThreshold + WithThisName + + + +
+ + +
+ drawDistanceThresholds2D_func + drawDistanceThresholds2D_func + Encapsulated in a function: Draw DistanceThresholds in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceThresholds + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D_func.snippet.meta new file mode 100644 index 0000000..0591db2 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawMeasurements2D_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d3ee7dbed886b61488b82b7097c81c4e +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawMeasurements_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawMeasurements_func.snippet new file mode 100644 index 0000000..16fcea9 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawMeasurements_func.snippet @@ -0,0 +1,1009 @@ + + + +
+ drawDistance_func + drawDistance_func + Encapsulated in a function: Draw a Distance in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Distance + WithThisName + + + +
+ + +
+ drawAngle_func + drawAngle_func + Encapsulated in a function: Draw an Angle in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Angle + WithThisName + + + +
+ + +
+ drawAngleSpan_func + drawAngleSpan_func + Encapsulated in a function: Draw an AngleSpan in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleSpan + WithThisName + + + +
+ + +
+ drawDistancePointToLine_ray_func + drawDistancePointToLine_ray_func + Encapsulated in a function: Draw a DistancePointToLine in the Unity Editor. (line defined by ray) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToLine + WithThisName + + + +
+ + +
+ drawDistancePointToLine_vec_func + drawDistancePointToLine_vec_func + Encapsulated in a function: Draw a DistancePointToLine in the Unity Editor. (line defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToLine + WithThisName + + + +
+ + +
+ drawDistanceLineToLine_ray_func + drawDistanceLineToLine_ray_func + Encapsulated in a function: Draw a DistanceLineToLine in the Unity Editor. (lines defined by rays) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceLineToLine + WithThisName + + + +
+ + +
+ drawDistanceLineToLine_vec_func + drawDistanceLineToLine_vec_func + Encapsulated in a function: Draw a DistanceLineToLine in the Unity Editor. (lines defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceLineToLine + WithThisName + + + +
+ + +
+ drawDistancePerpToOrthoViewDir_func + drawDistancePerpToOrthoViewDir_func + Encapsulated in a function: Draw a DistancePerpToOrthoViewDir in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePerpToOrthoViewDir + WithThisName + + + +
+ + +
+ drawDistanceAlongOrthoViewDir_func + drawDistanceAlongOrthoViewDir_func + Encapsulated in a function: Draw a DistanceAlongOrthoViewDir in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceAlongOrthoViewDir + WithThisName + + + +
+ + +
+ drawDistancePointToPlane_tr_func + drawDistancePointToPlane_tr_func + Encapsulated in a function: Draw a DistancePointToPlane in the Unity Editor. (plane defined by transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToPlane + WithThisName + + + +
+ + +
+ drawDistancePointToPlane_pl_func + drawDistancePointToPlane_pl_func + Encapsulated in a function: Draw a DistancePointToPlane in the Unity Editor. (plane defined by plane struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToPlane + WithThisName + + + +
+ + +
+ drawDistancePointToPlane_vec_func + drawDistancePointToPlane_vec_func + Encapsulated in a function: Draw a DistancePointToPlane in the Unity Editor. (plane defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistancePointToPlane + WithThisName + + + +
+ + +
+ drawAngleLineToPlane_ray_tr_func + drawAngleLineToPlane_ray_tr_func + Encapsulated in a function: Draw an AngleLineToPlane in the Unity Editor. (line defined by ray, plane defined by transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + WithThisName + + + +
+ + +
+ drawAngleLineToPlane_ray_pl_func + drawAngleLineToPlane_ray_pl_func + Encapsulated in a function: Draw an AngleLineToPlane in the Unity Editor. (line defined by ray, plane defined by plane struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + WithThisName + + + +
+ + +
+ drawAngleLineToPlane_ray_vec_func + drawAngleLineToPlane_ray_vec_func + Encapsulated in a function: Draw an AngleLineToPlane in the Unity Editor. (line defined by ray, plane defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + WithThisName + + + +
+ + +
+ drawAngleLineToPlane_vec_tr_func + drawAngleLineToPlane_vec_tr_func + Encapsulated in a function: Draw an AngleLineToPlane in the Unity Editor. (line defined by vectors, plane defined by transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + WithThisName + + + +
+ + +
+ drawAngleLineToPlane_vec_pl_func + drawAngleLineToPlane_vec_pl_func + Encapsulated in a function: Draw an AngleLineToPlane in the Unity Editor. (line defined by vectors, plane defined by plane struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + WithThisName + + + +
+ + +
+ drawAngleLineToPlane_vec_vec_func + drawAngleLineToPlane_vec_vec_func + Encapsulated in a function: Draw an AngleLineToPlane in the Unity Editor. (line defined by vectors, plane defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AngleLineToPlane + WithThisName + + + +
+ + +
+ drawAnglePlaneToPlane_tr_func + drawAnglePlaneToPlane_tr_func + Encapsulated in a function: Draw an AnglePlaneToPlane in the Unity Editor. (planes defined by transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AnglePlaneToPlane + WithThisName + + + +
+ + +
+ drawAnglePlaneToPlane_pl_func + drawAnglePlaneToPlane_pl_func + Encapsulated in a function: Draw an AnglePlaneToPlane in the Unity Editor. (planes defined by plane structs) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AnglePlaneToPlane + WithThisName + + + +
+ + +
+ drawAnglePlaneToPlane_vec_func + drawAnglePlaneToPlane_vec_func + Encapsulated in a function: Draw an AnglePlaneToPlane in the Unity Editor. (planes defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn AnglePlaneToPlane + WithThisName + + + +
+ + +
+ drawDistanceThreshold_func + drawDistanceThreshold_func + Encapsulated in a function: Draw DistanceThreshold in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceThreshold + WithThisName + + + +
+ + +
+ drawDistanceThresholds_func + drawDistanceThresholds_func + Encapsulated in a function: Draw DistanceThresholds in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn DistanceThresholds + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawMeasurements_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawMeasurements_func.snippet.meta new file mode 100644 index 0000000..b136aed --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawMeasurements_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2d0ccc893ca930143913f29eb216254c +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawPhysics.snippet b/Editor/DrawDebugLibrary/code snippets/drawPhysics.snippet new file mode 100644 index 0000000..ab23329 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawPhysics.snippet @@ -0,0 +1,1290 @@ + + + +
+ drawBoxCast + drawBoxCast + Draw a BoxCast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCast + boxCast + + + +
+ + +
+ drawBoxCast_outInfo + drawBoxCast_outInfo + Draw a BoxCast in the Unity Editor. (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCast + boxCast + + + +
+ + +
+ drawBoxCastAll + drawBoxCastAll + Draw a BoxCastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCastAll + boxCastAll + + + +
+ + +
+ drawBoxCastNonAlloc + drawBoxCastNonAlloc + Draw a BoxCastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCastNonAlloc + boxCastNonAlloc + + + +
+ + +
+ drawCapsuleCast_outInfo + drawCapsuleCast_outInfo + Draw a CapsuleCast in the Unity Editor. (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCast + capsuleCast + + + +
+ + +
+ drawCapsuleCast + drawCapsuleCast + Draw a CapsuleCast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCast + capsuleCast + + + +
+ + +
+ drawCapsuleCastAll + drawCapsuleCastAll + Draw a CapsuleCastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCastAll + capsuleCastAll + + + +
+ + +
+ drawCapsuleCastNonAlloc + drawCapsuleCastNonAlloc + Draw a CapsuleCastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCastNonAlloc + capsuleCastNonAlloc + + + +
+ + +
+ drawLinecast_outInfo + drawLinecast_outInfo + Draw a Linecast in the Unity Editor. (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Linecast + linecast + + + +
+ + +
+ drawLinecast + drawLinecast + Draw a Linecast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Linecast + linecast + + + +
+ + +
+ drawRaycast_ray_outInfo + drawRaycast_ray_outInfo + Draw a Raycast in the Unity Editor. (direction defined by ray struct) (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + raycast + + + +
+ + +
+ drawRaycast_ray + drawRaycast_ray + Draw a Raycast in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + raycast + + + +
+ + +
+ drawRaycast_vec_outInfo + drawRaycast_vec_outInfo + Draw a Raycast in the Unity Editor. (direction defined by vectors) (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + raycast + + + +
+ + +
+ drawRaycast_vec + drawRaycast_vec + Draw a Raycast in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + raycast + + + +
+ + +
+ drawRaycastAll_vec + drawRaycastAll_vec + Draw a RaycastAll in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastAll + raycastAll + + + +
+ + +
+ drawRaycastAll_ray + drawRaycastAll_ray + Draw a RaycastAll in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastAll + raycastAll + + + +
+ + +
+ drawRaycastNonAlloc_ray + drawRaycastNonAlloc_ray + Draw a RaycastNonAlloc in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastNonAlloc + raycastNonAlloc + + + +
+ + +
+ drawRaycastNonAlloc_vec + drawRaycastNonAlloc_vec + Draw a RaycastNonAlloc in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastNonAlloc + raycastNonAlloc + + + +
+ + +
+ drawSphereCast_ray + drawSphereCast_ray + Draw a SphereCast in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCast + sphereCast + + + +
+ + +
+ drawSphereCast_ray_outInfo + drawSphereCast_ray_outInfo + Draw a SphereCast in the Unity Editor. (direction defined by ray struct) (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCast + sphereCast + + + +
+ + +
+ drawSphereCast_vec + drawSphereCast_vec + Draw a SphereCast in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCast + sphereCast + + + +
+ + +
+ drawSphereCast_vec_outInfo + drawSphereCast_vec_outInfo + Draw a SphereCast in the Unity Editor. (direction defined by vectors) (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCast + sphereCast + + + +
+ + +
+ drawSphereCastAll_ray + drawSphereCastAll_ray + Draw a SphereCastAll in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCastAll + sphereCastAll + + + +
+ + +
+ drawSphereCastAll_vec + drawSphereCastAll_vec + Draw a SphereCastAll in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCastAll + sphereCastAll + + + +
+ + +
+ drawSphereCastNonAlloc_ray + drawSphereCastNonAlloc_ray + Draw a SphereCastNonAlloc in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCastNonAlloc + sphereCastNonAlloc + + + +
+ + +
+ drawSphereCastNonAlloc_vec + drawSphereCastNonAlloc_vec + Draw a SphereCastNonAlloc in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCastNonAlloc + sphereCastNonAlloc + + + +
+ + +
+ drawCheckBox + drawCheckBox + Draw CheckBox in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CheckBox + checkBox + + + +
+ + +
+ drawCheckCapsule + drawCheckCapsule + Draw CheckCapsule in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CheckCapsule + checkCapsule + + + +
+ + +
+ drawCheckSphere + drawCheckSphere + Draw CheckSphere in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CheckSphere + checkSphere + + + +
+ + +
+ drawOverlapBox + drawOverlapBox + Draw OverlapBox in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBox + overlapBox + + + +
+ + +
+ drawOverlapBoxNonAlloc + drawOverlapBoxNonAlloc + Draw OverlapBoxNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBoxNonAlloc + overlapBoxNonAlloc + + + +
+ + +
+ drawOverlapCapsule + drawOverlapCapsule + Draw OverlapCapsule in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsule + overlapCapsule + + + +
+ + +
+ drawOverlapCapsuleNonAlloc + drawOverlapCapsuleNonAlloc + Draw OverlapCapsuleNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsuleNonAlloc + overlapCapsuleNonAlloc + + + +
+ + +
+ drawOverlapSphere + drawOverlapSphere + Draw OverlapSphere in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapSphere + overlapSphere + + + +
+ + +
+ drawOverlapSphereNonAlloc + drawOverlapSphereNonAlloc + Draw OverlapSphereNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapSphereNonAlloc + overlapSphereNonAlloc + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawPhysics.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawPhysics.snippet.meta new file mode 100644 index 0000000..5799047 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawPhysics.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 96e77762a628f604a9dbf7839e59942d +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawPhysics2D.snippet b/Editor/DrawDebugLibrary/code snippets/drawPhysics2D.snippet new file mode 100644 index 0000000..e4dccc1 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawPhysics2D.snippet @@ -0,0 +1,1956 @@ + + + +
+ drawBoxCast2D + drawBoxCast2D + Draw a BoxCast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCast + boxCast + + + +
+ + +
+ drawBoxCast2D_conFil_array + drawBoxCast2D_conFil_array + Draw a BoxCast in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCast + boxCast + + + +
+ + +
+ drawBoxCast2D_conFil_list + drawBoxCast2D_conFil_list + Draw a BoxCast in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results_of_$name$ = ; + float distance_of_$name$ = float.PositiveInfinity; + string nameTag_of_$name$ = null; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = false; + DrawPhysics2D.BoxCast(origin_of_$name$, size_of_$name$, angle_of_$name$, direction_of_$name$, contactFilter_of_$name$, results_of_$name$, distance_of_$name$, nameTag_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn BoxCast + boxCast + + + +
+ + +
+ drawBoxCastAll2D + drawBoxCastAll2D + Draw a BoxCastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCastAll + boxCastAll + + + +
+ + +
+ drawBoxCastNonAlloc2D + drawBoxCastNonAlloc2D + Draw a BoxCastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCastNonAlloc + boxCastNonAlloc + + + +
+ + +
+ drawCapsuleCast2D + drawCapsuleCast2D + Draw a CapsuleCast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCast + capsuleCast + + + +
+ + +
+ drawCapsuleCast2D_conFil_array + drawCapsuleCast2D_conFil_array + Draw a CapsuleCast in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCast + capsuleCast + + + +
+ + +
+ drawCapsuleCast2D_conFil_list + drawCapsuleCast2D_conFil_list + Draw a CapsuleCast in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results_of_$name$ = ; + float distance_of_$name$ = float.PositiveInfinity; + string nameTag_of_$name$ = null; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = false; + DrawPhysics2D.CapsuleCast(origin_of_$name$, size_of_$name$, capsuleDirection_of_$name$, angle_of_$name$, direction_of_$name$, contactFilter_of_$name$, results_of_$name$, distance_of_$name$, nameTag_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn CapsuleCast + capsuleCast + + + +
+ + +
+ drawCapsuleCastAll2D + drawCapsuleCastAll2D + Draw a CapsuleCastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCastAll + capsuleCastAll + + + +
+ + +
+ drawCapsuleCastNonAlloc2D + drawCapsuleCastNonAlloc2D + Draw a CapsuleCastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCastNonAlloc + capsuleCastNonAlloc + + + +
+ + +
+ drawCircleCast2D + drawCircleCast2D + Draw a CircleCast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleCast + circleCast + + + +
+ + +
+ drawCircleCast2D_conFil_array + drawCircleCast2D_conFil_array + Draw a CircleCast in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleCast + circleCast + + + +
+ + +
+ drawCircleCast2D_conFil_list + drawCircleCast2D_conFil_list + Draw a CircleCast in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results_of_$name$ = ; + float distance_of_$name$ = float.PositiveInfinity; + string nameTag_of_$name$ = null; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = false; + DrawPhysics2D.CircleCast(origin_of_$name$, radius_of_$name$, direction_of_$name$, contactFilter_of_$name$, results_of_$name$, distance_of_$name$, nameTag_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn CircleCast + circleCast + + + +
+ + +
+ drawCircleCastAll2D + drawCircleCastAll2D + Draw a CircleCastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleCastAll + circleCastAll + + + +
+ + +
+ drawCircleCastNonAlloc2D + drawCircleCastNonAlloc2D + Draw a CircleCastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleCastNonAlloc + circleCastNonAlloc + + + +
+ + +
+ drawGetRayIntersection2D + drawGetRayIntersection2D + Draw GetRayIntersection in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GetRayIntersection + getRayIntersection + + + +
+ + +
+ drawGetRayIntersectionAll2D + drawGetRayIntersectionAll2D + Draw GetRayIntersectionAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GetRayIntersectionAll + getRayIntersectionAll + + + +
+ + +
+ drawGetRayIntersectionNonAlloc2D + drawGetRayIntersectionNonAlloc2D + Draw GetRayIntersectionNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GetRayIntersectionNonAlloc + getRayIntersectionNonAlloc + + + +
+ + +
+ drawLinecast2D + drawLinecast2D + Draw a Linecast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Linecast + linecast + + + +
+ + +
+ drawLinecast2D_conFil_array + drawLinecast2D_conFil_array + Draw a Linecast in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Linecast + linecast + + + +
+ + +
+ drawLinecast2D_conFil_list + drawLinecast2D_conFil_list + Draw a Linecast in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results_of_$name$ = ; + string nameTag_of_$name$ = null; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = false; + DrawPhysics2D.Linecast(start_of_$name$, end_of_$name$, contactFilter_of_$name$, results_of_$name$, nameTag_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn Linecast + linecast + + + +
+ + +
+ drawLinecastAll2D + drawLinecastAll2D + Draw a LinecastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LinecastAll + linecastAll + + + +
+ + +
+ drawLinecastNonAlloc2D + drawLinecastNonAlloc2D + Draw a LinecastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LinecastNonAlloc + linecastNonAlloc + + + +
+ + +
+ drawRaycast2D + drawRaycast2D + Draw a Raycast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + raycast + + + +
+ + +
+ drawRaycast2D_conFil_array + drawRaycast2D_conFil_array + Draw a Raycast in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + raycast + + + +
+ + +
+ drawRaycast2D_conFil_list + drawRaycast2D_conFil_list + Draw a Raycast in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results_of_$name$ = ; + float distance_of_$name$ = float.PositiveInfinity; + string nameTag_of_$name$ = null; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = false; + DrawPhysics2D.Raycast(origin_of_$name$, direction_of_$name$, contactFilter_of_$name$, results_of_$name$, distance_of_$name$, nameTag_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn Raycast + raycast + + + +
+ + +
+ drawRaycastAll2D + drawRaycastAll2D + Draw a RaycastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastAll + raycastAll + + + +
+ + +
+ drawRaycastNonAlloc2D + drawRaycastNonAlloc2D + Draw a RaycastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastNonAlloc + raycastNonAlloc + + + +
+ + +
+ drawOverlapArea2D + drawOverlapArea2D + Draw OverlapArea in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapArea + overlapArea + + + +
+ + +
+ drawOverlapArea2D_conFil_array + drawOverlapArea2D_conFil_array + Draw OverlapArea in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapArea + overlapArea + + + +
+ + +
+ drawOverlapArea2D_conFil_list + drawOverlapArea2D_conFil_list + Draw OverlapArea in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results_of_$name$ = ; + string nameTag_of_$name$ = null; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = false; + DrawPhysics2D.OverlapArea(pointA_of_$name$, pointB_of_$name$, contactFilter_of_$name$, results_of_$name$, nameTag_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn OverlapArea + overlapArea + + + +
+ + +
+ drawOverlapAreaAll2D + drawOverlapAreaAll2D + Draw OverlapAreaAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapAreaAll + overlapAreaAll + + + +
+ + +
+ drawOverlapAreaNonAlloc2D + drawOverlapAreaNonAlloc2D + Draw OverlapAreaNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapAreaNonAlloc + overlapAreaNonAlloc + + + +
+ + +
+ drawOverlapBox2D + drawOverlapBox2D + Draw OverlapBox in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBox + overlapBox + + + +
+ + +
+ drawOverlapBox2D_conFil_array + drawOverlapBox2D_conFil_array + Draw OverlapBox in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBox + overlapBox + + + +
+ + +
+ drawOverlapBox2D_conFil_list + drawOverlapBox2D_conFil_list + Draw OverlapBox in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results_of_$name$ = ; + string nameTag_of_$name$ = null; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = false; + DrawPhysics2D.OverlapBox(point_of_$name$, size_of_$name$, angle_of_$name$, contactFilter_of_$name$, results_of_$name$, nameTag_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn OverlapBox + overlapBox + + + +
+ + +
+ drawOverlapBoxAll2D + drawOverlapBoxAll2D + Draw OverlapBoxAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBoxAll + overlapBoxAll + + + +
+ + +
+ drawOverlapBoxNonAlloc2D + drawOverlapBoxNonAlloc2D + Draw OverlapBoxNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBoxNonAlloc + overlapBoxNonAlloc + + + +
+ + +
+ drawOverlapCapsule2D + drawOverlapCapsule2D + Draw OverlapCapsule in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsule + overlapCapsule + + + +
+ + +
+ drawOverlapCapsule2D_conFil_array + drawOverlapCapsule2D_conFil_array + Draw OverlapCapsule in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsule + overlapCapsule + + + +
+ + +
+ drawOverlapCapsule2D_conFil_list + drawOverlapCapsule2D_conFil_list + Draw OverlapCapsule in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results_of_$name$ = ; + string nameTag_of_$name$ = null; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = false; + DrawPhysics2D.OverlapCapsule(point_of_$name$, size_of_$name$, direction_of_$name$, angle_of_$name$, contactFilter_of_$name$, results_of_$name$, nameTag_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsule + overlapCapsule + + + +
+ + +
+ drawOverlapCapsuleAll2D + drawOverlapCapsuleAll2D + Draw OverlapCapsuleAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsuleAll + overlapCapsuleAll + + + +
+ + +
+ drawOverlapCapsuleNonAlloc2D + drawOverlapCapsuleNonAlloc2D + Draw OverlapCapsuleNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsuleNonAlloc + overlapCapsuleNonAlloc + + + +
+ + +
+ drawOverlapCircle2D + drawOverlapCircle2D + Draw OverlapCircle in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCircle + overlapCircle + + + +
+ + +
+ drawOverlapCircle2D_conFil_array + drawOverlapCircle2D_conFil_array + Draw OverlapCircle in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCircle + overlapCircle + + + +
+ + +
+ drawOverlapCircle2D_conFil_list + drawOverlapCircle2D_conFil_list + Draw OverlapCircle in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results_of_$name$ = ; + string nameTag_of_$name$ = null; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = false; + DrawPhysics2D.OverlapCircle(point_of_$name$, radius_of_$name$, contactFilter_of_$name$, results_of_$name$, nameTag_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn OverlapCircle + overlapCircle + + + +
+ + +
+ drawOverlapCircleAll2D + drawOverlapCircleAll2D + Draw OverlapCircleAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCircleAll + overlapCircleAll + + + +
+ + +
+ drawOverlapCircleNonAlloc2D + drawOverlapCircleNonAlloc2D + Draw OverlapCircleNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCircleNonAlloc + overlapCircleNonAlloc + + + +
+ + +
+ drawOverlapPoint2D + drawOverlapPoint2D + Draw OverlapPoint in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapPoint + overlapPoint + + + +
+ + +
+ drawOverlapPoint2D_conFil_array + drawOverlapPoint2D_conFil_array + Draw OverlapPoint in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapPoint + overlapPoint + + + +
+ + +
+ drawOverlapPoint2D_conFil_list + drawOverlapPoint2D_conFil_list + Draw OverlapPoint in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results_of_$name$ = ; + string nameTag_of_$name$ = null; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = false; + DrawPhysics2D.OverlapPoint(point_of_$name$, contactFilter_of_$name$, results_of_$name$, nameTag_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn OverlapPoint + overlapPoint + + + +
+ + +
+ drawOverlapPointAll2D + drawOverlapPointAll2D + Draw OverlapPointAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapPointAll + overlapPointAll + + + +
+ + +
+ drawOverlapPointNonAlloc2D + drawOverlapPointNonAlloc2D + Draw OverlapPointNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapPointNonAlloc + overlapPointNonAlloc + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawPhysics2D.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawPhysics2D.snippet.meta new file mode 100644 index 0000000..47d0817 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawPhysics2D.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bae756d6b3c653c4281c25cce684522b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawPhysics2D_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawPhysics2D_func.snippet new file mode 100644 index 0000000..a4fc9c3 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawPhysics2D_func.snippet @@ -0,0 +1,2115 @@ + + + +
+ drawBoxCast2D_func + drawBoxCast2D_func + Encapsulated in a function: Draw a BoxCast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCast + WithThisName + + + +
+ + +
+ drawBoxCast2D_conFil_array_func + drawBoxCast2D_conFil_array_func + Encapsulated in a function: Draw a BoxCast in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCast + WithThisName + + + +
+ + +
+ drawBoxCast2D_conFil_list_func + drawBoxCast2D_conFil_list_func + Encapsulated in a function: Draw a BoxCast in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results = ; + float distance = float.PositiveInfinity; + string nameTag = null; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = false; + return DrawPhysics2D.BoxCast(origin, size, angle, direction, contactFilter, results, distance, nameTag, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn BoxCast + WithThisName + + + +
+ + +
+ drawBoxCastAll2D_func + drawBoxCastAll2D_func + Encapsulated in a function: Draw a BoxCastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCastAll + WithThisName + + + +
+ + +
+ drawBoxCastNonAlloc2D_func + drawBoxCastNonAlloc2D_func + Encapsulated in a function: Draw a BoxCastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCastNonAlloc + WithThisName + + + +
+ + +
+ drawCapsuleCast2D_func + drawCapsuleCast2D_func + Encapsulated in a function: Draw a CapsuleCast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCast + WithThisName + + + +
+ + +
+ drawCapsuleCast2D_conFil_array_func + drawCapsuleCast2D_conFil_array_func + Encapsulated in a function: Draw a CapsuleCast in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCast + WithThisName + + + +
+ + +
+ drawCapsuleCast2D_conFil_list_func + drawCapsuleCast2D_conFil_list_func + Encapsulated in a function: Draw a CapsuleCast in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results = ; + float distance = float.PositiveInfinity; + string nameTag = null; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = false; + return DrawPhysics2D.CapsuleCast(origin, size, capsuleDirection, angle, direction, contactFilter, results, distance, nameTag, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn CapsuleCast + WithThisName + + + +
+ + +
+ drawCapsuleCastAll2D_func + drawCapsuleCastAll2D_func + Encapsulated in a function: Draw a CapsuleCastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCastAll + WithThisName + + + +
+ + +
+ drawCapsuleCastNonAlloc2D_func + drawCapsuleCastNonAlloc2D_func + Encapsulated in a function: Draw a CapsuleCastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCastNonAlloc + WithThisName + + + +
+ + +
+ drawCircleCast2D_func + drawCircleCast2D_func + Encapsulated in a function: Draw a CircleCast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleCast + WithThisName + + + +
+ + +
+ drawCircleCast2D_conFil_array_func + drawCircleCast2D_conFil_array_func + Encapsulated in a function: Draw a CircleCast in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleCast + WithThisName + + + +
+ + +
+ drawCircleCast2D_conFil_list_func + drawCircleCast2D_conFil_list_func + Encapsulated in a function: Draw a CircleCast in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results = ; + float distance = float.PositiveInfinity; + string nameTag = null; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = false; + return DrawPhysics2D.CircleCast(origin, radius, direction, contactFilter, results, distance, nameTag, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn CircleCast + WithThisName + + + +
+ + +
+ drawCircleCastAll2D_func + drawCircleCastAll2D_func + Encapsulated in a function: Draw a CircleCastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleCastAll + WithThisName + + + +
+ + +
+ drawCircleCastNonAlloc2D_func + drawCircleCastNonAlloc2D_func + Encapsulated in a function: Draw a CircleCastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CircleCastNonAlloc + WithThisName + + + +
+ + +
+ drawGetRayIntersection2D_func + drawGetRayIntersection2D_func + Encapsulated in a function: Draw GetRayIntersection in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GetRayIntersection + WithThisName + + + +
+ + +
+ drawGetRayIntersectionAll2D_func + drawGetRayIntersectionAll2D_func + Encapsulated in a function: Draw GetRayIntersectionAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GetRayIntersectionAll + WithThisName + + + +
+ + +
+ drawGetRayIntersectionNonAlloc2D_func + drawGetRayIntersectionNonAlloc2D_func + Encapsulated in a function: Draw GetRayIntersectionNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn GetRayIntersectionNonAlloc + WithThisName + + + +
+ + +
+ drawLinecast2D_func + drawLinecast2D_func + Encapsulated in a function: Draw a Linecast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Linecast + WithThisName + + + +
+ + +
+ drawLinecast2D_conFil_array_func + drawLinecast2D_conFil_array_func + Encapsulated in a function: Draw a Linecast in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Linecast + WithThisName + + + +
+ + +
+ drawLinecast2D_conFil_list_func + drawLinecast2D_conFil_list_func + Encapsulated in a function: Draw a Linecast in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results = ; + string nameTag = null; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = false; + return DrawPhysics2D.Linecast(start, end, contactFilter, results, nameTag, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn Linecast + WithThisName + + + +
+ + +
+ drawLinecastAll2D_func + drawLinecastAll2D_func + Encapsulated in a function: Draw a LinecastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LinecastAll + WithThisName + + + +
+ + +
+ drawLinecastNonAlloc2D_func + drawLinecastNonAlloc2D_func + Encapsulated in a function: Draw a LinecastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn LinecastNonAlloc + WithThisName + + + +
+ + +
+ drawRaycast2D_func + drawRaycast2D_func + Encapsulated in a function: Draw a Raycast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + WithThisName + + + +
+ + +
+ drawRaycast2D_conFil_array_func + drawRaycast2D_conFil_array_func + Encapsulated in a function: Draw a Raycast in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + WithThisName + + + +
+ + +
+ drawRaycast2D_conFil_list_func + drawRaycast2D_conFil_list_func + Encapsulated in a function: Draw a Raycast in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results = ; + float distance = float.PositiveInfinity; + string nameTag = null; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = false; + return DrawPhysics2D.Raycast(origin, direction, contactFilter, results, distance, nameTag, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn Raycast + WithThisName + + + +
+ + +
+ drawRaycastAll2D_func + drawRaycastAll2D_func + Encapsulated in a function: Draw a RaycastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastAll + WithThisName + + + +
+ + +
+ drawRaycastNonAlloc2D_func + drawRaycastNonAlloc2D_func + Encapsulated in a function: Draw a RaycastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastNonAlloc + WithThisName + + + +
+ + +
+ drawOverlapArea2D_func + drawOverlapArea2D_func + Encapsulated in a function: Draw OverlapArea in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapArea + WithThisName + + + +
+ + +
+ drawOverlapArea2D_conFil_array_func + drawOverlapArea2D_conFil_array_func + Encapsulated in a function: Draw OverlapArea in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapArea + WithThisName + + + +
+ + +
+ drawOverlapArea2D_conFil_list_func + drawOverlapArea2D_conFil_list_func + Encapsulated in a function: Draw OverlapArea in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results = ; + string nameTag = null; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = false; + return DrawPhysics2D.OverlapArea(pointA, pointB, contactFilter, results, nameTag, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn OverlapArea + WithThisName + + + +
+ + +
+ drawOverlapAreaAll2D_func + drawOverlapAreaAll2D_func + Encapsulated in a function: Draw OverlapAreaAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapAreaAll + WithThisName + + + +
+ + +
+ drawOverlapAreaNonAlloc2D_func + drawOverlapAreaNonAlloc2D_func + Encapsulated in a function: Draw OverlapAreaNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapAreaNonAlloc + WithThisName + + + +
+ + +
+ drawOverlapBox2D_func + drawOverlapBox2D_func + Encapsulated in a function: Draw OverlapBox in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBox + WithThisName + + + +
+ + +
+ drawOverlapBox2D_conFil_array_func + drawOverlapBox2D_conFil_array_func + Encapsulated in a function: Draw OverlapBox in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBox + WithThisName + + + +
+ + +
+ drawOverlapBox2D_conFil_list_func + drawOverlapBox2D_conFil_list_func + Encapsulated in a function: Draw OverlapBox in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results = ; + string nameTag = null; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = false; + return DrawPhysics2D.OverlapBox(point, size, angle, contactFilter, results, nameTag, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn OverlapBox + WithThisName + + + +
+ + +
+ drawOverlapBoxAll2D_func + drawOverlapBoxAll2D_func + Encapsulated in a function: Draw OverlapBoxAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBoxAll + WithThisName + + + +
+ + +
+ drawOverlapBoxNonAlloc2D_func + drawOverlapBoxNonAlloc2D_func + Encapsulated in a function: Draw OverlapBoxNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBoxNonAlloc + WithThisName + + + +
+ + +
+ drawOverlapCapsule2D_func + drawOverlapCapsule2D_func + Encapsulated in a function: Draw OverlapCapsule in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsule + WithThisName + + + +
+ + +
+ drawOverlapCapsule2D_conFil_array_func + drawOverlapCapsule2D_conFil_array_func + Encapsulated in a function: Draw OverlapCapsule in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsule + WithThisName + + + +
+ + +
+ drawOverlapCapsule2D_conFil_list_func + drawOverlapCapsule2D_conFil_list_func + Encapsulated in a function: Draw OverlapCapsule in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results = ; + string nameTag = null; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = false; + return DrawPhysics2D.OverlapCapsule(point, size, direction, angle, contactFilter, results, nameTag, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsule + WithThisName + + + +
+ + +
+ drawOverlapCapsuleAll2D_func + drawOverlapCapsuleAll2D_func + Encapsulated in a function: Draw OverlapCapsuleAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsuleAll + WithThisName + + + +
+ + +
+ drawOverlapCapsuleNonAlloc2D_func + drawOverlapCapsuleNonAlloc2D_func + Encapsulated in a function: Draw OverlapCapsuleNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsuleNonAlloc + WithThisName + + + +
+ + +
+ drawOverlapCircle2D_func + drawOverlapCircle2D_func + Encapsulated in a function: Draw OverlapCircle in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCircle + WithThisName + + + +
+ + +
+ drawOverlapCircle2D_conFil_array_func + drawOverlapCircle2D_conFil_array_func + Encapsulated in a function: Draw OverlapCircle in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCircle + WithThisName + + + +
+ + +
+ drawOverlapCircle2D_conFil_list_func + drawOverlapCircle2D_conFil_list_func + Encapsulated in a function: Draw OverlapCircle in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results = ; + string nameTag = null; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = false; + return DrawPhysics2D.OverlapCircle(point, radius, contactFilter, results, nameTag, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn OverlapCircle + WithThisName + + + +
+ + +
+ drawOverlapCircleAll2D_func + drawOverlapCircleAll2D_func + Encapsulated in a function: Draw OverlapCircleAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCircleAll + WithThisName + + + +
+ + +
+ drawOverlapCircleNonAlloc2D_func + drawOverlapCircleNonAlloc2D_func + Encapsulated in a function: Draw OverlapCircleNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCircleNonAlloc + WithThisName + + + +
+ + +
+ drawOverlapPoint2D_func + drawOverlapPoint2D_func + Encapsulated in a function: Draw OverlapPoint in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapPoint + WithThisName + + + +
+ + +
+ drawOverlapPoint2D_conFil_array_func + drawOverlapPoint2D_conFil_array_func + Encapsulated in a function: Draw OverlapPoint in the Unity Editor. (specified via ContactFilter2D) (hit results via array) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapPoint + WithThisName + + + +
+ + +
+ drawOverlapPoint2D_conFil_list_func + drawOverlapPoint2D_conFil_list_func + Encapsulated in a function: Draw OverlapPoint in the Unity Editor. (specified via ContactFilter2D) (hit results via list) + Draw XXL +
+ + + results = ; + string nameTag = null; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = false; + return DrawPhysics2D.OverlapPoint(point, contactFilter, results, nameTag, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn OverlapPoint + WithThisName + + + +
+ + +
+ drawOverlapPointAll2D_func + drawOverlapPointAll2D_func + Encapsulated in a function: Draw OverlapPointAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapPointAll + WithThisName + + + +
+ + +
+ drawOverlapPointNonAlloc2D_func + drawOverlapPointNonAlloc2D_func + Encapsulated in a function: Draw OverlapPointNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapPointNonAlloc + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawPhysics2D_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawPhysics2D_func.snippet.meta new file mode 100644 index 0000000..a2066b3 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawPhysics2D_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: fffa22eb13936fd469e2e654df7bb986 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawPhysics_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawPhysics_func.snippet new file mode 100644 index 0000000..f999f35 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawPhysics_func.snippet @@ -0,0 +1,1395 @@ + + + +
+ drawBoxCast_func + drawBoxCast_func + Encapsulated in a function: Draw a BoxCast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCast + WithThisName + + + +
+ + +
+ drawBoxCast_outInfo_func + drawBoxCast_outInfo_func + Encapsulated in a function: Draw a BoxCast in the Unity Editor. (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCast + WithThisName + + + +
+ + +
+ drawBoxCastAll_func + drawBoxCastAll_func + Encapsulated in a function: Draw a BoxCastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCastAll + WithThisName + + + +
+ + +
+ drawBoxCastNonAlloc_func + drawBoxCastNonAlloc_func + Encapsulated in a function: Draw a BoxCastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn BoxCastNonAlloc + WithThisName + + + +
+ + +
+ drawCapsuleCast_outInfo_func + drawCapsuleCast_outInfo_func + Encapsulated in a function: Draw a CapsuleCast in the Unity Editor. (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCast + WithThisName + + + +
+ + +
+ drawCapsuleCast_func + drawCapsuleCast_func + Encapsulated in a function: Draw a CapsuleCast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCast + WithThisName + + + +
+ + +
+ drawCapsuleCastAll_func + drawCapsuleCastAll_func + Encapsulated in a function: Draw a CapsuleCastAll in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCastAll + WithThisName + + + +
+ + +
+ drawCapsuleCastNonAlloc_func + drawCapsuleCastNonAlloc_func + Encapsulated in a function: Draw a CapsuleCastNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CapsuleCastNonAlloc + WithThisName + + + +
+ + +
+ drawLinecast_outInfo_func + drawLinecast_outInfo_func + Encapsulated in a function: Draw a Linecast in the Unity Editor. (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Linecast + WithThisName + + + +
+ + +
+ drawLinecast_func + drawLinecast_func + Encapsulated in a function: Draw a Linecast in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Linecast + WithThisName + + + +
+ + +
+ drawRaycast_ray_outInfo_func + drawRaycast_ray_outInfo_func + Encapsulated in a function: Draw a Raycast in the Unity Editor. (direction defined by ray struct) (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + WithThisName + + + +
+ + +
+ drawRaycast_ray_func + drawRaycast_ray_func + Encapsulated in a function: Draw a Raycast in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + WithThisName + + + +
+ + +
+ drawRaycast_vec_outInfo_func + drawRaycast_vec_outInfo_func + Encapsulated in a function: Draw a Raycast in the Unity Editor. (direction defined by vectors) (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + WithThisName + + + +
+ + +
+ drawRaycast_vec_func + drawRaycast_vec_func + Encapsulated in a function: Draw a Raycast in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Raycast + WithThisName + + + +
+ + +
+ drawRaycastAll_vec_func + drawRaycastAll_vec_func + Encapsulated in a function: Draw a RaycastAll in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastAll + WithThisName + + + +
+ + +
+ drawRaycastAll_ray_func + drawRaycastAll_ray_func + Encapsulated in a function: Draw a RaycastAll in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastAll + WithThisName + + + +
+ + +
+ drawRaycastNonAlloc_ray_func + drawRaycastNonAlloc_ray_func + Encapsulated in a function: Draw a RaycastNonAlloc in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastNonAlloc + WithThisName + + + +
+ + +
+ drawRaycastNonAlloc_vec_func + drawRaycastNonAlloc_vec_func + Encapsulated in a function: Draw a RaycastNonAlloc in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RaycastNonAlloc + WithThisName + + + +
+ + +
+ drawSphereCast_ray_func + drawSphereCast_ray_func + Encapsulated in a function: Draw a SphereCast in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCast + WithThisName + + + +
+ + +
+ drawSphereCast_ray_outInfo_func + drawSphereCast_ray_outInfo_func + Encapsulated in a function: Draw a SphereCast in the Unity Editor. (direction defined by ray struct) (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCast + WithThisName + + + +
+ + +
+ drawSphereCast_vec_func + drawSphereCast_vec_func + Encapsulated in a function: Draw a SphereCast in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCast + WithThisName + + + +
+ + +
+ drawSphereCast_vec_outInfo_func + drawSphereCast_vec_outInfo_func + Encapsulated in a function: Draw a SphereCast in the Unity Editor. (direction defined by vectors) (with 'out' paramter that supplies 'RaycastHit hitInfo') + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCast + WithThisName + + + +
+ + +
+ drawSphereCastAll_ray_func + drawSphereCastAll_ray_func + Encapsulated in a function: Draw a SphereCastAll in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCastAll + WithThisName + + + +
+ + +
+ drawSphereCastAll_vec_func + drawSphereCastAll_vec_func + Encapsulated in a function: Draw a SphereCastAll in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCastAll + WithThisName + + + +
+ + +
+ drawSphereCastNonAlloc_ray_func + drawSphereCastNonAlloc_ray_func + Encapsulated in a function: Draw a SphereCastNonAlloc in the Unity Editor. (direction defined by ray struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCastNonAlloc + WithThisName + + + +
+ + +
+ drawSphereCastNonAlloc_vec_func + drawSphereCastNonAlloc_vec_func + Encapsulated in a function: Draw a SphereCastNonAlloc in the Unity Editor. (direction defined by vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn SphereCastNonAlloc + WithThisName + + + +
+ + +
+ drawCheckBox_func + drawCheckBox_func + Encapsulated in a function: Draw CheckBox in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CheckBox + WithThisName + + + +
+ + +
+ drawCheckCapsule_func + drawCheckCapsule_func + Encapsulated in a function: Draw CheckCapsule in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CheckCapsule + WithThisName + + + +
+ + +
+ drawCheckSphere_func + drawCheckSphere_func + Encapsulated in a function: Draw CheckSphere in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CheckSphere + WithThisName + + + +
+ + +
+ drawOverlapBox_func + drawOverlapBox_func + Encapsulated in a function: Draw OverlapBox in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBox + WithThisName + + + +
+ + +
+ drawOverlapBoxNonAlloc_func + drawOverlapBoxNonAlloc_func + Encapsulated in a function: Draw OverlapBoxNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapBoxNonAlloc + WithThisName + + + +
+ + +
+ drawOverlapCapsule_func + drawOverlapCapsule_func + Encapsulated in a function: Draw OverlapCapsule in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsule + WithThisName + + + +
+ + +
+ drawOverlapCapsuleNonAlloc_func + drawOverlapCapsuleNonAlloc_func + Encapsulated in a function: Draw OverlapCapsuleNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapCapsuleNonAlloc + WithThisName + + + +
+ + +
+ drawOverlapSphere_func + drawOverlapSphere_func + Encapsulated in a function: Draw OverlapSphere in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapSphere + WithThisName + + + +
+ + +
+ drawOverlapSphereNonAlloc_func + drawOverlapSphereNonAlloc_func + Encapsulated in a function: Draw OverlapSphereNonAlloc in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn OverlapSphereNonAlloc + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawPhysics_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawPhysics_func.snippet.meta new file mode 100644 index 0000000..c44f1a0 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawPhysics_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c973f2196d11ebe41905edc3f753c737 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawScreenspace.snippet b/Editor/DrawDebugLibrary/code snippets/drawScreenspace.snippet new file mode 100644 index 0000000..af55476 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawScreenspace.snippet @@ -0,0 +1,4335 @@ + + + +
+ drawScreenLine + drawScreenLine + Draw a ScreenLine in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLine + screenLine + + + +
+ + +
+ drawScreenLine_cam + drawScreenLine_cam + Draw a ScreenLine in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLine + screenLine + + + +
+ + +
+ drawScreenRay + drawScreenRay + Draw a ScreenRay in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRay + screenRay + + + +
+ + +
+ drawScreenRay_cam + drawScreenRay_cam + Draw a ScreenRay in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRay + screenRay + + + +
+ + +
+ drawScreenLineFrom + drawScreenLineFrom + Draw a ScreenLineFrom in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineFrom + screenLineFrom + + + +
+ + +
+ drawScreenLineFrom_cam + drawScreenLineFrom_cam + Draw a ScreenLineFrom in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineFrom + screenLineFrom + + + +
+ + +
+ drawScreenLineTo + drawScreenLineTo + Draw a ScreenLineTo in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineTo + screenLineTo + + + +
+ + +
+ drawScreenLineTo_cam + drawScreenLineTo_cam + Draw a ScreenLineTo in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineTo + screenLineTo + + + +
+ + +
+ drawScreenLineColFade + drawScreenLineColFade + Draw a ScreenLineColFade in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineColFade + screenLineColFade + + + +
+ + +
+ drawScreenLineColFade_cam + drawScreenLineColFade_cam + Draw a ScreenLineColFade in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineColFade + screenLineColFade + + + +
+ + +
+ drawScreenRayColFade + drawScreenRayColFade + Draw a ScreenRayColFade in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayColFade + screenRayColFade + + + +
+ + +
+ drawScreenRayColFade_cam + drawScreenRayColFade_cam + Draw a ScreenRayColFade in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayColFade + screenRayColFade + + + +
+ + +
+ drawScreenLineFromColFade + drawScreenLineFromColFade + Draw a ScreenLineFromColFade in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineFromColFade + screenLineFromColFade + + + +
+ + +
+ drawScreenLineFromColFade_cam + drawScreenLineFromColFade_cam + Draw a ScreenLineFromColFade in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineFromColFade + screenLineFromColFade + + + +
+ + +
+ drawScreenLineToColFade + drawScreenLineToColFade + Draw a ScreenLineToColFade in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineToColFade + screenLineToColFade + + + +
+ + +
+ drawScreenLineToColFade_cam + drawScreenLineToColFade_cam + Draw a ScreenLineToColFade in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineToColFade + screenLineToColFade + + + +
+ + +
+ drawScreenLineCircled_angleToAngle + drawScreenLineCircled_angleToAngle + Draw a ScreenLineCircled in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineCircled + screenLineCircled + + + +
+ + +
+ drawScreenLineCircled_angleToAngle_cam + drawScreenLineCircled_angleToAngle_cam + Draw a ScreenLineCircled in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineCircled + screenLineCircled + + + +
+ + +
+ drawScreenLineCircled_angleFromStartPos + drawScreenLineCircled_angleFromStartPos + Draw a ScreenLineCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineCircled + screenLineCircled + + + +
+ + +
+ drawScreenLineCircled_angleFromStartPos_cam + drawScreenLineCircled_angleFromStartPos_cam + Draw a ScreenLineCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineCircled + screenLineCircled + + + +
+ + +
+ drawScreenCircleSegment_angleToAngle + drawScreenCircleSegment_angleToAngle + Draw a ScreenCircleSegment in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircleSegment + screenCircleSegment + + + +
+ + +
+ drawScreenCircleSegment_angleToAngle_cam + drawScreenCircleSegment_angleToAngle_cam + Draw a ScreenCircleSegment in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircleSegment + screenCircleSegment + + + +
+ + +
+ drawScreenCircleSegment_angleFromStartPos + drawScreenCircleSegment_angleFromStartPos + Draw a ScreenCircleSegment in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircleSegment + screenCircleSegment + + + +
+ + +
+ drawScreenCircleSegment_angleFromStartPos_cam + drawScreenCircleSegment_angleFromStartPos_cam + Draw a ScreenCircleSegment in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircleSegment + screenCircleSegment + + + +
+ + +
+ drawScreenLineString_array + drawScreenLineString_array + Draw a ScreenLineString in the Unity Editor. (points defined via array) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineString + screenLineString + + + +
+ + +
+ drawScreenLineString_array_cam + drawScreenLineString_array_cam + Draw a ScreenLineString in the Unity Editor. (points defined via array) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineString + screenLineString + + + +
+ + +
+ drawScreenLineString_list + drawScreenLineString_list + Draw a ScreenLineString in the Unity Editor. (points defined via list) (automatic detection of target camera) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + bool closeGapBetweenLastAndFirstPoint_of_$name$ = false; + float width_relToViewportHeight_of_$name$ = 0.0f; + string text_of_$name$ = null; + bool drawPointerIfOffscreen_of_$name$ = false; + DrawBasics.LineStyle style_of_$name$ = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor_of_$name$ = 1.0f; + float durationInSec_of_$name$ = 0.0f; + DrawScreenspace.LineString(points_of_$name$, color_of_$name$, closeGapBetweenLastAndFirstPoint_of_$name$, width_relToViewportHeight_of_$name$, text_of_$name$, drawPointerIfOffscreen_of_$name$, style_of_$name$, stylePatternScaleFactor_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenLineString + screenLineString + + + +
+ + +
+ drawScreenLineString_list_cam + drawScreenLineString_list_cam + Draw a ScreenLineString in the Unity Editor. (points defined via list) (explicitly defining the target camera) + Draw XXL +
+ + + points_of_$name$ = ; + Color color_of_$name$ = default(Color); + bool closeGapBetweenLastAndFirstPoint_of_$name$ = false; + float width_relToViewportHeight_of_$name$ = 0.0f; + string text_of_$name$ = null; + bool drawPointerIfOffscreen_of_$name$ = false; + DrawBasics.LineStyle style_of_$name$ = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor_of_$name$ = 1.0f; + float durationInSec_of_$name$ = 0.0f; + DrawScreenspace.LineString(targetCamera_of_$name$, points_of_$name$, color_of_$name$, closeGapBetweenLastAndFirstPoint_of_$name$, width_relToViewportHeight_of_$name$, text_of_$name$, drawPointerIfOffscreen_of_$name$, style_of_$name$, stylePatternScaleFactor_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenLineString + screenLineString + + + +
+ + +
+ drawScreenLineStringColFade_array + drawScreenLineStringColFade_array + Draw a ScreenLineStringColFade in the Unity Editor. (points defined via array) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineStringColFade + screenLineStringColFade + + + +
+ + +
+ drawScreenLineStringColFade_array_cam + drawScreenLineStringColFade_array_cam + Draw a ScreenLineStringColFade in the Unity Editor. (points defined via array) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineStringColFade + screenLineStringColFade + + + +
+ + +
+ drawScreenLineStringColFade_list + drawScreenLineStringColFade_list + Draw a ScreenLineStringColFade in the Unity Editor. (points defined via list) (automatic detection of target camera) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color startColor_of_$name$ = ; + Color endColor_of_$name$ = ; + bool closeGapBetweenLastAndFirstPoint_of_$name$ = false; + float width_relToViewportHeight_of_$name$ = 0.0f; + string text_of_$name$ = null; + bool drawPointerIfOffscreen_of_$name$ = false; + DrawBasics.LineStyle style_of_$name$ = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor_of_$name$ = 1.0f; + float durationInSec_of_$name$ = 0.0f; + DrawScreenspace.LineStringColorFade(points_of_$name$, startColor_of_$name$, endColor_of_$name$, closeGapBetweenLastAndFirstPoint_of_$name$, width_relToViewportHeight_of_$name$, text_of_$name$, drawPointerIfOffscreen_of_$name$, style_of_$name$, stylePatternScaleFactor_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenLineStringColFade + screenLineStringColFade + + + +
+ + +
+ drawScreenLineStringColFade_list_cam + drawScreenLineStringColFade_list_cam + Draw a ScreenLineStringColFade in the Unity Editor. (points defined via list) (explicitly defining the target camera) + Draw XXL +
+ + + points_of_$name$ = ; + Color startColor_of_$name$ = ; + Color endColor_of_$name$ = ; + bool closeGapBetweenLastAndFirstPoint_of_$name$ = false; + float width_relToViewportHeight_of_$name$ = 0.0f; + string text_of_$name$ = null; + bool drawPointerIfOffscreen_of_$name$ = false; + DrawBasics.LineStyle style_of_$name$ = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor_of_$name$ = 1.0f; + float durationInSec_of_$name$ = 0.0f; + DrawScreenspace.LineStringColorFade(targetCamera_of_$name$, points_of_$name$, startColor_of_$name$, endColor_of_$name$, closeGapBetweenLastAndFirstPoint_of_$name$, width_relToViewportHeight_of_$name$, text_of_$name$, drawPointerIfOffscreen_of_$name$, style_of_$name$, stylePatternScaleFactor_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenLineStringColFade + screenLineStringColFade + + + +
+ + +
+ drawScreenShape_3Dpos + drawScreenShape_3Dpos + Draw a ScreenShape in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenShape + screenShape + + + +
+ + +
+ drawScreenShape_3Dpos_cam + drawScreenShape_3Dpos_cam + Draw a ScreenShape in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenShape + screenShape + + + +
+ + +
+ drawScreenShape_2Dpos + drawScreenShape_2Dpos + Draw a ScreenShape in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenShape + screenShape + + + +
+ + +
+ drawScreenShape_2Dpos_cam + drawScreenShape_2Dpos_cam + Draw a ScreenShape in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenShape + screenShape + + + +
+ + +
+ drawScreenRectangle_rect + drawScreenRectangle_rect + Draw a ScreenRectangle in the Unity Editor. (defined via rect struct) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRectangle + screenRectangle + + + +
+ + +
+ drawScreenRectangle_rect_cam + drawScreenRectangle_rect_cam + Draw a ScreenRectangle in the Unity Editor. (defined via rect struct) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRectangle + screenRectangle + + + +
+ + +
+ drawScreenRectangle_vecFloat + drawScreenRectangle_vecFloat + Draw a ScreenRectangle in the Unity Editor. (defined via vector and floats) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRectangle + screenRectangle + + + +
+ + +
+ drawScreenRectangle_vecFloat_cam + drawScreenRectangle_vecFloat_cam + Draw a ScreenRectangle in the Unity Editor. (defined via vector and floats) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRectangle + screenRectangle + + + +
+ + +
+ drawScreenBox_rect + drawScreenBox_rect + Draw a ScreenBox in the Unity Editor. (defined via rect struct) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + screenBox + + + +
+ + +
+ drawScreenBox_rect_cam + drawScreenBox_rect_cam + Draw a ScreenBox in the Unity Editor. (defined via rect struct) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + screenBox + + + +
+ + +
+ drawScreenBox_3Dpos_vec + drawScreenBox_3Dpos_vec + Draw a ScreenBox in the Unity Editor. (position defined in 3D worldspace) (defined via vectors) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + screenBox + + + +
+ + +
+ drawScreenBox_3Dpos_vec_cam + drawScreenBox_3Dpos_vec_cam + Draw a ScreenBox in the Unity Editor. (position defined in 3D worldspace) (defined via vectors) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + screenBox + + + +
+ + +
+ drawScreenBox_2Dpos_vec + drawScreenBox_2Dpos_vec + Draw a ScreenBox in the Unity Editor. (position defined in 2D screenspace) (defined via vectors) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + screenBox + + + +
+ + +
+ drawScreenBox_2Dpos_vec_cam + drawScreenBox_2Dpos_vec_cam + Draw a ScreenBox in the Unity Editor. (position defined in 2D screenspace) (defined via vectors) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + screenBox + + + +
+ + +
+ drawScreenCircle_rect + drawScreenCircle_rect + Draw a ScreenCircle in the Unity Editor. (defined via rect struct) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + screenCircle + + + +
+ + +
+ drawScreenCircle_rect_cam + drawScreenCircle_rect_cam + Draw a ScreenCircle in the Unity Editor. (defined via rect struct) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + screenCircle + + + +
+ + +
+ drawScreenCircle_3Dpos_vecRad + drawScreenCircle_3Dpos_vecRad + Draw a ScreenCircle in the Unity Editor. (position defined in 3D worldspace) (defined via vector and float as radius) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + screenCircle + + + +
+ + +
+ drawScreenCircle_3Dpos_vecRad_cam + drawScreenCircle_3Dpos_vecRad_cam + Draw a ScreenCircle in the Unity Editor. (position defined in 3D worldspace) (defined via vector and float as radius) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + screenCircle + + + +
+ + +
+ drawScreenCircle_2Dpos_vecRad + drawScreenCircle_2Dpos_vecRad + Draw a ScreenCircle in the Unity Editor. (position defined in 2D screenspace) (defined via vector and float as radius) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + screenCircle + + + +
+ + +
+ drawScreenCircle_2Dpos_vecRad_cam + drawScreenCircle_2Dpos_vecRad_cam + Draw a ScreenCircle in the Unity Editor. (position defined in 2D screenspace) (defined via vector and float as radius) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + screenCircle + + + +
+ + +
+ drawScreenCapsule_3Dpos_vecC1C2Pos + drawScreenCapsule_3Dpos_vecC1C2Pos + Draw a ScreenCapsule in the Unity Editor. (position defined in 3D worldspace) (defined via position of circle1 and circle2) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + screenCapsule + + + +
+ + +
+ drawScreenCapsule_3Dpos_vecC1C2Pos_cam + drawScreenCapsule_3Dpos_vecC1C2Pos_cam + Draw a ScreenCapsule in the Unity Editor. (position defined in 3D worldspace) (defined via position of circle1 and circle2) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + screenCapsule + + + +
+ + +
+ drawScreenCapsule_2Dpos_vecC1C2Pos + drawScreenCapsule_2Dpos_vecC1C2Pos + Draw a ScreenCapsule in the Unity Editor. (position defined in 2D screenspace) (defined via position of circle1 and circle2) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + screenCapsule + + + +
+ + +
+ drawScreenCapsule_2Dpos_vecC1C2Pos_cam + drawScreenCapsule_2Dpos_vecC1C2Pos_cam + Draw a ScreenCapsule in the Unity Editor. (position defined in 2D screenspace) (defined via position of circle1 and circle2) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + screenCapsule + + + +
+ + +
+ drawScreenCapsule_rect + drawScreenCapsule_rect + Draw a ScreenCapsule in the Unity Editor. (defined via rect struct) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + screenCapsule + + + +
+ + +
+ drawScreenCapsule_rect_cam + drawScreenCapsule_rect_cam + Draw a ScreenCapsule in the Unity Editor. (defined via rect struct) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + screenCapsule + + + +
+ + +
+ drawScreenCapsule_3Dpos_vecPosSize + drawScreenCapsule_3Dpos_vecPosSize + Draw a ScreenCapsule in the Unity Editor. (position defined in 3D worldspace) (defined via center position and size from vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + screenCapsule + + + +
+ + +
+ drawScreenCapsule_3Dpos_vecPosSize_cam + drawScreenCapsule_3Dpos_vecPosSize_cam + Draw a ScreenCapsule in the Unity Editor. (position defined in 3D worldspace) (defined via center position and size from vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + screenCapsule + + + +
+ + +
+ drawScreenCapsule_2Dpos_vecPosSize + drawScreenCapsule_2Dpos_vecPosSize + Draw a ScreenCapsule in the Unity Editor. (position defined in 2D screenspace) (defined via center position and size from vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + screenCapsule + + + +
+ + +
+ drawScreenCapsule_2Dpos_vecPosSize_cam + drawScreenCapsule_2Dpos_vecPosSize_cam + Draw a ScreenCapsule in the Unity Editor. (position defined in 2D screenspace) (defined via center position and size from vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + screenCapsule + + + +
+ + +
+ drawScreenPointArray + drawScreenPointArray + Draw a ScreenPointArray in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointArray + screenPointArray + + + +
+ + +
+ drawScreenPointArray_cam + drawScreenPointArray_cam + Draw a ScreenPointArray in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointArray + screenPointArray + + + +
+ + +
+ drawScreenPointList + drawScreenPointList + Draw a ScreenPointList in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + points_of_$name$ = $end$; + Color color_of_$name$ = default(Color); + float sizeOfMarkingCross_relToViewportHeight_of_$name$ = 0.1f; + float markingCrossLinesWidth_relToViewportHeight_of_$name$ = 0.0f; + bool drawCoordsAsText_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + DrawScreenspace.PointList(points_of_$name$, color_of_$name$, sizeOfMarkingCross_relToViewportHeight_of_$name$, markingCrossLinesWidth_relToViewportHeight_of_$name$, drawCoordsAsText_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenPointList + screenPointList + + + +
+ + +
+ drawScreenPointList_cam + drawScreenPointList_cam + Draw a ScreenPointList in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + points_of_$name$ = ; + Color color_of_$name$ = default(Color); + float sizeOfMarkingCross_relToViewportHeight_of_$name$ = 0.1f; + float markingCrossLinesWidth_relToViewportHeight_of_$name$ = 0.0f; + bool drawCoordsAsText_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + DrawScreenspace.PointList(targetCamera_of_$name$, points_of_$name$, color_of_$name$, sizeOfMarkingCross_relToViewportHeight_of_$name$, markingCrossLinesWidth_relToViewportHeight_of_$name$, drawCoordsAsText_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenPointList + screenPointList + + + +
+ + +
+ drawScreenPoint + drawScreenPoint + Draw a ScreenPoint in the Unity Editor. (pointMarking has raised priority) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPoint + screenPoint + + + +
+ + +
+ drawScreenPoint_cam + drawScreenPoint_cam + Draw a ScreenPoint in the Unity Editor. (pointMarking has raised priority) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPoint + screenPoint + + + +
+ + +
+ drawScreenPoint_prioText + drawScreenPoint_prioText + Draw a ScreenPoint in the Unity Editor. (text parameter has raised priority) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPoint + screenPoint + + + +
+ + +
+ drawScreenPoint_prioText_cam + drawScreenPoint_prioText_cam + Draw a ScreenPoint in the Unity Editor. (text parameter has raised priority) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPoint + screenPoint + + + +
+ + +
+ drawScreenPointTag_3Dpos + drawScreenPointTag_3Dpos + Draw a ScreenPointTag in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointTag + screenPointTag + + + +
+ + +
+ drawScreenPointTag_3Dpos_cam + drawScreenPointTag_3Dpos_cam + Draw a ScreenPointTag in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointTag + screenPointTag + + + +
+ + +
+ drawScreenPointTag_2Dpos + drawScreenPointTag_2Dpos + Draw a ScreenPointTag in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointTag + screenPointTag + + + +
+ + +
+ drawScreenPointTag_2Dpos_cam + drawScreenPointTag_2Dpos_cam + Draw a ScreenPointTag in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointTag + screenPointTag + + + +
+ + +
+ drawScreenVector + drawScreenVector + Draw a ScreenVector in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVector + screenVector + + + +
+ + +
+ drawScreenVector_cam + drawScreenVector_cam + Draw a ScreenVector in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVector + screenVector + + + +
+ + +
+ drawScreenVectorFrom + drawScreenVectorFrom + Draw a ScreenVectorFrom in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorFrom + screenVectorFrom + + + +
+ + +
+ drawScreenVectorFrom_cam + drawScreenVectorFrom_cam + Draw a ScreenVectorFrom in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorFrom + screenVectorFrom + + + +
+ + +
+ drawScreenVectorTo + drawScreenVectorTo + Draw a ScreenVectorTo in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorTo + screenVectorTo + + + +
+ + +
+ drawScreenVectorTo_cam + drawScreenVectorTo_cam + Draw a ScreenVectorTo in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorTo + screenVectorTo + + + +
+ + +
+ drawScreenVectorCircled_angleToAngle + drawScreenVectorCircled_angleToAngle + Draw a ScreenVectorCircled in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorCircled + screenVectorCircled + + + +
+ + +
+ drawScreenVectorCircled_angleToAngle_cam + drawScreenVectorCircled_angleToAngle_cam + Draw a ScreenVectorCircled in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorCircled + screenVectorCircled + + + +
+ + +
+ drawScreenVectorCircled_angleFromStartPos + drawScreenVectorCircled_angleFromStartPos + Draw a ScreenVectorCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorCircled + screenVectorCircled + + + +
+ + +
+ drawScreenVectorCircled_angleFromStartPos_cam + drawScreenVectorCircled_angleFromStartPos_cam + Draw a ScreenVectorCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorCircled + screenVectorCircled + + + +
+ + +
+ drawScreenIcon_3Dpos + drawScreenIcon_3Dpos + Draw a ScreenIcon in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenIcon + screenIcon + + + +
+ + +
+ drawScreenIcon_3Dpos_cam + drawScreenIcon_3Dpos_cam + Draw a ScreenIcon in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenIcon + screenIcon + + + +
+ + +
+ drawScreenIcon_2Dpos + drawScreenIcon_2Dpos + Draw a ScreenIcon in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenIcon + screenIcon + + + +
+ + +
+ drawScreenIcon_2Dpos_cam + drawScreenIcon_2Dpos_cam + Draw a ScreenIcon in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenIcon + screenIcon + + + +
+ + +
+ drawScreenDot_3Dpos + drawScreenDot_3Dpos + Draw a ScreenDot in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenDot + screenDot + + + +
+ + +
+ drawScreenDot_3Dpos_cam + drawScreenDot_3Dpos_cam + Draw a ScreenDot in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenDot + screenDot + + + +
+ + +
+ drawScreenDot_2Dpos + drawScreenDot_2Dpos + Draw a ScreenDot in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenDot + screenDot + + + +
+ + +
+ drawScreenDot_2Dpos_cam + drawScreenDot_2Dpos_cam + Draw a ScreenDot in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenDot + screenDot + + + +
+ + +
+ drawScreenMovingArrowsRay + drawScreenMovingArrowsRay + Draw a ScreenMovingArrowsRay in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenMovingArrowsRay + screenMovingArrowsRay + + + +
+ + +
+ drawScreenMovingArrowsRay_cam + drawScreenMovingArrowsRay_cam + Draw a ScreenMovingArrowsRay in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenMovingArrowsRay + screenMovingArrowsRay + + + +
+ + +
+ drawScreenMovingArrowsLine + drawScreenMovingArrowsLine + Draw a ScreenMovingArrowsLine in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenMovingArrowsLine + screenMovingArrowsLine + + + +
+ + +
+ drawScreenMovingArrowsLine_cam + drawScreenMovingArrowsLine_cam + Draw a ScreenMovingArrowsLine in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenMovingArrowsLine + screenMovingArrowsLine + + + +
+ + +
+ drawScreenRayWithAlternatingColors + drawScreenRayWithAlternatingColors + Draw a ScreenRayWithAlternatingColors in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayWithAlternatingColors + screenRayWithAlternatingColors + + + +
+ + +
+ drawScreenRayWithAlternatingColors_cam + drawScreenRayWithAlternatingColors_cam + Draw a ScreenRayWithAlternatingColors in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayWithAlternatingColors + screenRayWithAlternatingColors + + + +
+ + +
+ drawScreenLineWithAlternatingColors + drawScreenLineWithAlternatingColors + Draw a ScreenLineWithAlternatingColors in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineWithAlternatingColors + screenLineWithAlternatingColors + + + +
+ + +
+ drawScreenLineWithAlternatingColors_cam + drawScreenLineWithAlternatingColors_cam + Draw a ScreenLineWithAlternatingColors in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineWithAlternatingColors + screenLineWithAlternatingColors + + + +
+ + +
+ drawScreenBlinkingRay + drawScreenBlinkingRay + Draw a ScreenBlinkingRay in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBlinkingRay + screenBlinkingRay + + + +
+ + +
+ drawScreenBlinkingRay_cam + drawScreenBlinkingRay_cam + Draw a ScreenBlinkingRay in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBlinkingRay + screenBlinkingRay + + + +
+ + +
+ drawScreenBlinkingLine + drawScreenBlinkingLine + Draw a ScreenBlinkingLine in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBlinkingLine + screenBlinkingLine + + + +
+ + +
+ drawScreenBlinkingLine_cam + drawScreenBlinkingLine_cam + Draw a ScreenBlinkingLine in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBlinkingLine + screenBlinkingLine + + + +
+ + +
+ drawScreenRayUnderTension + drawScreenRayUnderTension + Draw a ScreenRayUnderTension in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayUnderTension + screenRayUnderTension + + + +
+ + +
+ drawScreenRayUnder_cam + drawScreenRayUnder_cam + Draw a ScreenRayUnder in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayUnder + screenRayUnder + + + +
+ + +
+ drawScreenLineUnder + drawScreenLineUnder + Draw a ScreenLineUnder in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineUnder + screenLineUnder + + + +
+ + +
+ drawScreenLineUnder_cam + drawScreenLineUnder_cam + Draw a ScreenLineUnder in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineUnder + screenLineUnder + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawScreenspace.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawScreenspace.snippet.meta new file mode 100644 index 0000000..aacaa4e --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawScreenspace.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 96608cce3a4b5a94cb81f51a2d6bc164 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawScreenspace_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawScreenspace_func.snippet new file mode 100644 index 0000000..1779d05 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawScreenspace_func.snippet @@ -0,0 +1,4659 @@ + + + +
+ drawScreenLine_func + drawScreenLine_func + Encapsulated in a function: Draw a ScreenLine in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLine + WithThisName + + + +
+ + +
+ drawScreenLine_cam_func + drawScreenLine_cam_func + Encapsulated in a function: Draw a ScreenLine in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLine + WithThisName + + + +
+ + +
+ drawScreenRay_func + drawScreenRay_func + Encapsulated in a function: Draw a ScreenRay in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRay + WithThisName + + + +
+ + +
+ drawScreenRay_cam_func + drawScreenRay_cam_func + Encapsulated in a function: Draw a ScreenRay in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRay + WithThisName + + + +
+ + +
+ drawScreenLineFrom_func + drawScreenLineFrom_func + Encapsulated in a function: Draw a ScreenLineFrom in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineFrom + WithThisName + + + +
+ + +
+ drawScreenLineFrom_cam_func + drawScreenLineFrom_cam_func + Encapsulated in a function: Draw a ScreenLineFrom in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineFrom + WithThisName + + + +
+ + +
+ drawScreenLineTo_func + drawScreenLineTo_func + Encapsulated in a function: Draw a ScreenLineTo in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineTo + WithThisName + + + +
+ + +
+ drawScreenLineTo_cam_func + drawScreenLineTo_cam_func + Encapsulated in a function: Draw a ScreenLineTo in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineTo + WithThisName + + + +
+ + +
+ drawScreenLineColFade_func + drawScreenLineColFade_func + Encapsulated in a function: Draw a ScreenLineColFade in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineColFade + WithThisName + + + +
+ + +
+ drawScreenLineColFade_cam_func + drawScreenLineColFade_cam_func + Encapsulated in a function: Draw a ScreenLineColFade in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineColFade + WithThisName + + + +
+ + +
+ drawScreenRayColFade_func + drawScreenRayColFade_func + Encapsulated in a function: Draw a ScreenRayColFade in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayColFade + WithThisName + + + +
+ + +
+ drawScreenRayColFade_cam_func + drawScreenRayColFade_cam_func + Encapsulated in a function: Draw a ScreenRayColFade in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayColFade + WithThisName + + + +
+ + +
+ drawScreenLineFromColFade_func + drawScreenLineFromColFade_func + Encapsulated in a function: Draw a ScreenLineFromColFade in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineFromColFade + WithThisName + + + +
+ + +
+ drawScreenLineFromColFade_cam_func + drawScreenLineFromColFade_cam_func + Encapsulated in a function: Draw a ScreenLineFromColFade in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineFromColFade + WithThisName + + + +
+ + +
+ drawScreenLineToColFade_func + drawScreenLineToColFade_func + Encapsulated in a function: Draw a ScreenLineToColFade in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineToColFade + WithThisName + + + +
+ + +
+ drawScreenLineToColFade_cam_func + drawScreenLineToColFade_cam_func + Encapsulated in a function: Draw a ScreenLineToColFade in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineToColFade + WithThisName + + + +
+ + +
+ drawScreenLineCircled_angleToAngle_func + drawScreenLineCircled_angleToAngle_func + Encapsulated in a function: Draw a ScreenLineCircled in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineCircled + WithThisName + + + +
+ + +
+ drawScreenLineCircled_angleToAngle_cam_func + drawScreenLineCircled_angleToAngle_cam_func + Encapsulated in a function: Draw a ScreenLineCircled in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineCircled + WithThisName + + + +
+ + +
+ drawScreenLineCircled_angleFromStartPos_func + drawScreenLineCircled_angleFromStartPos_func + Encapsulated in a function: Draw a ScreenLineCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineCircled + WithThisName + + + +
+ + +
+ drawScreenLineCircled_angleFromStartPos_cam_func + drawScreenLineCircled_angleFromStartPos_cam_func + Encapsulated in a function: Draw a ScreenLineCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineCircled + WithThisName + + + +
+ + +
+ drawScreenCircleSegment_angleToAngle_func + drawScreenCircleSegment_angleToAngle_func + Encapsulated in a function: Draw a ScreenCircleSegment in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircleSegment + WithThisName + + + +
+ + +
+ drawScreenCircleSegment_angleToAngle_cam_func + drawScreenCircleSegment_angleToAngle_cam_func + Encapsulated in a function: Draw a ScreenCircleSegment in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircleSegment + WithThisName + + + +
+ + +
+ drawScreenCircleSegment_angleFromStartPos_func + drawScreenCircleSegment_angleFromStartPos_func + Encapsulated in a function: Draw a ScreenCircleSegment in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircleSegment + WithThisName + + + +
+ + +
+ drawScreenCircleSegment_angleFromStartPos_cam_func + drawScreenCircleSegment_angleFromStartPos_cam_func + Encapsulated in a function: Draw a ScreenCircleSegment in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircleSegment + WithThisName + + + +
+ + +
+ drawScreenLineString_array_func + drawScreenLineString_array_func + Encapsulated in a function: Draw a ScreenLineString in the Unity Editor. (points defined via array) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineString + WithThisName + + + +
+ + +
+ drawScreenLineString_array_cam_func + drawScreenLineString_array_cam_func + Encapsulated in a function: Draw a ScreenLineString in the Unity Editor. (points defined via array) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineString + WithThisName + + + +
+ + +
+ drawScreenLineString_list_func + drawScreenLineString_list_func + Encapsulated in a function: Draw a ScreenLineString in the Unity Editor. (points defined via list) (automatic detection of target camera) + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + bool closeGapBetweenLastAndFirstPoint = false; + float width_relToViewportHeight = 0.0f; + string text = null; + bool drawPointerIfOffscreen = false; + DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor = 1.0f; + float durationInSec = 0.0f; + DrawScreenspace.LineString(points, color, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenLineString + WithThisName + + + +
+ + +
+ drawScreenLineString_list_cam_func + drawScreenLineString_list_cam_func + Encapsulated in a function: Draw a ScreenLineString in the Unity Editor. (points defined via list) (explicitly defining the target camera) + Draw XXL +
+ + + points = ; + Color color = default(Color); + bool closeGapBetweenLastAndFirstPoint = false; + float width_relToViewportHeight = 0.0f; + string text = null; + bool drawPointerIfOffscreen = false; + DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor = 1.0f; + float durationInSec = 0.0f; + DrawScreenspace.LineString(targetCamera, points, color, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenLineString + WithThisName + + + +
+ + +
+ drawScreenLineStringColFade_array_func + drawScreenLineStringColFade_array_func + Encapsulated in a function: Draw a ScreenLineStringColFade in the Unity Editor. (points defined via array) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineStringColFade + WithThisName + + + +
+ + +
+ drawScreenLineStringColFade_array_cam_func + drawScreenLineStringColFade_array_cam_func + Encapsulated in a function: Draw a ScreenLineStringColFade in the Unity Editor. (points defined via array) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineStringColFade + WithThisName + + + +
+ + +
+ drawScreenLineStringColFade_list_func + drawScreenLineStringColFade_list_func + Encapsulated in a function: Draw a ScreenLineStringColFade in the Unity Editor. (points defined via list) (automatic detection of target camera) + Draw XXL +
+ + + points = $end$; + Color startColor = ; + Color endColor = ; + bool closeGapBetweenLastAndFirstPoint = false; + float width_relToViewportHeight = 0.0f; + string text = null; + bool drawPointerIfOffscreen = false; + DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor = 1.0f; + float durationInSec = 0.0f; + DrawScreenspace.LineStringColorFade(points, startColor, endColor, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenLineStringColFade + WithThisName + + + +
+ + +
+ drawScreenLineStringColFade_list_cam_func + drawScreenLineStringColFade_list_cam_func + Encapsulated in a function: Draw a ScreenLineStringColFade in the Unity Editor. (points defined via list) (explicitly defining the target camera) + Draw XXL +
+ + + points = ; + Color startColor = ; + Color endColor = ; + bool closeGapBetweenLastAndFirstPoint = false; + float width_relToViewportHeight = 0.0f; + string text = null; + bool drawPointerIfOffscreen = false; + DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + float stylePatternScaleFactor = 1.0f; + float durationInSec = 0.0f; + DrawScreenspace.LineStringColorFade(targetCamera, points, startColor, endColor, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenLineStringColFade + WithThisName + + + +
+ + +
+ drawScreenShape_3Dpos_func + drawScreenShape_3Dpos_func + Encapsulated in a function: Draw a ScreenShape in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenShape + WithThisName + + + +
+ + +
+ drawScreenShape_3Dpos_cam_func + drawScreenShape_3Dpos_cam_func + Encapsulated in a function: Draw a ScreenShape in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenShape + WithThisName + + + +
+ + +
+ drawScreenShape_2Dpos_func + drawScreenShape_2Dpos_func + Encapsulated in a function: Draw a ScreenShape in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenShape + WithThisName + + + +
+ + +
+ drawScreenShape_2Dpos_cam_func + drawScreenShape_2Dpos_cam_func + Encapsulated in a function: Draw a ScreenShape in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenShape + WithThisName + + + +
+ + +
+ drawScreenRectangle_rect_func + drawScreenRectangle_rect_func + Encapsulated in a function: Draw a ScreenRectangle in the Unity Editor. (defined via rect struct) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRectangle + WithThisName + + + +
+ + +
+ drawScreenRectangle_rect_cam_func + drawScreenRectangle_rect_cam_func + Encapsulated in a function: Draw a ScreenRectangle in the Unity Editor. (defined via rect struct) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRectangle + WithThisName + + + +
+ + +
+ drawScreenRectangle_vecFloat_func + drawScreenRectangle_vecFloat_func + Encapsulated in a function: Draw a ScreenRectangle in the Unity Editor. (defined via vector and floats) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRectangle + WithThisName + + + +
+ + +
+ drawScreenRectangle_vecFloat_cam_func + drawScreenRectangle_vecFloat_cam_func + Encapsulated in a function: Draw a ScreenRectangle in the Unity Editor. (defined via vector and floats) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRectangle + WithThisName + + + +
+ + +
+ drawScreenBox_rect_func + drawScreenBox_rect_func + Encapsulated in a function: Draw a ScreenBox in the Unity Editor. (defined via rect struct) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + WithThisName + + + +
+ + +
+ drawScreenBox_rect_cam_func + drawScreenBox_rect_cam_func + Encapsulated in a function: Draw a ScreenBox in the Unity Editor. (defined via rect struct) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + WithThisName + + + +
+ + +
+ drawScreenBox_3Dpos_vec_func + drawScreenBox_3Dpos_vec_func + Encapsulated in a function: Draw a ScreenBox in the Unity Editor. (position defined in 3D worldspace) (defined via vectors) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + WithThisName + + + +
+ + +
+ drawScreenBox_3Dpos_vec_cam_func + drawScreenBox_3Dpos_vec_cam_func + Encapsulated in a function: Draw a ScreenBox in the Unity Editor. (position defined in 3D worldspace) (defined via vectors) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + WithThisName + + + +
+ + +
+ drawScreenBox_2Dpos_vec_func + drawScreenBox_2Dpos_vec_func + Encapsulated in a function: Draw a ScreenBox in the Unity Editor. (position defined in 2D screenspace) (defined via vectors) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + WithThisName + + + +
+ + +
+ drawScreenBox_2Dpos_vec_cam_func + drawScreenBox_2Dpos_vec_cam_func + Encapsulated in a function: Draw a ScreenBox in the Unity Editor. (position defined in 2D screenspace) (defined via vectors) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBox + WithThisName + + + +
+ + +
+ drawScreenCircle_rect_func + drawScreenCircle_rect_func + Encapsulated in a function: Draw a ScreenCircle in the Unity Editor. (defined via rect struct) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + WithThisName + + + +
+ + +
+ drawScreenCircle_rect_cam_func + drawScreenCircle_rect_cam_func + Encapsulated in a function: Draw a ScreenCircle in the Unity Editor. (defined via rect struct) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + WithThisName + + + +
+ + +
+ drawScreenCircle_3Dpos_vecRad_func + drawScreenCircle_3Dpos_vecRad_func + Encapsulated in a function: Draw a ScreenCircle in the Unity Editor. (position defined in 3D worldspace) (defined via vector and float as radius) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + WithThisName + + + +
+ + +
+ drawScreenCircle_3Dpos_vecRad_cam_func + drawScreenCircle_3Dpos_vecRad_cam_func + Encapsulated in a function: Draw a ScreenCircle in the Unity Editor. (position defined in 3D worldspace) (defined via vector and float as radius) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + WithThisName + + + +
+ + +
+ drawScreenCircle_2Dpos_vecRad_func + drawScreenCircle_2Dpos_vecRad_func + Encapsulated in a function: Draw a ScreenCircle in the Unity Editor. (position defined in 2D screenspace) (defined via vector and float as radius) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + WithThisName + + + +
+ + +
+ drawScreenCircle_2Dpos_vecRad_cam_func + drawScreenCircle_2Dpos_vecRad_cam_func + Encapsulated in a function: Draw a ScreenCircle in the Unity Editor. (position defined in 2D screenspace) (defined via vector and float as radius) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCircle + WithThisName + + + +
+ + +
+ drawScreenCapsule_3Dpos_vecC1C2Pos_func + drawScreenCapsule_3Dpos_vecC1C2Pos_func + Encapsulated in a function: Draw a ScreenCapsule in the Unity Editor. (position defined in 3D worldspace) (defined via position of circle1 and circle2) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + WithThisName + + + +
+ + +
+ drawScreenCapsule_3Dpos_vecC1C2Pos_cam_func + drawScreenCapsule_3Dpos_vecC1C2Pos_cam_func + Encapsulated in a function: Draw a ScreenCapsule in the Unity Editor. (position defined in 3D worldspace) (defined via position of circle1 and circle2) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + WithThisName + + + +
+ + +
+ drawScreenCapsule_2Dpos_vecC1C2Pos_func + drawScreenCapsule_2Dpos_vecC1C2Pos_func + Encapsulated in a function: Draw a ScreenCapsule in the Unity Editor. (position defined in 2D screenspace) (defined via position of circle1 and circle2) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + WithThisName + + + +
+ + +
+ drawScreenCapsule_2Dpos_vecC1C2Pos_cam_func + drawScreenCapsule_2Dpos_vecC1C2Pos_cam_func + Encapsulated in a function: Draw a ScreenCapsule in the Unity Editor. (position defined in 2D screenspace) (defined via position of circle1 and circle2) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + WithThisName + + + +
+ + +
+ drawScreenCapsule_rect_func + drawScreenCapsule_rect_func + Encapsulated in a function: Draw a ScreenCapsule in the Unity Editor. (defined via rect struct) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + WithThisName + + + +
+ + +
+ drawScreenCapsule_rect_cam_func + drawScreenCapsule_rect_cam_func + Encapsulated in a function: Draw a ScreenCapsule in the Unity Editor. (defined via rect struct) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + WithThisName + + + +
+ + +
+ drawScreenCapsule_3Dpos_vecPosSize_func + drawScreenCapsule_3Dpos_vecPosSize_func + Encapsulated in a function: Draw a ScreenCapsule in the Unity Editor. (position defined in 3D worldspace) (defined via center position and size from vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + WithThisName + + + +
+ + +
+ drawScreenCapsule_3Dpos_vecPosSize_cam_func + drawScreenCapsule_3Dpos_vecPosSize_cam_func + Encapsulated in a function: Draw a ScreenCapsule in the Unity Editor. (position defined in 3D worldspace) (defined via center position and size from vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + WithThisName + + + +
+ + +
+ drawScreenCapsule_2Dpos_vecPosSize_func + drawScreenCapsule_2Dpos_vecPosSize_func + Encapsulated in a function: Draw a ScreenCapsule in the Unity Editor. (position defined in 2D screenspace) (defined via center position and size from vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + WithThisName + + + +
+ + +
+ drawScreenCapsule_2Dpos_vecPosSize_cam_func + drawScreenCapsule_2Dpos_vecPosSize_cam_func + Encapsulated in a function: Draw a ScreenCapsule in the Unity Editor. (position defined in 2D screenspace) (defined via center position and size from vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenCapsule + WithThisName + + + +
+ + +
+ drawScreenPointArray_func + drawScreenPointArray_func + Encapsulated in a function: Draw a ScreenPointArray in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointArray + WithThisName + + + +
+ + +
+ drawScreenPointArray_cam_func + drawScreenPointArray_cam_func + Encapsulated in a function: Draw a ScreenPointArray in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointArray + WithThisName + + + +
+ + +
+ drawScreenPointList_func + drawScreenPointList_func + Encapsulated in a function: Draw a ScreenPointList in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + points = $end$; + Color color = default(Color); + float sizeOfMarkingCross_relToViewportHeight = 0.1f; + float markingCrossLinesWidth_relToViewportHeight = 0.0f; + bool drawCoordsAsText = true; + float durationInSec = 0.0f; + DrawScreenspace.PointList(points, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, drawCoordsAsText, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenPointList + WithThisName + + + +
+ + +
+ drawScreenPointList_cam_func + drawScreenPointList_cam_func + Encapsulated in a function: Draw a ScreenPointList in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + points = ; + Color color = default(Color); + float sizeOfMarkingCross_relToViewportHeight = 0.1f; + float markingCrossLinesWidth_relToViewportHeight = 0.0f; + bool drawCoordsAsText = true; + float durationInSec = 0.0f; + DrawScreenspace.PointList(targetCamera, points, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, drawCoordsAsText, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ScreenPointList + WithThisName + + + +
+ + +
+ drawScreenPoint_func + drawScreenPoint_func + Encapsulated in a function: Draw a ScreenPoint in the Unity Editor. (pointMarking has raised priority) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPoint + WithThisName + + + +
+ + +
+ drawScreenPoint_cam_func + drawScreenPoint_cam_func + Encapsulated in a function: Draw a ScreenPoint in the Unity Editor. (pointMarking has raised priority) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPoint + WithThisName + + + +
+ + +
+ drawScreenPoint_prioText_func + drawScreenPoint_prioText_func + Encapsulated in a function: Draw a ScreenPoint in the Unity Editor. (text parameter has raised priority) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPoint + WithThisName + + + +
+ + +
+ drawScreenPoint_prioText_cam_func + drawScreenPoint_prioText_cam_func + Encapsulated in a function: Draw a ScreenPoint in the Unity Editor. (text parameter has raised priority) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPoint + WithThisName + + + +
+ + +
+ drawScreenPointTag_3Dpos_func + drawScreenPointTag_3Dpos_func + Encapsulated in a function: Draw a ScreenPointTag in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointTag + WithThisName + + + +
+ + +
+ drawScreenPointTag_3Dpos_cam_func + drawScreenPointTag_3Dpos_cam_func + Encapsulated in a function: Draw a ScreenPointTag in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointTag + WithThisName + + + +
+ + +
+ drawScreenPointTag_2Dpos_func + drawScreenPointTag_2Dpos_func + Encapsulated in a function: Draw a ScreenPointTag in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointTag + WithThisName + + + +
+ + +
+ drawScreenPointTag_2Dpos_cam_func + drawScreenPointTag_2Dpos_cam_func + Encapsulated in a function: Draw a ScreenPointTag in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenPointTag + WithThisName + + + +
+ + +
+ drawScreenVector_func + drawScreenVector_func + Encapsulated in a function: Draw a ScreenVector in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVector + WithThisName + + + +
+ + +
+ drawScreenVector_cam_func + drawScreenVector_cam_func + Encapsulated in a function: Draw a ScreenVector in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVector + WithThisName + + + +
+ + +
+ drawScreenVectorFrom_func + drawScreenVectorFrom_func + Encapsulated in a function: Draw a ScreenVectorFrom in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorFrom + WithThisName + + + +
+ + +
+ drawScreenVectorFrom_cam_func + drawScreenVectorFrom_cam_func + Encapsulated in a function: Draw a ScreenVectorFrom in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorFrom + WithThisName + + + +
+ + +
+ drawScreenVectorTo_func + drawScreenVectorTo_func + Encapsulated in a function: Draw a ScreenVectorTo in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorTo + WithThisName + + + +
+ + +
+ drawScreenVectorTo_cam_func + drawScreenVectorTo_cam_func + Encapsulated in a function: Draw a ScreenVectorTo in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorTo + WithThisName + + + +
+ + +
+ drawScreenVectorCircled_angleToAngle_func + drawScreenVectorCircled_angleToAngle_func + Encapsulated in a function: Draw a ScreenVectorCircled in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorCircled + WithThisName + + + +
+ + +
+ drawScreenVectorCircled_angleToAngle_cam_func + drawScreenVectorCircled_angleToAngle_cam_func + Encapsulated in a function: Draw a ScreenVectorCircled in the Unity Editor. (turnCenter defined as position, angles relative to screens upwardDir) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorCircled + WithThisName + + + +
+ + +
+ drawScreenVectorCircled_angleFromStartPos_func + drawScreenVectorCircled_angleFromStartPos_func + Encapsulated in a function: Draw a ScreenVectorCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorCircled + WithThisName + + + +
+ + +
+ drawScreenVectorCircled_angleFromStartPos_cam_func + drawScreenVectorCircled_angleFromStartPos_cam_func + Encapsulated in a function: Draw a ScreenVectorCircled in the Unity Editor. (turnCenter and startPosition defined as positions, angle as float) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenVectorCircled + WithThisName + + + +
+ + +
+ drawScreenIcon_3Dpos_func + drawScreenIcon_3Dpos_func + Encapsulated in a function: Draw a ScreenIcon in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenIcon + WithThisName + + + +
+ + +
+ drawScreenIcon_3Dpos_cam_func + drawScreenIcon_3Dpos_cam_func + Encapsulated in a function: Draw a ScreenIcon in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenIcon + WithThisName + + + +
+ + +
+ drawScreenIcon_2Dpos_func + drawScreenIcon_2Dpos_func + Encapsulated in a function: Draw a ScreenIcon in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenIcon + WithThisName + + + +
+ + +
+ drawScreenIcon_2Dpos_cam_func + drawScreenIcon_2Dpos_cam_func + Encapsulated in a function: Draw a ScreenIcon in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenIcon + WithThisName + + + +
+ + +
+ drawScreenDot_3Dpos_func + drawScreenDot_3Dpos_func + Encapsulated in a function: Draw a ScreenDot in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenDot + WithThisName + + + +
+ + +
+ drawScreenDot_3Dpos_cam_func + drawScreenDot_3Dpos_cam_func + Encapsulated in a function: Draw a ScreenDot in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenDot + WithThisName + + + +
+ + +
+ drawScreenDot_2Dpos_func + drawScreenDot_2Dpos_func + Encapsulated in a function: Draw a ScreenDot in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenDot + WithThisName + + + +
+ + +
+ drawScreenDot_2Dpos_cam_func + drawScreenDot_2Dpos_cam_func + Encapsulated in a function: Draw a ScreenDot in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenDot + WithThisName + + + +
+ + +
+ drawScreenMovingArrowsRay_func + drawScreenMovingArrowsRay_func + Encapsulated in a function: Draw a ScreenMovingArrowsRay in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenMovingArrowsRay + WithThisName + + + +
+ + +
+ drawScreenMovingArrowsRay_cam_func + drawScreenMovingArrowsRay_cam_func + Encapsulated in a function: Draw a ScreenMovingArrowsRay in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenMovingArrowsRay + WithThisName + + + +
+ + +
+ drawScreenMovingArrowsLine_func + drawScreenMovingArrowsLine_func + Encapsulated in a function: Draw a ScreenMovingArrowsLine in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenMovingArrowsLine + WithThisName + + + +
+ + +
+ drawScreenMovingArrowsLine_cam_func + drawScreenMovingArrowsLine_cam_func + Encapsulated in a function: Draw a ScreenMovingArrowsLine in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenMovingArrowsLine + WithThisName + + + +
+ + +
+ drawScreenRayWithAlternatingColors_func + drawScreenRayWithAlternatingColors_func + Encapsulated in a function: Draw a ScreenRayWithAlternatingColors in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayWithAlternatingColors + WithThisName + + + +
+ + +
+ drawScreenRayWithAlternatingColors_cam_func + drawScreenRayWithAlternatingColors_cam_func + Encapsulated in a function: Draw a ScreenRayWithAlternatingColors in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayWithAlternatingColors + WithThisName + + + +
+ + +
+ drawScreenLineWithAlternatingColors_func + drawScreenLineWithAlternatingColors_func + Encapsulated in a function: Draw a ScreenLineWithAlternatingColors in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineWithAlternatingColors + WithThisName + + + +
+ + +
+ drawScreenLineWithAlternatingColors_cam_func + drawScreenLineWithAlternatingColors_cam_func + Encapsulated in a function: Draw a ScreenLineWithAlternatingColors in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineWithAlternatingColors + WithThisName + + + +
+ + +
+ drawScreenBlinkingRay_func + drawScreenBlinkingRay_func + Encapsulated in a function: Draw a ScreenBlinkingRay in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBlinkingRay + WithThisName + + + +
+ + +
+ drawScreenBlinkingRay_cam_func + drawScreenBlinkingRay_cam_func + Encapsulated in a function: Draw a ScreenBlinkingRay in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBlinkingRay + WithThisName + + + +
+ + +
+ drawScreenBlinkingLine_func + drawScreenBlinkingLine_func + Encapsulated in a function: Draw a ScreenBlinkingLine in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBlinkingLine + WithThisName + + + +
+ + +
+ drawScreenBlinkingLine_cam_func + drawScreenBlinkingLine_cam_func + Encapsulated in a function: Draw a ScreenBlinkingLine in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenBlinkingLine + WithThisName + + + +
+ + +
+ drawScreenRayUnderTension_func + drawScreenRayUnderTension_func + Encapsulated in a function: Draw a ScreenRayUnderTension in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayUnderTension + WithThisName + + + +
+ + +
+ drawScreenRayUnder_cam_func + drawScreenRayUnder_cam_func + Encapsulated in a function: Draw a ScreenRayUnder in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenRayUnder + WithThisName + + + +
+ + +
+ drawScreenLineUnder_func + drawScreenLineUnder_func + Encapsulated in a function: Draw a ScreenLineUnder in the Unity Editor. (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineUnder + WithThisName + + + +
+ + +
+ drawScreenLineUnder_cam_func + drawScreenLineUnder_cam_func + Encapsulated in a function: Draw a ScreenLineUnder in the Unity Editor. (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ScreenLineUnder + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawScreenspace_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawScreenspace_func.snippet.meta new file mode 100644 index 0000000..46eaaec --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawScreenspace_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 699e067d28063634783fc15a7ab9fd60 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawShapes.snippet b/Editor/DrawDebugLibrary/code snippets/drawShapes.snippet new file mode 100644 index 0000000..5c64732 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawShapes.snippet @@ -0,0 +1,4610 @@ + + + +
+ drawRegularPolygon_rotViaQuat + drawRegularPolygon_rotViaQuat + Draw a RegularPolygon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RegularPolygon + regularPolygon + + + +
+ + +
+ drawRegularPolygon_rotViaVec + drawRegularPolygon_rotViaVec + Draw a RegularPolygon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RegularPolygon + regularPolygon + + + +
+ + +
+ drawTriangle_rotViaQuat + drawTriangle_rotViaQuat + Draw a Triangle in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Triangle + triangle + + + +
+ + +
+ drawTriangle_rotViaVec + drawTriangle_rotViaVec + Draw a Triangle in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Triangle + triangle + + + +
+ + +
+ drawSquare_rotViaQuat + drawSquare_rotViaQuat + Draw a Square in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Square + square + + + +
+ + +
+ drawSquare_rotViaVec + drawSquare_rotViaVec + Draw a Square in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Square + square + + + +
+ + +
+ drawPentagon_rotViaQuat + drawPentagon_rotViaQuat + Draw a Pentagon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pentagon + pentagon + + + +
+ + +
+ drawPentagon_rotViaVec + drawPentagon_rotViaVec + Draw a Pentagon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pentagon + pentagon + + + +
+ + +
+ drawHexagon_rotViaQuat + drawHexagon_rotViaQuat + Draw a Hexagon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Hexagon + hexagon + + + +
+ + +
+ drawHexagon_rotViaVec + drawHexagon_rotViaVec + Draw a Hexagon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Hexagon + hexagon + + + +
+ + +
+ drawSeptagon_rotViaQuat + drawSeptagon_rotViaQuat + Draw a Septagon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Septagon + septagon + + + +
+ + +
+ drawSeptagon_rotViaVec + drawSeptagon_rotViaVec + Draw a Septagon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Septagon + septagon + + + +
+ + +
+ drawOctagon_rotViaQuat + drawOctagon_rotViaQuat + Draw an Octagon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Octagon + octagon + + + +
+ + +
+ drawOctagon_rotViaVec + drawOctagon_rotViaVec + Draw an Octagon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Octagon + octagon + + + +
+ + +
+ drawDecagon_rotViaQuat + drawDecagon_rotViaQuat + Draw a Decagon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Decagon + decagon + + + +
+ + +
+ drawDecagon_rotViaVec + drawDecagon_rotViaVec + Draw a Decagon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Decagon + decagon + + + +
+ + +
+ drawCircle_rotViaQuat + drawCircle_rotViaQuat + Draw a Circle in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle + circle + + + +
+ + +
+ drawCircle_rotViaVec + drawCircle_rotViaVec + Draw a Circle in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle + circle + + + +
+ + +
+ drawEllipse_rotViaQuat + drawEllipse_rotViaQuat + Draw an Ellipse in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ellipse + ellipse + + + +
+ + +
+ drawEllipse_rotViaVec + drawEllipse_rotViaVec + Draw an Ellipse in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ellipse + ellipse + + + +
+ + +
+ drawStar_rotViaQuat + drawStar_rotViaQuat + Draw a Star in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Star + star + + + +
+ + +
+ drawStar_rotViaVec + drawStar_rotViaVec + Draw a Star in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Star + star + + + +
+ + +
+ drawFlatCapsule_vecC1C2Pos + drawFlatCapsule_vecC1C2Pos + Draw a FlatCapsule in the Unity Editor. (capsule defined via position of circle1 and circle2) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatCapsule + flatCapsule + + + +
+ + +
+ drawFlatCapsule_rotViaQuat + drawFlatCapsule_rotViaQuat + Draw a FlatCapsule in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatCapsule + flatCapsule + + + +
+ + +
+ drawFlatCapsule_rotViaVec + drawFlatCapsule_rotViaVec + Draw a FlatCapsule in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatCapsule + flatCapsule + + + +
+ + +
+ drawPlane_tr + drawPlane_tr + Draw a Plane in the Unity Editor. (defined via transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Plane + plane + + + +
+ + +
+ drawPlane_pl + drawPlane_pl + Draw a Plane in the Unity Editor. (defined via plane struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Plane + plane + + + +
+ + +
+ drawPlane_vec + drawPlane_vec + Draw a Plane in the Unity Editor. (defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Plane + plane + + + +
+ + +
+ drawRhombusAroundCenter + drawRhombusAroundCenter + Draw a RhombusAroundCenter in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RhombusAroundCenter + rhombusAroundCenter + + + +
+ + +
+ drawRhombus + drawRhombus + Draw a Rhombus in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Rhombus + rhombus + + + +
+ + +
+ drawCube_tr + drawCube_tr + Draw a Cube in the Unity Editor. (defined via transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cube + cube + + + +
+ + +
+ drawCube_vecQuat + drawCube_vecQuat + Draw a Cube in the Unity Editor. pos defined via vector, rot defined via quaternion + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cube + cube + + + +
+ + +
+ drawCube_vecVec + drawCube_vecVec + Draw a Cube in the Unity Editor. both pos and rot defined via vectors + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cube + cube + + + +
+ + +
+ drawCubeFilled_tr_alpha + drawCubeFilled_tr_alpha + Draw a CubeFilled in the Unity Editor. (pos/size/rot from transform) (fill color same as strut color except lower alpha) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + cubeFilled + + + +
+ + +
+ drawCubeFilled_vecQuat_alpha + drawCubeFilled_vecQuat_alpha + Draw a CubeFilled in the Unity Editor. (pos from vector, rot from quaternion) (fill color same as strut color except lower alpha) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + cubeFilled + + + +
+ + +
+ drawCubeFilled_vecVec_alpha + drawCubeFilled_vecVec_alpha + Draw a CubeFilled in the Unity Editor. (pos/size/rot from vectors) (fill color same as strut color except lower alpha) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + cubeFilled + + + +
+ + +
+ drawCubeFilled_tr_2col + drawCubeFilled_tr_2col + Draw a CubeFilled in the Unity Editor. (pos/size/rot from transform) (fill color is different from strut color) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + cubeFilled + + + +
+ + +
+ drawCubeFilled_vecQuat_2col + drawCubeFilled_vecQuat_2col + Draw a CubeFilled in the Unity Editor. (pos from vector, rot from quaternion) (fill color is different from strut color) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + cubeFilled + + + +
+ + +
+ drawCubeFilled_vecVec_2col + drawCubeFilled_vecVec_2col + Draw a CubeFilled in the Unity Editor. (pos/size/rot from vectors) (fill color is different from strut color) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + cubeFilled + + + +
+ + +
+ drawSphere_tr + drawSphere_tr + Draw a Sphere in the Unity Editor. (pos/size/rot from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Sphere + sphere + + + +
+ + +
+ drawSphere_vecQuat + drawSphere_vecQuat + Draw a Sphere in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Sphere + sphere + + + +
+ + +
+ drawSphere_vecVec + drawSphere_vecVec + Draw a Sphere in the Unity Editor. (pos/size/rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Sphere + sphere + + + +
+ + +
+ drawEllipsoid_tr + drawEllipsoid_tr + Draw an Ellipsoid in the Unity Editor. (pos/size/rot from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ellipsoid + ellipsoid + + + +
+ + +
+ drawEllipsoid_vecQuat + drawEllipsoid_vecQuat + Draw an Ellipsoid in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ellipsoid + ellipsoid + + + +
+ + +
+ drawEllipsoid_vecVec + drawEllipsoid_vecVec + Draw an Ellipsoid in the Unity Editor. (pos/size/rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ellipsoid + ellipsoid + + + +
+ + +
+ drawEllipsoidNonUniform_vecQuat + drawEllipsoidNonUniform_vecQuat + Draw an EllipsoidNonUniform in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EllipsoidNonUniform + ellipsoidNonUniform + + + +
+ + +
+ drawEllipsoidNonUniform_vecVec + drawEllipsoidNonUniform_vecVec + Draw an EllipsoidNonUniform in the Unity Editor. (pos/rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EllipsoidNonUniform + ellipsoidNonUniform + + + +
+ + +
+ drawCapsule_vecC1C2Pos + drawCapsule_vecC1C2Pos + Draw a Capsule in the Unity Editor. (defined via position of circle1 and circle2) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + capsule + + + +
+ + +
+ drawCapsule_tr + drawCapsule_tr + Draw a Capsule in the Unity Editor. (defined via transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + capsule + + + +
+ + +
+ drawCapsule_vecVecQuat + drawCapsule_vecVecQuat + Draw a Capsule in the Unity Editor. (pos from vector, size from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + capsule + + + +
+ + +
+ drawCapsule_vecVecVec + drawCapsule_vecVecVec + Draw a Capsule in the Unity Editor. (pos/size/rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + capsule + + + +
+ + +
+ drawCapsule_vecRadQuat + drawCapsule_vecRadQuat + Draw a Capsule in the Unity Editor. (pos from vector, radius from float, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + capsule + + + +
+ + +
+ drawCapsule_vecRadVec + drawCapsule_vecRadVec + Draw a Capsule in the Unity Editor. (pos from vector, radius from float, rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + capsule + + + +
+ + +
+ drawPyramid_apexAnglesQuat + drawPyramid_apexAnglesQuat + Draw a Pyramid in the Unity Editor. (defined via apex pos and angles from there, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + pyramid + + + +
+ + +
+ drawPyramid_apexAnglesVec + drawPyramid_apexAnglesVec + Draw a Pyramid in the Unity Editor. (defined via apex pos and angles from there, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + pyramid + + + +
+ + +
+ drawPyramid_baseRectQuat + drawPyramid_baseRectQuat + Draw a Pyramid in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + pyramid + + + +
+ + +
+ drawPyramid_baseRectVec + drawPyramid_baseRectVec + Draw a Pyramid in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + pyramid + + + +
+ + +
+ drawPyramid_vecVecQuat + drawPyramid_vecVecQuat + Draw a Pyramid in the Unity Editor. (pos+size via vectors, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + pyramid + + + +
+ + +
+ drawPyramid_vecFloatQuat + drawPyramid_vecFloatQuat + Draw a Pyramid in the Unity Editor. (pos via vector, size via floats, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + pyramid + + + +
+ + +
+ drawPyramid_vecFloatVec + drawPyramid_vecFloatVec + Draw a Pyramid in the Unity Editor. (pos via vector, size via floats, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + pyramid + + + +
+ + +
+ drawCone_apexAnglesQuat + drawCone_apexAnglesQuat + Draw a Cone in the Unity Editor. (defined via apex pos and angles from there, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cone + cone + + + +
+ + +
+ drawCone_apexAnglesVec + drawCone_apexAnglesVec + Draw a Cone in the Unity Editor. (defined via apex pos and angles from there, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cone + cone + + + +
+ + +
+ drawCone_vecVecQuat + drawCone_vecVecQuat + Draw a Cone in the Unity Editor. (pos+size via vectors, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cone + cone + + + +
+ + +
+ drawCone_vecFloatQuat + drawCone_vecFloatQuat + Draw a Cone in the Unity Editor. (pos via vector, size via floats, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cone + cone + + + +
+ + +
+ drawCone_vecFloatVec + drawCone_vecFloatVec + Draw a Cone in the Unity Editor. (pos via vector, size via floats, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cone + cone + + + +
+ + +
+ drawConeFilled_apexAnglesQuat + drawConeFilled_apexAnglesQuat + Draw a ConeFilled in the Unity Editor. (defined via apex pos and angles from there, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ConeFilled + coneFilled + + + +
+ + +
+ drawConeFilled_apexAnglesVec + drawConeFilled_apexAnglesVec + Draw a ConeFilled in the Unity Editor. (defined via apex pos and angles from there, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ConeFilled + coneFilled + + + +
+ + +
+ drawConeFilled_vecVecQuat + drawConeFilled_vecVecQuat + Draw a ConeFilled in the Unity Editor. (pos+size via vectors, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ConeFilled + coneFilled + + + +
+ + +
+ drawConeFilled_vecFloatQuat + drawConeFilled_vecFloatQuat + Draw a ConeFilled in the Unity Editor. (pos via vector, size via floats, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ConeFilled + coneFilled + + + +
+ + +
+ drawConeFilled_vecFloatVec + drawConeFilled_vecFloatVec + Draw a ConeFilled in the Unity Editor. (pos via vector, size via floats, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ConeFilled + coneFilled + + + +
+ + +
+ drawBipyramid_baseRectQuat + drawBipyramid_baseRectQuat + Draw a Bipyramid in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bipyramid + bipyramid + + + +
+ + +
+ drawBipyramid_baseRectVec + drawBipyramid_baseRectVec + Draw a Bipyramid in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bipyramid + bipyramid + + + +
+ + +
+ drawBipyramid_vecVecQuat + drawBipyramid_vecVecQuat + Draw a Bipyramid in the Unity Editor. (pos+size via vectors, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bipyramid + bipyramid + + + +
+ + +
+ drawBipyramid_vecFloatQuat + drawBipyramid_vecFloatQuat + Draw a Bipyramid in the Unity Editor. (pos via vector, size via floats, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bipyramid + bipyramid + + + +
+ + +
+ drawBipyramid_vecFloatVec + drawBipyramid_vecFloatVec + Draw a Bipyramid in the Unity Editor. (pos via vector, size via floats, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bipyramid + bipyramid + + + +
+ + +
+ drawCylinder_baseRectQuat + drawCylinder_baseRectQuat + Draw a Cylinder in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cylinder + cylinder + + + +
+ + +
+ drawCylinder_baseRectVec + drawCylinder_baseRectVec + Draw a Cylinder in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cylinder + cylinder + + + +
+ + +
+ drawCylinder_vecVecQuat + drawCylinder_vecVecQuat + Draw a Cylinder in the Unity Editor. (pos+size via vectors, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cylinder + cylinder + + + +
+ + +
+ drawCylinder_vecFloatQuat + drawCylinder_vecFloatQuat + Draw a Cylinder in the Unity Editor. (pos via vector, size via floats, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cylinder + cylinder + + + +
+ + +
+ drawCylinder_vecFloatVec + drawCylinder_vecFloatVec + Draw a Cylinder in the Unity Editor. (pos via vector, size via floats, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cylinder + cylinder + + + +
+ + +
+ drawExtrusion_baseRectQuat + drawExtrusion_baseRectQuat + Draw an Extrusion in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Extrusion + extrusion + + + +
+ + +
+ drawExtrusion_baseRectVec + drawExtrusion_baseRectVec + Draw an Extrusion in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Extrusion + extrusion + + + +
+ + +
+ drawExtrusion_vecQuat + drawExtrusion_vecQuat + Draw an Extrusion in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Extrusion + extrusion + + + +
+ + +
+ drawExtrusion_vecVec + drawExtrusion_vecVec + Draw an Extrusion in the Unity Editor. (pos + rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Extrusion + extrusion + + + +
+ + +
+ drawFrustum_cam + drawFrustum_cam + Draw a Frustum in the Unity Editor. (specified via a camera component) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFrustum_apexAndAngles_rotViaQuat + drawFrustum_apexAndAngles_rotViaQuat + Draw a Frustum in the Unity Editor. (defined via apex pos and angles from there, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFrustum_apexAndAngles_rotViaVec + drawFrustum_apexAndAngles_rotViaVec + Draw a Frustum in the Unity Editor. (defined via apex pos and angles from there, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFrustum_bigClipPlaneRect_rotViaQuat + drawFrustum_bigClipPlaneRect_rotViaQuat + Draw a Frustum in the Unity Editor. (defined via rect struct as big clip plane, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFrustum_bigClipPlaneRect_rotViaVec + drawFrustum_bigClipPlaneRect_rotViaVec + Draw a Frustum in the Unity Editor. (defined via rect struct as big clip plane, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFrustum_hull + drawFrustum_hull + Draw a Frustum in the Unity Editor. (defined via pos/size/rot of a hull box) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFrustum_bigClipPlanePos_distanceToSmallAndApex_rotViaQuat + drawFrustum_bigClipPlanePos_distanceToSmallAndApex_rotViaQuat + Draw a Frustum in the Unity Editor. (defined via big clip plane center and distances to small clip plane and apex, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFrustum_bigClipPlanePos_distanceToSmallAndApex_rotViaVec + drawFrustum_bigClipPlanePos_distanceToSmallAndApex_rotViaVec + Draw a Frustum in the Unity Editor. (defined via big clip plane center and distances to small clip plane and apex, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFrustum_bigClipPlanePos_sizeFactorToSmall_rotViaQuat + drawFrustum_bigClipPlanePos_sizeFactorToSmall_rotViaQuat + Draw a Frustum in the Unity Editor. (defined via big clip plane center and size scale factor for small clip plane, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFrustum_bigClipPlanePos_sizeFactorToSmall_rotViaVec + drawFrustum_bigClipPlanePos_sizeFactorToSmall_rotViaVec + Draw a Frustum in the Unity Editor. (defined via big clip plane center and size scale factor for small clip plane, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFrustum_clipPlanesPos + drawFrustum_clipPlanesPos + Draw a Frustum in the Unity Editor. (defined via position of big and of small clip plane) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + frustum + + + +
+ + +
+ drawFlatShape_baseRectQuat + drawFlatShape_baseRectQuat + Draw a FlatShape in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatShape + flatShape + + + +
+ + +
+ drawFlatShape_baseRectVec + drawFlatShape_baseRectVec + Draw a FlatShape in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatShape + flatShape + + + +
+ + +
+ drawFlatShape_vecQuat + drawFlatShape_vecQuat + Draw a FlatShape in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatShape + flatShape + + + +
+ + +
+ drawFlatShape_vecVec + drawFlatShape_vecVec + Draw a FlatShape in the Unity Editor. (pos + rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatShape + flatShape + + + +
+ + +
+ drawRectangle_baseRectQuat + drawRectangle_baseRectQuat + Draw a Rectangle in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Rectangle + rectangle + + + +
+ + +
+ drawRectangle_baseRectVec + drawRectangle_baseRectVec + Draw a Rectangle in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Rectangle + rectangle + + + +
+ + +
+ drawRectangle_vecQuat + drawRectangle_vecQuat + Draw a Rectangle in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Rectangle + rectangle + + + +
+ + +
+ drawRectangle_vecVec + drawRectangle_vecVec + Draw a Rectangle in the Unity Editor. (pos + rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Rectangle + rectangle + + + +
+ + +
+ drawBox2D_rect + drawBox2D_rect + Draw a Box2D in the Unity Editor. (defined via rect struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Box2D + box2D + + + +
+ + +
+ drawBox2D_vec + drawBox2D_vec + Draw a Box2D in the Unity Editor. (defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Box2D + box2D + + + +
+ + +
+ drawCircle2D_rect + drawCircle2D_rect + Draw a Circle2D in the Unity Editor. (defined via rect struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle2D + circle2D + + + +
+ + +
+ drawCircle2D_vecRad + drawCircle2D_vecRad + Draw a Circle2D in the Unity Editor. (defined via vector and float as radius) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle2D + circle2D + + + +
+ + +
+ drawCapsule2D_vecC1C2Pos + drawCapsule2D_vecC1C2Pos + Draw a Capsule2D in the Unity Editor. (defined via position of circle1 and circle2) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule2D + capsule2D + + + +
+ + +
+ drawCapsule2D_rect + drawCapsule2D_rect + Draw a Capsule2D in the Unity Editor. (defined via rect struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule2D + capsule2D + + + +
+ + +
+ drawCapsule2D_vecPosSize + drawCapsule2D_vecPosSize + Draw a Capsule2D in the Unity Editor. (defined via center position and size from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule2D + capsule2D + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawShapes.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawShapes.snippet.meta new file mode 100644 index 0000000..fa84455 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawShapes.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cc5a54140a7981f4ca82bd53b8d3472d +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawShapes_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawShapes_func.snippet new file mode 100644 index 0000000..57acbff --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawShapes_func.snippet @@ -0,0 +1,4940 @@ + + + +
+ drawRegularPolygon_rotViaQuat_func + drawRegularPolygon_rotViaQuat_func + Encapsulated in a function: Draw a RegularPolygon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RegularPolygon + WithThisName + + + +
+ + +
+ drawRegularPolygon_rotViaVec_func + drawRegularPolygon_rotViaVec_func + Encapsulated in a function: Draw a RegularPolygon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RegularPolygon + WithThisName + + + +
+ + +
+ drawTriangle_rotViaQuat_func + drawTriangle_rotViaQuat_func + Encapsulated in a function: Draw a Triangle in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Triangle + WithThisName + + + +
+ + +
+ drawTriangle_rotViaVec_func + drawTriangle_rotViaVec_func + Encapsulated in a function: Draw a Triangle in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Triangle + WithThisName + + + +
+ + +
+ drawSquare_rotViaQuat_func + drawSquare_rotViaQuat_func + Encapsulated in a function: Draw a Square in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Square + WithThisName + + + +
+ + +
+ drawSquare_rotViaVec_func + drawSquare_rotViaVec_func + Encapsulated in a function: Draw a Square in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Square + WithThisName + + + +
+ + +
+ drawPentagon_rotViaQuat_func + drawPentagon_rotViaQuat_func + Encapsulated in a function: Draw a Pentagon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pentagon + WithThisName + + + +
+ + +
+ drawPentagon_rotViaVec_func + drawPentagon_rotViaVec_func + Encapsulated in a function: Draw a Pentagon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pentagon + WithThisName + + + +
+ + +
+ drawHexagon_rotViaQuat_func + drawHexagon_rotViaQuat_func + Encapsulated in a function: Draw a Hexagon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Hexagon + WithThisName + + + +
+ + +
+ drawHexagon_rotViaVec_func + drawHexagon_rotViaVec_func + Encapsulated in a function: Draw a Hexagon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Hexagon + WithThisName + + + +
+ + +
+ drawSeptagon_rotViaQuat_func + drawSeptagon_rotViaQuat_func + Encapsulated in a function: Draw a Septagon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Septagon + WithThisName + + + +
+ + +
+ drawSeptagon_rotViaVec_func + drawSeptagon_rotViaVec_func + Encapsulated in a function: Draw a Septagon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Septagon + WithThisName + + + +
+ + +
+ drawOctagon_rotViaQuat_func + drawOctagon_rotViaQuat_func + Encapsulated in a function: Draw an Octagon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Octagon + WithThisName + + + +
+ + +
+ drawOctagon_rotViaVec_func + drawOctagon_rotViaVec_func + Encapsulated in a function: Draw an Octagon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Octagon + WithThisName + + + +
+ + +
+ drawDecagon_rotViaQuat_func + drawDecagon_rotViaQuat_func + Encapsulated in a function: Draw a Decagon in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Decagon + WithThisName + + + +
+ + +
+ drawDecagon_rotViaVec_func + drawDecagon_rotViaVec_func + Encapsulated in a function: Draw a Decagon in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Decagon + WithThisName + + + +
+ + +
+ drawCircle_rotViaQuat_func + drawCircle_rotViaQuat_func + Encapsulated in a function: Draw a Circle in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle + WithThisName + + + +
+ + +
+ drawCircle_rotViaVec_func + drawCircle_rotViaVec_func + Encapsulated in a function: Draw a Circle in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle + WithThisName + + + +
+ + +
+ drawEllipse_rotViaQuat_func + drawEllipse_rotViaQuat_func + Encapsulated in a function: Draw an Ellipse in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ellipse + WithThisName + + + +
+ + +
+ drawEllipse_rotViaVec_func + drawEllipse_rotViaVec_func + Encapsulated in a function: Draw an Ellipse in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ellipse + WithThisName + + + +
+ + +
+ drawStar_rotViaQuat_func + drawStar_rotViaQuat_func + Encapsulated in a function: Draw a Star in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Star + WithThisName + + + +
+ + +
+ drawStar_rotViaVec_func + drawStar_rotViaVec_func + Encapsulated in a function: Draw a Star in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Star + WithThisName + + + +
+ + +
+ drawFlatCapsule_vecC1C2Pos_func + drawFlatCapsule_vecC1C2Pos_func + Encapsulated in a function: Draw a FlatCapsule in the Unity Editor. (capsule defined via position of circle1 and circle2) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatCapsule + WithThisName + + + +
+ + +
+ drawFlatCapsule_rotViaQuat_func + drawFlatCapsule_rotViaQuat_func + Encapsulated in a function: Draw a FlatCapsule in the Unity Editor. (the rotation is defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatCapsule + WithThisName + + + +
+ + +
+ drawFlatCapsule_rotViaVec_func + drawFlatCapsule_rotViaVec_func + Encapsulated in a function: Draw a FlatCapsule in the Unity Editor. (the rotation is defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatCapsule + WithThisName + + + +
+ + +
+ drawPlane_tr_func + drawPlane_tr_func + Encapsulated in a function: Draw a Plane in the Unity Editor. (defined via transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Plane + WithThisName + + + +
+ + +
+ drawPlane_pl_func + drawPlane_pl_func + Encapsulated in a function: Draw a Plane in the Unity Editor. (defined via plane struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Plane + WithThisName + + + +
+ + +
+ drawPlane_vec_func + drawPlane_vec_func + Encapsulated in a function: Draw a Plane in the Unity Editor. (defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Plane + WithThisName + + + +
+ + +
+ drawRhombusAroundCenter_func + drawRhombusAroundCenter_func + Encapsulated in a function: Draw a RhombusAroundCenter in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn RhombusAroundCenter + WithThisName + + + +
+ + +
+ drawRhombus_func + drawRhombus_func + Encapsulated in a function: Draw a Rhombus in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Rhombus + WithThisName + + + +
+ + +
+ drawCube_tr_func + drawCube_tr_func + Encapsulated in a function: Draw a Cube in the Unity Editor. (defined via transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cube + WithThisName + + + +
+ + +
+ drawCube_vecQuat_func + drawCube_vecQuat_func + Encapsulated in a function: Draw a Cube in the Unity Editor. pos defined via vector, rot defined via quaternion + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cube + WithThisName + + + +
+ + +
+ drawCube_vecVec_func + drawCube_vecVec_func + Encapsulated in a function: Draw a Cube in the Unity Editor. both pos and rot defined via vectors + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cube + WithThisName + + + +
+ + +
+ drawCubeFilled_tr_alpha_func + drawCubeFilled_tr_alpha_func + Encapsulated in a function: Draw a CubeFilled in the Unity Editor. (pos/size/rot from transform) (fill color same as strut color except lower alpha) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + WithThisName + + + +
+ + +
+ drawCubeFilled_vecQuat_alpha_func + drawCubeFilled_vecQuat_alpha_func + Encapsulated in a function: Draw a CubeFilled in the Unity Editor. (pos from vector, rot from quaternion) (fill color same as strut color except lower alpha) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + WithThisName + + + +
+ + +
+ drawCubeFilled_vecVec_alpha_func + drawCubeFilled_vecVec_alpha_func + Encapsulated in a function: Draw a CubeFilled in the Unity Editor. (pos/size/rot from vectors) (fill color same as strut color except lower alpha) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + WithThisName + + + +
+ + +
+ drawCubeFilled_tr_2col_func + drawCubeFilled_tr_2col_func + Encapsulated in a function: Draw a CubeFilled in the Unity Editor. (pos/size/rot from transform) (fill color is different from strut color) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + WithThisName + + + +
+ + +
+ drawCubeFilled_vecQuat_2col_func + drawCubeFilled_vecQuat_2col_func + Encapsulated in a function: Draw a CubeFilled in the Unity Editor. (pos from vector, rot from quaternion) (fill color is different from strut color) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + WithThisName + + + +
+ + +
+ drawCubeFilled_vecVec_2col_func + drawCubeFilled_vecVec_2col_func + Encapsulated in a function: Draw a CubeFilled in the Unity Editor. (pos/size/rot from vectors) (fill color is different from strut color) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn CubeFilled + WithThisName + + + +
+ + +
+ drawSphere_tr_func + drawSphere_tr_func + Encapsulated in a function: Draw a Sphere in the Unity Editor. (pos/size/rot from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Sphere + WithThisName + + + +
+ + +
+ drawSphere_vecQuat_func + drawSphere_vecQuat_func + Encapsulated in a function: Draw a Sphere in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Sphere + WithThisName + + + +
+ + +
+ drawSphere_vecVec_func + drawSphere_vecVec_func + Encapsulated in a function: Draw a Sphere in the Unity Editor. (pos/size/rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Sphere + WithThisName + + + +
+ + +
+ drawEllipsoid_tr_func + drawEllipsoid_tr_func + Encapsulated in a function: Draw an Ellipsoid in the Unity Editor. (pos/size/rot from transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ellipsoid + WithThisName + + + +
+ + +
+ drawEllipsoid_vecQuat_func + drawEllipsoid_vecQuat_func + Encapsulated in a function: Draw an Ellipsoid in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ellipsoid + WithThisName + + + +
+ + +
+ drawEllipsoid_vecVec_func + drawEllipsoid_vecVec_func + Encapsulated in a function: Draw an Ellipsoid in the Unity Editor. (pos/size/rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Ellipsoid + WithThisName + + + +
+ + +
+ drawEllipsoidNonUniform_vecQuat_func + drawEllipsoidNonUniform_vecQuat_func + Encapsulated in a function: Draw an EllipsoidNonUniform in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EllipsoidNonUniform + WithThisName + + + +
+ + +
+ drawEllipsoidNonUniform_vecVec_func + drawEllipsoidNonUniform_vecVec_func + Encapsulated in a function: Draw an EllipsoidNonUniform in the Unity Editor. (pos/rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn EllipsoidNonUniform + WithThisName + + + +
+ + +
+ drawCapsule_vecC1C2Pos_func + drawCapsule_vecC1C2Pos_func + Encapsulated in a function: Draw a Capsule in the Unity Editor. (defined via position of circle1 and circle2) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + WithThisName + + + +
+ + +
+ drawCapsule_tr_func + drawCapsule_tr_func + Encapsulated in a function: Draw a Capsule in the Unity Editor. (defined via transform) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + WithThisName + + + +
+ + +
+ drawCapsule_vecVecQuat_func + drawCapsule_vecVecQuat_func + Encapsulated in a function: Draw a Capsule in the Unity Editor. (pos from vector, size from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + WithThisName + + + +
+ + +
+ drawCapsule_vecVecVec_func + drawCapsule_vecVecVec_func + Encapsulated in a function: Draw a Capsule in the Unity Editor. (pos/size/rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + WithThisName + + + +
+ + +
+ drawCapsule_vecRadQuat_func + drawCapsule_vecRadQuat_func + Encapsulated in a function: Draw a Capsule in the Unity Editor. (pos from vector, radius from float, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + WithThisName + + + +
+ + +
+ drawCapsule_vecRadVec_func + drawCapsule_vecRadVec_func + Encapsulated in a function: Draw a Capsule in the Unity Editor. (pos from vector, radius from float, rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule + WithThisName + + + +
+ + +
+ drawPyramid_apexAnglesQuat_func + drawPyramid_apexAnglesQuat_func + Encapsulated in a function: Draw a Pyramid in the Unity Editor. (defined via apex pos and angles from there, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + WithThisName + + + +
+ + +
+ drawPyramid_apexAnglesVec_func + drawPyramid_apexAnglesVec_func + Encapsulated in a function: Draw a Pyramid in the Unity Editor. (defined via apex pos and angles from there, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + WithThisName + + + +
+ + +
+ drawPyramid_baseRectQuat_func + drawPyramid_baseRectQuat_func + Encapsulated in a function: Draw a Pyramid in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + WithThisName + + + +
+ + +
+ drawPyramid_baseRectVec_func + drawPyramid_baseRectVec_func + Encapsulated in a function: Draw a Pyramid in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + WithThisName + + + +
+ + +
+ drawPyramid_vecVecQuat_func + drawPyramid_vecVecQuat_func + Encapsulated in a function: Draw a Pyramid in the Unity Editor. (pos+size via vectors, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + WithThisName + + + +
+ + +
+ drawPyramid_vecFloatQuat_func + drawPyramid_vecFloatQuat_func + Encapsulated in a function: Draw a Pyramid in the Unity Editor. (pos via vector, size via floats, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + WithThisName + + + +
+ + +
+ drawPyramid_vecFloatVec_func + drawPyramid_vecFloatVec_func + Encapsulated in a function: Draw a Pyramid in the Unity Editor. (pos via vector, size via floats, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Pyramid + WithThisName + + + +
+ + +
+ drawCone_apexAnglesQuat_func + drawCone_apexAnglesQuat_func + Encapsulated in a function: Draw a Cone in the Unity Editor. (defined via apex pos and angles from there, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cone + WithThisName + + + +
+ + +
+ drawCone_apexAnglesVec_func + drawCone_apexAnglesVec_func + Encapsulated in a function: Draw a Cone in the Unity Editor. (defined via apex pos and angles from there, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cone + WithThisName + + + +
+ + +
+ drawCone_vecVecQuat_func + drawCone_vecVecQuat_func + Encapsulated in a function: Draw a Cone in the Unity Editor. (pos+size via vectors, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cone + WithThisName + + + +
+ + +
+ drawCone_vecFloatQuat_func + drawCone_vecFloatQuat_func + Encapsulated in a function: Draw a Cone in the Unity Editor. (pos via vector, size via floats, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cone + WithThisName + + + +
+ + +
+ drawCone_vecFloatVec_func + drawCone_vecFloatVec_func + Encapsulated in a function: Draw a Cone in the Unity Editor. (pos via vector, size via floats, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cone + WithThisName + + + +
+ + +
+ drawConeFilled_apexAnglesQuat_func + drawConeFilled_apexAnglesQuat_func + Encapsulated in a function: Draw a ConeFilled in the Unity Editor. (defined via apex pos and angles from there, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ConeFilled + WithThisName + + + +
+ + +
+ drawConeFilled_apexAnglesVec_func + drawConeFilled_apexAnglesVec_func + Encapsulated in a function: Draw a ConeFilled in the Unity Editor. (defined via apex pos and angles from there, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ConeFilled + WithThisName + + + +
+ + +
+ drawConeFilled_vecVecQuat_func + drawConeFilled_vecVecQuat_func + Encapsulated in a function: Draw a ConeFilled in the Unity Editor. (pos+size via vectors, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ConeFilled + WithThisName + + + +
+ + +
+ drawConeFilled_vecFloatQuat_func + drawConeFilled_vecFloatQuat_func + Encapsulated in a function: Draw a ConeFilled in the Unity Editor. (pos via vector, size via floats, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ConeFilled + WithThisName + + + +
+ + +
+ drawConeFilled_vecFloatVec_func + drawConeFilled_vecFloatVec_func + Encapsulated in a function: Draw a ConeFilled in the Unity Editor. (pos via vector, size via floats, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ConeFilled + WithThisName + + + +
+ + +
+ drawBipyramid_baseRectQuat_func + drawBipyramid_baseRectQuat_func + Encapsulated in a function: Draw a Bipyramid in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bipyramid + WithThisName + + + +
+ + +
+ drawBipyramid_baseRectVec_func + drawBipyramid_baseRectVec_func + Encapsulated in a function: Draw a Bipyramid in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bipyramid + WithThisName + + + +
+ + +
+ drawBipyramid_vecVecQuat_func + drawBipyramid_vecVecQuat_func + Encapsulated in a function: Draw a Bipyramid in the Unity Editor. (pos+size via vectors, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bipyramid + WithThisName + + + +
+ + +
+ drawBipyramid_vecFloatQuat_func + drawBipyramid_vecFloatQuat_func + Encapsulated in a function: Draw a Bipyramid in the Unity Editor. (pos via vector, size via floats, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bipyramid + WithThisName + + + +
+ + +
+ drawBipyramid_vecFloatVec_func + drawBipyramid_vecFloatVec_func + Encapsulated in a function: Draw a Bipyramid in the Unity Editor. (pos via vector, size via floats, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Bipyramid + WithThisName + + + +
+ + +
+ drawCylinder_baseRectQuat_func + drawCylinder_baseRectQuat_func + Encapsulated in a function: Draw a Cylinder in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cylinder + WithThisName + + + +
+ + +
+ drawCylinder_baseRectVec_func + drawCylinder_baseRectVec_func + Encapsulated in a function: Draw a Cylinder in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cylinder + WithThisName + + + +
+ + +
+ drawCylinder_vecVecQuat_func + drawCylinder_vecVecQuat_func + Encapsulated in a function: Draw a Cylinder in the Unity Editor. (pos+size via vectors, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cylinder + WithThisName + + + +
+ + +
+ drawCylinder_vecFloatQuat_func + drawCylinder_vecFloatQuat_func + Encapsulated in a function: Draw a Cylinder in the Unity Editor. (pos via vector, size via floats, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cylinder + WithThisName + + + +
+ + +
+ drawCylinder_vecFloatVec_func + drawCylinder_vecFloatVec_func + Encapsulated in a function: Draw a Cylinder in the Unity Editor. (pos via vector, size via floats, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Cylinder + WithThisName + + + +
+ + +
+ drawExtrusion_baseRectQuat_func + drawExtrusion_baseRectQuat_func + Encapsulated in a function: Draw an Extrusion in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Extrusion + WithThisName + + + +
+ + +
+ drawExtrusion_baseRectVec_func + drawExtrusion_baseRectVec_func + Encapsulated in a function: Draw an Extrusion in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Extrusion + WithThisName + + + +
+ + +
+ drawExtrusion_vecQuat_func + drawExtrusion_vecQuat_func + Encapsulated in a function: Draw an Extrusion in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Extrusion + WithThisName + + + +
+ + +
+ drawExtrusion_vecVec_func + drawExtrusion_vecVec_func + Encapsulated in a function: Draw an Extrusion in the Unity Editor. (pos + rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Extrusion + WithThisName + + + +
+ + +
+ drawFrustum_cam_func + drawFrustum_cam_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (specified via a camera component) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFrustum_apexAndAngles_rotViaQuat_func + drawFrustum_apexAndAngles_rotViaQuat_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (defined via apex pos and angles from there, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFrustum_apexAndAngles_rotViaVec_func + drawFrustum_apexAndAngles_rotViaVec_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (defined via apex pos and angles from there, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFrustum_bigClipPlaneRect_rotViaQuat_func + drawFrustum_bigClipPlaneRect_rotViaQuat_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (defined via rect struct as big clip plane, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFrustum_bigClipPlaneRect_rotViaVec_func + drawFrustum_bigClipPlaneRect_rotViaVec_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (defined via rect struct as big clip plane, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFrustum_hull_func + drawFrustum_hull_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (defined via pos/size/rot of a hull box) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFrustum_bigClipPlanePos_distanceToSmallAndApex_rotViaQuat_func + drawFrustum_bigClipPlanePos_distanceToSmallAndApex_rotViaQuat_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (defined via big clip plane center and distances to small clip plane and apex, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFrustum_bigClipPlanePos_distanceToSmallAndApex_rotViaVec_func + drawFrustum_bigClipPlanePos_distanceToSmallAndApex_rotViaVec_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (defined via big clip plane center and distances to small clip plane and apex, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFrustum_bigClipPlanePos_sizeFactorToSmall_rotViaQuat_func + drawFrustum_bigClipPlanePos_sizeFactorToSmall_rotViaQuat_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (defined via big clip plane center and size scale factor for small clip plane, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFrustum_bigClipPlanePos_sizeFactorToSmall_rotViaVec_func + drawFrustum_bigClipPlanePos_sizeFactorToSmall_rotViaVec_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (defined via big clip plane center and size scale factor for small clip plane, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFrustum_clipPlanesPos_func + drawFrustum_clipPlanesPos_func + Encapsulated in a function: Draw a Frustum in the Unity Editor. (defined via position of big and of small clip plane) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Frustum + WithThisName + + + +
+ + +
+ drawFlatShape_baseRectQuat_func + drawFlatShape_baseRectQuat_func + Encapsulated in a function: Draw a FlatShape in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatShape + WithThisName + + + +
+ + +
+ drawFlatShape_baseRectVec_func + drawFlatShape_baseRectVec_func + Encapsulated in a function: Draw a FlatShape in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatShape + WithThisName + + + +
+ + +
+ drawFlatShape_vecQuat_func + drawFlatShape_vecQuat_func + Encapsulated in a function: Draw a FlatShape in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatShape + WithThisName + + + +
+ + +
+ drawFlatShape_vecVec_func + drawFlatShape_vecVec_func + Encapsulated in a function: Draw a FlatShape in the Unity Editor. (pos + rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn FlatShape + WithThisName + + + +
+ + +
+ drawRectangle_baseRectQuat_func + drawRectangle_baseRectQuat_func + Encapsulated in a function: Draw a Rectangle in the Unity Editor. (defined via rect struct as base, rotation via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Rectangle + WithThisName + + + +
+ + +
+ drawRectangle_baseRectVec_func + drawRectangle_baseRectVec_func + Encapsulated in a function: Draw a Rectangle in the Unity Editor. (defined via rect struct as base, rotation via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Rectangle + WithThisName + + + +
+ + +
+ drawRectangle_vecQuat_func + drawRectangle_vecQuat_func + Encapsulated in a function: Draw a Rectangle in the Unity Editor. (pos from vector, rot from quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Rectangle + WithThisName + + + +
+ + +
+ drawRectangle_vecVec_func + drawRectangle_vecVec_func + Encapsulated in a function: Draw a Rectangle in the Unity Editor. (pos + rot from vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Rectangle + WithThisName + + + +
+ + +
+ drawBox2D_rect_func + drawBox2D_rect_func + Encapsulated in a function: Draw a Box2D in the Unity Editor. (defined via rect struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Box2D + WithThisName + + + +
+ + +
+ drawBox2D_vec_func + drawBox2D_vec_func + Encapsulated in a function: Draw a Box2D in the Unity Editor. (defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Box2D + WithThisName + + + +
+ + +
+ drawCircle2D_rect_func + drawCircle2D_rect_func + Encapsulated in a function: Draw a Circle2D in the Unity Editor. (defined via rect struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle2D + WithThisName + + + +
+ + +
+ drawCircle2D_vecRad_func + drawCircle2D_vecRad_func + Encapsulated in a function: Draw a Circle2D in the Unity Editor. (defined via vector and float as radius) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Circle2D + WithThisName + + + +
+ + +
+ drawCapsule2D_vecC1C2Pos_func + drawCapsule2D_vecC1C2Pos_func + Encapsulated in a function: Draw a Capsule2D in the Unity Editor. (defined via position of circle1 and circle2) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule2D + WithThisName + + + +
+ + +
+ drawCapsule2D_rect_func + drawCapsule2D_rect_func + Encapsulated in a function: Draw a Capsule2D in the Unity Editor. (defined via rect struct) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule2D + WithThisName + + + +
+ + +
+ drawCapsule2D_vecPosSize_func + drawCapsule2D_vecPosSize_func + Encapsulated in a function: Draw a Capsule2D in the Unity Editor. (defined via center position and size from vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Capsule2D + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawShapes_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawShapes_func.snippet.meta new file mode 100644 index 0000000..1ecced2 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawShapes_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a74eae24b1e87d04da1a0a997ce7cefd +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawText.snippet b/Editor/DrawDebugLibrary/code snippets/drawText.snippet new file mode 100644 index 0000000..f71192c --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawText.snippet @@ -0,0 +1,4581 @@ + + + +
+ drawTextScreenspace_3Dpos_dirViaVec + drawTextScreenspace_3Dpos_dirViaVec + Draw TextScreenspace in the Unity Editor. (position defined in 3D worldspace) (text direction defined via vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + textScreenspace + + + +
+ + +
+ drawTextScreenspace_3Dpos_dirViaVec_cam + drawTextScreenspace_3Dpos_dirViaVec_cam + Draw TextScreenspace in the Unity Editor. (position defined in 3D worldspace) (text direction defined via vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + textScreenspace + + + +
+ + +
+ drawTextScreenspace_2Dpos_dirViaVec + drawTextScreenspace_2Dpos_dirViaVec + Draw TextScreenspace in the Unity Editor. (position defined in 2D screenspace) (text direction defined via vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + textScreenspace + + + +
+ + +
+ drawTextScreenspace_2Dpos_dirViaVec_cam + drawTextScreenspace_2Dpos_dirViaVec_cam + Draw TextScreenspace in the Unity Editor. (position defined in 2D screenspace) (text direction defined via vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + textScreenspace + + + +
+ + +
+ drawTextScreenspaceFramed_3Dpos_dirViaVec + drawTextScreenspaceFramed_3Dpos_dirViaVec + Draw TextScreenspaceFramed in the Unity Editor. (position defined in 3D worldspace) (text direction defined via vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + textScreenspaceFramed + + + +
+ + +
+ drawTextScreenspaceFramed_3Dpos_dirViaVec_cam + drawTextScreenspaceFramed_3Dpos_dirViaVec_cam + Draw TextScreenspaceFramed in the Unity Editor. (position defined in 3D worldspace) (text direction defined via vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + textScreenspaceFramed + + + +
+ + +
+ drawTextScreenspaceFramed_2Dpos_dirViaVec + drawTextScreenspaceFramed_2Dpos_dirViaVec + Draw TextScreenspaceFramed in the Unity Editor. (position defined in 2D screenspace) (text direction defined via vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + textScreenspaceFramed + + + +
+ + +
+ drawTextScreenspaceFramed_2Dpos_dirViaVec_cam + drawTextScreenspaceFramed_2Dpos_dirViaVec_cam + Draw TextScreenspaceFramed in the Unity Editor. (position defined in 2D screenspace) (text direction defined via vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + textScreenspaceFramed + + + +
+ + +
+ drawTextScreenspace_3Dpos_dirViaAngle + drawTextScreenspace_3Dpos_dirViaAngle + Draw TextScreenspace in the Unity Editor. (position defined in 3D worldspace) (text direction defined via angle) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + textScreenspace + + + +
+ + +
+ drawTextScreenspace_3Dpos_dirViaAngle_cam + drawTextScreenspace_3Dpos_dirViaAngle_cam + Draw TextScreenspace in the Unity Editor. (position defined in 3D worldspace) (text direction defined via angle) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + textScreenspace + + + +
+ + +
+ drawTextScreenspace_2Dpos_dirViaAngle + drawTextScreenspace_2Dpos_dirViaAngle + Draw TextScreenspace in the Unity Editor. (position defined in 2D screenspace) (text direction defined via angle) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + textScreenspace + + + +
+ + +
+ drawTextScreenspace_2Dpos_dirViaAngle_cam + drawTextScreenspace_2Dpos_dirViaAngle_cam + Draw TextScreenspace in the Unity Editor. (position defined in 2D screenspace) (text direction defined via angle) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + textScreenspace + + + +
+ + +
+ drawTextScreenspaceFramed_3Dpos_dirViaAngle + drawTextScreenspaceFramed_3Dpos_dirViaAngle + Draw TextScreenspaceFramed in the Unity Editor. (position defined in 3D worldspace) (text direction defined via angle) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + textScreenspaceFramed + + + +
+ + +
+ drawTextScreenspaceFramed_3Dpos_dirViaAngle_cam + drawTextScreenspaceFramed_3Dpos_dirViaAngle_cam + Draw TextScreenspaceFramed in the Unity Editor. (position defined in 3D worldspace) (text direction defined via angle) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + textScreenspaceFramed + + + +
+ + +
+ drawTextScreenspaceFramed_2Dpos_dirViaAngle + drawTextScreenspaceFramed_2Dpos_dirViaAngle + Draw TextScreenspaceFramed in the Unity Editor. (position defined in 2D screenspace) (text direction defined via angle) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + textScreenspaceFramed + + + +
+ + +
+ drawTextScreenspaceFramed_2Dpos_dirViaAngle_cam + drawTextScreenspaceFramed_2Dpos_dirViaAngle_cam + Draw TextScreenspaceFramed in the Unity Editor. (position defined in 2D screenspace) (text direction defined via angle) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + textScreenspaceFramed + + + +
+ + +
+ drawText2D_dirViaVec + drawText2D_dirViaVec + Draw Text2D in the Unity Editor. (text direction defined via vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text2D + text2D + + + +
+ + +
+ drawText2DFramed_dirViaVec + drawText2DFramed_dirViaVec + Draw Text2DFramed in the Unity Editor. (text direction defined via vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text2DFramed + text2DFramed + + + +
+ + +
+ drawText2D_dirViaAngle + drawText2D_dirViaAngle + Draw Text2D in the Unity Editor. (text direction defined via angle) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text2D + text2D + + + +
+ + +
+ drawText2DFramed_dirViaAngle + drawText2DFramed_dirViaAngle + Draw Text2DFramed in the Unity Editor. (text direction defined via angle) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text2DFramed + text2DFramed + + + +
+ + +
+ drawText_dirViaQuat + drawText_dirViaQuat + Draw Text in the Unity Editor. (text direction defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text + text + + + +
+ + +
+ drawTextFramed_dirViaQuat + drawTextFramed_dirViaQuat + Draw TextFramed in the Unity Editor. (text direction defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextFramed + textFramed + + + +
+ + +
+ drawText_dirViaVec + drawText_dirViaVec + Draw Text in the Unity Editor. (text direction defined via vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text + text + + + +
+ + +
+ drawTextFramed_dirViaVec + drawTextFramed_dirViaVec + Draw TextFramed in the Unity Editor. (text direction defined via vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextFramed + textFramed + + + +
+ + +
+ drawTextOnCircleScreenspace_viaStartPos + drawTextOnCircleScreenspace_viaStartPos + Draw TextOnCircleScreenspace in the Unity Editor. (defined via text start position, instead of circle center position) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + textOnCircleScreenspace + + + +
+ + +
+ drawTextOnCircleScreenspace_viaStartPos_cam + drawTextOnCircleScreenspace_viaStartPos_cam + Draw TextOnCircleScreenspace in the Unity Editor. (defined via text start position, instead of circle center position) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + textOnCircleScreenspace + + + +
+ + +
+ drawTextOnCircleScreenspace_dirViaVecUp + drawTextOnCircleScreenspace_dirViaVecUp + Draw TextOnCircleScreenspace in the Unity Editor. (text initial upDirection defined via vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + textOnCircleScreenspace + + + +
+ + +
+ drawTextOnCircleScreenspace_dirViaVecUp_cam + drawTextOnCircleScreenspace_dirViaVecUp_cam + Draw TextOnCircleScreenspace in the Unity Editor. (text initial upDirection defined via vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + textOnCircleScreenspace + + + +
+ + +
+ drawTextOnCircleScreenspace_dirViaAngle + drawTextOnCircleScreenspace_dirViaAngle + Draw TextOnCircleScreenspace in the Unity Editor. (initial text direction defined via angle) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + textOnCircleScreenspace + + + +
+ + +
+ drawTextOnCircleScreenspace_dirViaAngle_cam + drawTextOnCircleScreenspace_dirViaAngle_cam + Draw TextOnCircleScreenspace in the Unity Editor. (initial text direction defined via angle) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + textOnCircleScreenspace + + + +
+ + +
+ drawTextOnCircle2D_viaStartPos + drawTextOnCircle2D_viaStartPos + Draw TextOnCircle2D in the Unity Editor. (defined via text start position, instead of circle center position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle2D + textOnCircle2D + + + +
+ + +
+ drawTextOnCircle2D_dirViaVecUp + drawTextOnCircle2D_dirViaVecUp + Draw TextOnCircle2D in the Unity Editor. (text initial upDirection defined via vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle2D + textOnCircle2D + + + +
+ + +
+ drawTextOnCircle2D_dirViaAngle + drawTextOnCircle2D_dirViaAngle + Draw TextOnCircle2D in the Unity Editor. (initial text direction defined via angle) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle2D + textOnCircle2D + + + +
+ + +
+ drawTextOnCircle_viaStartPos + drawTextOnCircle_viaStartPos + Draw TextOnCircle in the Unity Editor. (defined via text start position, instead of circle center position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle + textOnCircle + + + +
+ + +
+ drawTextOnCircle_viaQuat + drawTextOnCircle_viaQuat + Draw TextOnCircle in the Unity Editor. (orientation defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle + textOnCircle + + + +
+ + +
+ drawTextOnCircle_viaVec + drawTextOnCircle_viaVec + Draw TextOnCircle in the Unity Editor. (orientation defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle + textOnCircle + + + +
+ + +
+ drawArrayOfBool + drawArrayOfBool + Draw ArrayOfBool in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + arrayOfBool + + + +
+ + +
+ drawArrayOfBool_in2D + drawArrayOfBool_in2D + Draw ArrayOfBool in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + arrayOfBool + + + +
+ + +
+ drawArrayOfBool_screenspace_3Dpos + drawArrayOfBool_screenspace_3Dpos + Draw ArrayOfBool in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + arrayOfBool + + + +
+ + +
+ drawArrayOfBool_screenspace_3Dpos_cam + drawArrayOfBool_screenspace_3Dpos_cam + Draw ArrayOfBool in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + arrayOfBool + + + +
+ + +
+ drawArrayOfBool_screenspace_2Dpos + drawArrayOfBool_screenspace_2Dpos + Draw ArrayOfBool in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + arrayOfBool + + + +
+ + +
+ drawArrayOfBool_screenspace_2Dpos_cam + drawArrayOfBool_screenspace_2Dpos_cam + Draw ArrayOfBool in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + arrayOfBool + + + +
+ + +
+ drawListOfBool + drawListOfBool + Draw ListOfBool in the Unity Editor. + Draw XXL +
+ + + boolList_of_$name$ = $end$; + Vector3 position_of_$name$ = default(Vector3); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + Quaternion rotation_of_$name$ = default(Quaternion); + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList(boolList_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, rotation_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + listOfBool + + + +
+ + +
+ drawListOfBool_in2D + drawListOfBool_in2D + Draw ListOfBool in the Unity Editor. + Draw XXL +
+ + + boolList_of_$name$ = $end$; + Vector2 position_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + float custom_zPos_of_$name$ = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList2D(boolList_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, custom_zPos_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + listOfBool + + + +
+ + +
+ drawListOfBool_screenspace_3Dpos + drawListOfBool_screenspace_3Dpos + Draw ListOfBool in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + boolList_of_$name$ = $end$; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(boolList_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + listOfBool + + + +
+ + +
+ drawListOfBool_screenspace_3Dpos_cam + drawListOfBool_screenspace_3Dpos_cam + Draw ListOfBool in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + boolList_of_$name$ = ; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, boolList_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + listOfBool + + + +
+ + +
+ drawListOfBool_screenspace_2Dpos + drawListOfBool_screenspace_2Dpos + Draw ListOfBool in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + boolList_of_$name$ = $end$; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(boolList_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + listOfBool + + + +
+ + +
+ drawListOfBool_screenspace_2Dpos_cam + drawListOfBool_screenspace_2Dpos_cam + Draw ListOfBool in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + boolList_of_$name$ = ; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, boolList_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + listOfBool + + + +
+ + +
+ drawArrayOfInt + drawArrayOfInt + Draw ArrayOfInt in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + arrayOfInt + + + +
+ + +
+ drawArrayOfInt_in2D + drawArrayOfInt_in2D + Draw ArrayOfInt in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + arrayOfInt + + + +
+ + +
+ drawArrayOfInt_screenspace_3Dpos + drawArrayOfInt_screenspace_3Dpos + Draw ArrayOfInt in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + arrayOfInt + + + +
+ + +
+ drawArrayOfInt_screenspace_3Dpos_cam + drawArrayOfInt_screenspace_3Dpos_cam + Draw ArrayOfInt in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + arrayOfInt + + + +
+ + +
+ drawArrayOfInt_screenspace_2Dpos + drawArrayOfInt_screenspace_2Dpos + Draw ArrayOfInt in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + arrayOfInt + + + +
+ + +
+ drawArrayOfInt_screenspace_2Dpos_cam + drawArrayOfInt_screenspace_2Dpos_cam + Draw ArrayOfInt in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + arrayOfInt + + + +
+ + +
+ drawListOfInt + drawListOfInt + Draw ListOfInt in the Unity Editor. + Draw XXL +
+ + + intList_of_$name$ = $end$; + Vector3 position_of_$name$ = default(Vector3); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + Quaternion rotation_of_$name$ = default(Quaternion); + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList(intList_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, rotation_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + listOfInt + + + +
+ + +
+ drawListOfInt_in2D + drawListOfInt_in2D + Draw ListOfInt in the Unity Editor. + Draw XXL +
+ + + intList_of_$name$ = $end$; + Vector2 position_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + float custom_zPos_of_$name$ = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList2D(intList_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, custom_zPos_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + listOfInt + + + +
+ + +
+ drawListOfInt_screenspace_3Dpos + drawListOfInt_screenspace_3Dpos + Draw ListOfInt in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + intList_of_$name$ = $end$; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(intList_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + listOfInt + + + +
+ + +
+ drawListOfInt_screenspace_3Dpos_cam + drawListOfInt_screenspace_3Dpos_cam + Draw ListOfInt in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + intList_of_$name$ = ; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, intList_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + listOfInt + + + +
+ + +
+ drawListOfInt_screenspace_2Dpos + drawListOfInt_screenspace_2Dpos + Draw ListOfInt in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + intList_of_$name$ = $end$; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(intList_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + listOfInt + + + +
+ + +
+ drawListOfInt_screenspace_2Dpos_cam + drawListOfInt_screenspace_2Dpos_cam + Draw ListOfInt in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + intList_of_$name$ = ; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, intList_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + listOfInt + + + +
+ + +
+ drawArrayOfFloat + drawArrayOfFloat + Draw ArrayOfFloat in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + arrayOfFloat + + + +
+ + +
+ drawArrayOfFloat_in2D + drawArrayOfFloat_in2D + Draw ArrayOfFloat in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + arrayOfFloat + + + +
+ + +
+ drawArrayOfFloat_screenspace_3Dpos + drawArrayOfFloat_screenspace_3Dpos + Draw ArrayOfFloat in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + arrayOfFloat + + + +
+ + +
+ drawArrayOfFloat_screenspace_3Dpos_cam + drawArrayOfFloat_screenspace_3Dpos_cam + Draw ArrayOfFloat in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + arrayOfFloat + + + +
+ + +
+ drawArrayOfFloat_screenspace_2Dpos + drawArrayOfFloat_screenspace_2Dpos + Draw ArrayOfFloat in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + arrayOfFloat + + + +
+ + +
+ drawArrayOfFloat_screenspace_2Dpos_cam + drawArrayOfFloat_screenspace_2Dpos_cam + Draw ArrayOfFloat in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + arrayOfFloat + + + +
+ + +
+ drawListOfFloat + drawListOfFloat + Draw ListOfFloat in the Unity Editor. + Draw XXL +
+ + + floatList_of_$name$ = $end$; + Vector3 position_of_$name$ = default(Vector3); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + Quaternion rotation_of_$name$ = default(Quaternion); + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList(floatList_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, rotation_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + listOfFloat + + + +
+ + +
+ drawListOfFloat_in2D + drawListOfFloat_in2D + Draw ListOfFloat in the Unity Editor. + Draw XXL +
+ + + floatList_of_$name$ = $end$; + Vector2 position_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + float custom_zPos_of_$name$ = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList2D(floatList_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, custom_zPos_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + listOfFloat + + + +
+ + +
+ drawListOfFloat_screenspace_3Dpos + drawListOfFloat_screenspace_3Dpos + Draw ListOfFloat in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + floatList_of_$name$ = $end$; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(floatList_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + listOfFloat + + + +
+ + +
+ drawListOfFloat_screenspace_3Dpos_cam + drawListOfFloat_screenspace_3Dpos_cam + Draw ListOfFloat in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + floatList_of_$name$ = ; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, floatList_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + listOfFloat + + + +
+ + +
+ drawListOfFloat_screenspace_2Dpos + drawListOfFloat_screenspace_2Dpos + Draw ListOfFloat in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + floatList_of_$name$ = $end$; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(floatList_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + listOfFloat + + + +
+ + +
+ drawListOfFloat_screenspace_2Dpos_cam + drawListOfFloat_screenspace_2Dpos_cam + Draw ListOfFloat in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + floatList_of_$name$ = ; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, floatList_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + listOfFloat + + + +
+ + +
+ drawArrayOfString + drawArrayOfString + Draw ArrayOfString in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + arrayOfString + + + +
+ + +
+ drawArrayOfString_in2D + drawArrayOfString_in2D + Draw ArrayOfString in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + arrayOfString + + + +
+ + +
+ drawArrayOfString_screenspace_3Dpos + drawArrayOfString_screenspace_3Dpos + Draw ArrayOfString in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + arrayOfString + + + +
+ + +
+ drawArrayOfString_screenspace_3Dpos_cam + drawArrayOfString_screenspace_3Dpos_cam + Draw ArrayOfString in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + arrayOfString + + + +
+ + +
+ drawArrayOfString_screenspace_2Dpos + drawArrayOfString_screenspace_2Dpos + Draw ArrayOfString in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + arrayOfString + + + +
+ + +
+ drawArrayOfString_screenspace_2Dpos_cam + drawArrayOfString_screenspace_2Dpos_cam + Draw ArrayOfString in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + arrayOfString + + + +
+ + +
+ drawListOfString + drawListOfString + Draw ListOfString in the Unity Editor. + Draw XXL +
+ + + stringList_of_$name$ = $end$; + Vector3 position_of_$name$ = default(Vector3); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + Quaternion rotation_of_$name$ = default(Quaternion); + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList(stringList_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, rotation_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + listOfString + + + +
+ + +
+ drawListOfString_in2D + drawListOfString_in2D + Draw ListOfString in the Unity Editor. + Draw XXL +
+ + + stringList_of_$name$ = $end$; + Vector2 position_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + float custom_zPos_of_$name$ = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList2D(stringList_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, custom_zPos_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + listOfString + + + +
+ + +
+ drawListOfString_screenspace_3Dpos + drawListOfString_screenspace_3Dpos + Draw ListOfString in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + stringList_of_$name$ = $end$; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(stringList_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + listOfString + + + +
+ + +
+ drawListOfString_screenspace_3Dpos_cam + drawListOfString_screenspace_3Dpos_cam + Draw ListOfString in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + stringList_of_$name$ = ; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, stringList_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + listOfString + + + +
+ + +
+ drawListOfString_screenspace_2Dpos + drawListOfString_screenspace_2Dpos + Draw ListOfString in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + stringList_of_$name$ = $end$; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(stringList_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + listOfString + + + +
+ + +
+ drawListOfString_screenspace_2Dpos_cam + drawListOfString_screenspace_2Dpos_cam + Draw ListOfString in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + stringList_of_$name$ = ; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, stringList_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + listOfString + + + +
+ + +
+ drawArrayOfVector2 + drawArrayOfVector2 + Draw ArrayOfVector2 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + arrayOfVector2 + + + +
+ + +
+ drawArrayOfVector2_in2D + drawArrayOfVector2_in2D + Draw ArrayOfVector2 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + arrayOfVector2 + + + +
+ + +
+ drawArrayOfVector2_screenspace_3Dpos + drawArrayOfVector2_screenspace_3Dpos + Draw ArrayOfVector2 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + arrayOfVector2 + + + +
+ + +
+ drawArrayOfVector2_screenspace_3Dpos_cam + drawArrayOfVector2_screenspace_3Dpos_cam + Draw ArrayOfVector2 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + arrayOfVector2 + + + +
+ + +
+ drawArrayOfVector2_screenspace_2Dpos + drawArrayOfVector2_screenspace_2Dpos + Draw ArrayOfVector2 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + arrayOfVector2 + + + +
+ + +
+ drawArrayOfVector2_screenspace_2Dpos_cam + drawArrayOfVector2_screenspace_2Dpos_cam + Draw ArrayOfVector2 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + arrayOfVector2 + + + +
+ + +
+ drawListOfVector2 + drawListOfVector2 + Draw ListOfVector2 in the Unity Editor. + Draw XXL +
+ + + vector2List_of_$name$ = $end$; + Vector3 position_of_$name$ = default(Vector3); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + Quaternion rotation_of_$name$ = default(Quaternion); + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList(vector2List_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, rotation_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + listOfVector2 + + + +
+ + +
+ drawListOfVector2_in2D + drawListOfVector2_in2D + Draw ListOfVector2 in the Unity Editor. + Draw XXL +
+ + + vector2List_of_$name$ = $end$; + Vector2 position_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + float custom_zPos_of_$name$ = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList2D(vector2List_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, custom_zPos_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + listOfVector2 + + + +
+ + +
+ drawListOfVector2_screenspace_3Dpos + drawListOfVector2_screenspace_3Dpos + Draw ListOfVector2 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + vector2List_of_$name$ = $end$; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(vector2List_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + listOfVector2 + + + +
+ + +
+ drawListOfVector2_screenspace_3Dpos_cam + drawListOfVector2_screenspace_3Dpos_cam + Draw ListOfVector2 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector2List_of_$name$ = ; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, vector2List_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + listOfVector2 + + + +
+ + +
+ drawListOfVector2_screenspace_2Dpos + drawListOfVector2_screenspace_2Dpos + Draw ListOfVector2 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + vector2List_of_$name$ = $end$; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(vector2List_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + listOfVector2 + + + +
+ + +
+ drawListOfVector2_screenspace_2Dpos_cam + drawListOfVector2_screenspace_2Dpos_cam + Draw ListOfVector2 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector2List_of_$name$ = ; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, vector2List_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + listOfVector2 + + + +
+ + +
+ drawArrayOfVector3 + drawArrayOfVector3 + Draw ArrayOfVector3 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + arrayOfVector3 + + + +
+ + +
+ drawArrayOfVector3_in2D + drawArrayOfVector3_in2D + Draw ArrayOfVector3 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + arrayOfVector3 + + + +
+ + +
+ drawArrayOfVector3_screenspace_3Dpos + drawArrayOfVector3_screenspace_3Dpos + Draw ArrayOfVector3 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + arrayOfVector3 + + + +
+ + +
+ drawArrayOfVector3_screenspace_3Dpos_cam + drawArrayOfVector3_screenspace_3Dpos_cam + Draw ArrayOfVector3 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + arrayOfVector3 + + + +
+ + +
+ drawArrayOfVector3_screenspace_2Dpos + drawArrayOfVector3_screenspace_2Dpos + Draw ArrayOfVector3 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + arrayOfVector3 + + + +
+ + +
+ drawArrayOfVector3_screenspace_2Dpos_cam + drawArrayOfVector3_screenspace_2Dpos_cam + Draw ArrayOfVector3 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + arrayOfVector3 + + + +
+ + +
+ drawListOfVector3 + drawListOfVector3 + Draw ListOfVector3 in the Unity Editor. + Draw XXL +
+ + + vector3List_of_$name$ = $end$; + Vector3 position_of_$name$ = default(Vector3); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + Quaternion rotation_of_$name$ = default(Quaternion); + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList(vector3List_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, rotation_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + listOfVector3 + + + +
+ + +
+ drawListOfVector3_in2D + drawListOfVector3_in2D + Draw ListOfVector3 in the Unity Editor. + Draw XXL +
+ + + vector3List_of_$name$ = $end$; + Vector2 position_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + float custom_zPos_of_$name$ = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList2D(vector3List_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, custom_zPos_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + listOfVector3 + + + +
+ + +
+ drawListOfVector3_screenspace_3Dpos + drawListOfVector3_screenspace_3Dpos + Draw ListOfVector3 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + vector3List_of_$name$ = $end$; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(vector3List_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + listOfVector3 + + + +
+ + +
+ drawListOfVector3_screenspace_3Dpos_cam + drawListOfVector3_screenspace_3Dpos_cam + Draw ListOfVector3 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector3List_of_$name$ = ; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, vector3List_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + listOfVector3 + + + +
+ + +
+ drawListOfVector3_screenspace_2Dpos + drawListOfVector3_screenspace_2Dpos + Draw ListOfVector3 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + vector3List_of_$name$ = $end$; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(vector3List_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + listOfVector3 + + + +
+ + +
+ drawListOfVector3_screenspace_2Dpos_cam + drawListOfVector3_screenspace_2Dpos_cam + Draw ListOfVector3 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector3List_of_$name$ = ; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, vector3List_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + listOfVector3 + + + +
+ + +
+ drawArrayOfVector4 + drawArrayOfVector4 + Draw ArrayOfVector4 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + arrayOfVector4 + + + +
+ + +
+ drawArrayOfVector4_in2D + drawArrayOfVector4_in2D + Draw ArrayOfVector4 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + arrayOfVector4 + + + +
+ + +
+ drawArrayOfVector4_screenspace_3Dpos + drawArrayOfVector4_screenspace_3Dpos + Draw ArrayOfVector4 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + arrayOfVector4 + + + +
+ + +
+ drawArrayOfVector4_screenspace_3Dpos_cam + drawArrayOfVector4_screenspace_3Dpos_cam + Draw ArrayOfVector4 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + arrayOfVector4 + + + +
+ + +
+ drawArrayOfVector4_screenspace_2Dpos + drawArrayOfVector4_screenspace_2Dpos + Draw ArrayOfVector4 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + arrayOfVector4 + + + +
+ + +
+ drawArrayOfVector4_screenspace_2Dpos_cam + drawArrayOfVector4_screenspace_2Dpos_cam + Draw ArrayOfVector4 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + arrayOfVector4 + + + +
+ + +
+ drawListOfVector4 + drawListOfVector4 + Draw ListOfVector4 in the Unity Editor. + Draw XXL +
+ + + vector4List_of_$name$ = $end$; + Vector3 position_of_$name$ = default(Vector3); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + Quaternion rotation_of_$name$ = default(Quaternion); + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList(vector4List_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, rotation_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + listOfVector4 + + + +
+ + +
+ drawListOfVector4_in2D + drawListOfVector4_in2D + Draw ListOfVector4 in the Unity Editor. + Draw XXL +
+ + + vector4List_of_$name$ = $end$; + Vector2 position_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_of_$name$ = 0.05f; + float forceHeightOfWholeTableBox_of_$name$ = 0.0f; + float custom_zPos_of_$name$ = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft_of_$name$ = true; + float durationInSec_of_$name$ = 0.0f; + bool hiddenByNearerObjects_of_$name$ = true; + DrawText.WriteList2D(vector4List_of_$name$, position_of_$name$, color_of_$name$, title_of_$name$, textSize_of_$name$, forceHeightOfWholeTableBox_of_$name$, custom_zPos_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$, hiddenByNearerObjects_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + listOfVector4 + + + +
+ + +
+ drawListOfVector4_screenspace_3Dpos + drawListOfVector4_screenspace_3Dpos + Draw ListOfVector4 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + vector4List_of_$name$ = $end$; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(vector4List_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + listOfVector4 + + + +
+ + +
+ drawListOfVector4_screenspace_3Dpos_cam + drawListOfVector4_screenspace_3Dpos_cam + Draw ListOfVector4 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector4List_of_$name$ = ; + Vector3 position_in3DWorldspace_of_$name$ = ; + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, vector4List_of_$name$, position_in3DWorldspace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + listOfVector4 + + + +
+ + +
+ drawListOfVector4_screenspace_2Dpos + drawListOfVector4_screenspace_2Dpos + Draw ListOfVector4 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + vector4List_of_$name$ = $end$; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(vector4List_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + listOfVector4 + + + +
+ + +
+ drawListOfVector4_screenspace_2Dpos_cam + drawListOfVector4_screenspace_2Dpos_cam + Draw ListOfVector4 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector4List_of_$name$ = ; + Vector2 position_in2DViewportSpace_of_$name$ = default(Vector2); + Color color_of_$name$ = default(Color); + string title_of_$name$ = null; + float textSize_relToViewportHeight_of_$name$ = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight_of_$name$ = 0.0f; + bool position_isTopLeft_notLowLeft_of_$name$ = false; + float durationInSec_of_$name$ = 0.0f; + DrawText.WriteListScreenspace(screenCamera_of_$name$, vector4List_of_$name$, position_in2DViewportSpace_of_$name$, color_of_$name$, title_of_$name$, textSize_relToViewportHeight_of_$name$, forceHeightOfWholeTableBox_relToViewportHeight_of_$name$, position_isTopLeft_notLowLeft_of_$name$, durationInSec_of_$name$); + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + listOfVector4 + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawText.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawText.snippet.meta new file mode 100644 index 0000000..9cb21d0 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawText.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2879fc731d36c254485ca450810e577b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/DrawDebugLibrary/code snippets/drawText_func.snippet b/Editor/DrawDebugLibrary/code snippets/drawText_func.snippet new file mode 100644 index 0000000..c8c5145 --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawText_func.snippet @@ -0,0 +1,4941 @@ + + + +
+ drawTextScreenspace_3Dpos_dirViaVec_func + drawTextScreenspace_3Dpos_dirViaVec_func + Encapsulated in a function: Draw TextScreenspace in the Unity Editor. (position defined in 3D worldspace) (text direction defined via vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + WithThisName + + + +
+ + +
+ drawTextScreenspace_3Dpos_dirViaVec_cam_func + drawTextScreenspace_3Dpos_dirViaVec_cam_func + Encapsulated in a function: Draw TextScreenspace in the Unity Editor. (position defined in 3D worldspace) (text direction defined via vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + WithThisName + + + +
+ + +
+ drawTextScreenspace_2Dpos_dirViaVec_func + drawTextScreenspace_2Dpos_dirViaVec_func + Encapsulated in a function: Draw TextScreenspace in the Unity Editor. (position defined in 2D screenspace) (text direction defined via vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + WithThisName + + + +
+ + +
+ drawTextScreenspace_2Dpos_dirViaVec_cam_func + drawTextScreenspace_2Dpos_dirViaVec_cam_func + Encapsulated in a function: Draw TextScreenspace in the Unity Editor. (position defined in 2D screenspace) (text direction defined via vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + WithThisName + + + +
+ + +
+ drawTextScreenspaceFramed_3Dpos_dirViaVec_func + drawTextScreenspaceFramed_3Dpos_dirViaVec_func + Encapsulated in a function: Draw TextScreenspaceFramed in the Unity Editor. (position defined in 3D worldspace) (text direction defined via vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + WithThisName + + + +
+ + +
+ drawTextScreenspaceFramed_3Dpos_dirViaVec_cam_func + drawTextScreenspaceFramed_3Dpos_dirViaVec_cam_func + Encapsulated in a function: Draw TextScreenspaceFramed in the Unity Editor. (position defined in 3D worldspace) (text direction defined via vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + WithThisName + + + +
+ + +
+ drawTextScreenspaceFramed_2Dpos_dirViaVec_func + drawTextScreenspaceFramed_2Dpos_dirViaVec_func + Encapsulated in a function: Draw TextScreenspaceFramed in the Unity Editor. (position defined in 2D screenspace) (text direction defined via vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + WithThisName + + + +
+ + +
+ drawTextScreenspaceFramed_2Dpos_dirViaVec_cam_func + drawTextScreenspaceFramed_2Dpos_dirViaVec_cam_func + Encapsulated in a function: Draw TextScreenspaceFramed in the Unity Editor. (position defined in 2D screenspace) (text direction defined via vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + WithThisName + + + +
+ + +
+ drawTextScreenspace_3Dpos_dirViaAngle_func + drawTextScreenspace_3Dpos_dirViaAngle_func + Encapsulated in a function: Draw TextScreenspace in the Unity Editor. (position defined in 3D worldspace) (text direction defined via angle) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + WithThisName + + + +
+ + +
+ drawTextScreenspace_3Dpos_dirViaAngle_cam_func + drawTextScreenspace_3Dpos_dirViaAngle_cam_func + Encapsulated in a function: Draw TextScreenspace in the Unity Editor. (position defined in 3D worldspace) (text direction defined via angle) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + WithThisName + + + +
+ + +
+ drawTextScreenspace_2Dpos_dirViaAngle_func + drawTextScreenspace_2Dpos_dirViaAngle_func + Encapsulated in a function: Draw TextScreenspace in the Unity Editor. (position defined in 2D screenspace) (text direction defined via angle) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + WithThisName + + + +
+ + +
+ drawTextScreenspace_2Dpos_dirViaAngle_cam_func + drawTextScreenspace_2Dpos_dirViaAngle_cam_func + Encapsulated in a function: Draw TextScreenspace in the Unity Editor. (position defined in 2D screenspace) (text direction defined via angle) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspace + WithThisName + + + +
+ + +
+ drawTextScreenspaceFramed_3Dpos_dirViaAngle_func + drawTextScreenspaceFramed_3Dpos_dirViaAngle_func + Encapsulated in a function: Draw TextScreenspaceFramed in the Unity Editor. (position defined in 3D worldspace) (text direction defined via angle) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + WithThisName + + + +
+ + +
+ drawTextScreenspaceFramed_3Dpos_dirViaAngle_cam_func + drawTextScreenspaceFramed_3Dpos_dirViaAngle_cam_func + Encapsulated in a function: Draw TextScreenspaceFramed in the Unity Editor. (position defined in 3D worldspace) (text direction defined via angle) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + WithThisName + + + +
+ + +
+ drawTextScreenspaceFramed_2Dpos_dirViaAngle_func + drawTextScreenspaceFramed_2Dpos_dirViaAngle_func + Encapsulated in a function: Draw TextScreenspaceFramed in the Unity Editor. (position defined in 2D screenspace) (text direction defined via angle) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + WithThisName + + + +
+ + +
+ drawTextScreenspaceFramed_2Dpos_dirViaAngle_cam_func + drawTextScreenspaceFramed_2Dpos_dirViaAngle_cam_func + Encapsulated in a function: Draw TextScreenspaceFramed in the Unity Editor. (position defined in 2D screenspace) (text direction defined via angle) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextScreenspaceFramed + WithThisName + + + +
+ + +
+ drawText2D_dirViaVec_func + drawText2D_dirViaVec_func + Encapsulated in a function: Draw Text2D in the Unity Editor. (text direction defined via vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text2D + WithThisName + + + +
+ + +
+ drawText2DFramed_dirViaVec_func + drawText2DFramed_dirViaVec_func + Encapsulated in a function: Draw Text2DFramed in the Unity Editor. (text direction defined via vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text2DFramed + WithThisName + + + +
+ + +
+ drawText2D_dirViaAngle_func + drawText2D_dirViaAngle_func + Encapsulated in a function: Draw Text2D in the Unity Editor. (text direction defined via angle) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text2D + WithThisName + + + +
+ + +
+ drawText2DFramed_dirViaAngle_func + drawText2DFramed_dirViaAngle_func + Encapsulated in a function: Draw Text2DFramed in the Unity Editor. (text direction defined via angle) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text2DFramed + WithThisName + + + +
+ + +
+ drawText_dirViaQuat_func + drawText_dirViaQuat_func + Encapsulated in a function: Draw Text in the Unity Editor. (text direction defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text + WithThisName + + + +
+ + +
+ drawTextFramed_dirViaQuat_func + drawTextFramed_dirViaQuat_func + Encapsulated in a function: Draw TextFramed in the Unity Editor. (text direction defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextFramed + WithThisName + + + +
+ + +
+ drawText_dirViaVec_func + drawText_dirViaVec_func + Encapsulated in a function: Draw Text in the Unity Editor. (text direction defined via vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn Text + WithThisName + + + +
+ + +
+ drawTextFramed_dirViaVec_func + drawTextFramed_dirViaVec_func + Encapsulated in a function: Draw TextFramed in the Unity Editor. (text direction defined via vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextFramed + WithThisName + + + +
+ + +
+ drawTextOnCircleScreenspace_viaStartPos_func + drawTextOnCircleScreenspace_viaStartPos_func + Encapsulated in a function: Draw TextOnCircleScreenspace in the Unity Editor. (defined via text start position, instead of circle center position) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + WithThisName + + + +
+ + +
+ drawTextOnCircleScreenspace_viaStartPos_cam_func + drawTextOnCircleScreenspace_viaStartPos_cam_func + Encapsulated in a function: Draw TextOnCircleScreenspace in the Unity Editor. (defined via text start position, instead of circle center position) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + WithThisName + + + +
+ + +
+ drawTextOnCircleScreenspace_dirViaVecUp_func + drawTextOnCircleScreenspace_dirViaVecUp_func + Encapsulated in a function: Draw TextOnCircleScreenspace in the Unity Editor. (text initial upDirection defined via vector) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + WithThisName + + + +
+ + +
+ drawTextOnCircleScreenspace_dirViaVecUp_cam_func + drawTextOnCircleScreenspace_dirViaVecUp_cam_func + Encapsulated in a function: Draw TextOnCircleScreenspace in the Unity Editor. (text initial upDirection defined via vector) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + WithThisName + + + +
+ + +
+ drawTextOnCircleScreenspace_dirViaAngle_func + drawTextOnCircleScreenspace_dirViaAngle_func + Encapsulated in a function: Draw TextOnCircleScreenspace in the Unity Editor. (initial text direction defined via angle) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + WithThisName + + + +
+ + +
+ drawTextOnCircleScreenspace_dirViaAngle_cam_func + drawTextOnCircleScreenspace_dirViaAngle_cam_func + Encapsulated in a function: Draw TextOnCircleScreenspace in the Unity Editor. (initial text direction defined via angle) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircleScreenspace + WithThisName + + + +
+ + +
+ drawTextOnCircle2D_viaStartPos_func + drawTextOnCircle2D_viaStartPos_func + Encapsulated in a function: Draw TextOnCircle2D in the Unity Editor. (defined via text start position, instead of circle center position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle2D + WithThisName + + + +
+ + +
+ drawTextOnCircle2D_dirViaVecUp_func + drawTextOnCircle2D_dirViaVecUp_func + Encapsulated in a function: Draw TextOnCircle2D in the Unity Editor. (text initial upDirection defined via vector) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle2D + WithThisName + + + +
+ + +
+ drawTextOnCircle2D_dirViaAngle_func + drawTextOnCircle2D_dirViaAngle_func + Encapsulated in a function: Draw TextOnCircle2D in the Unity Editor. (initial text direction defined via angle) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle2D + WithThisName + + + +
+ + +
+ drawTextOnCircle_viaStartPos_func + drawTextOnCircle_viaStartPos_func + Encapsulated in a function: Draw TextOnCircle in the Unity Editor. (defined via text start position, instead of circle center position) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle + WithThisName + + + +
+ + +
+ drawTextOnCircle_viaQuat_func + drawTextOnCircle_viaQuat_func + Encapsulated in a function: Draw TextOnCircle in the Unity Editor. (orientation defined via quaternion) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle + WithThisName + + + +
+ + +
+ drawTextOnCircle_viaVec_func + drawTextOnCircle_viaVec_func + Encapsulated in a function: Draw TextOnCircle in the Unity Editor. (orientation defined via vectors) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn TextOnCircle + WithThisName + + + +
+ + +
+ drawArrayOfBool_func + drawArrayOfBool_func + Encapsulated in a function: Draw ArrayOfBool in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + WithThisName + + + +
+ + +
+ drawArrayOfBool_in2D_func + drawArrayOfBool_in2D_func + Encapsulated in a function: Draw ArrayOfBool in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + WithThisName + + + +
+ + +
+ drawArrayOfBool_screenspace_3Dpos_func + drawArrayOfBool_screenspace_3Dpos_func + Encapsulated in a function: Draw ArrayOfBool in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + WithThisName + + + +
+ + +
+ drawArrayOfBool_screenspace_3Dpos_cam_func + drawArrayOfBool_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ArrayOfBool in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + WithThisName + + + +
+ + +
+ drawArrayOfBool_screenspace_2Dpos_func + drawArrayOfBool_screenspace_2Dpos_func + Encapsulated in a function: Draw ArrayOfBool in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + WithThisName + + + +
+ + +
+ drawArrayOfBool_screenspace_2Dpos_cam_func + drawArrayOfBool_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ArrayOfBool in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfBool + WithThisName + + + +
+ + +
+ drawListOfBool_func + drawListOfBool_func + Encapsulated in a function: Draw ListOfBool in the Unity Editor. + Draw XXL +
+ + + boolList = $end$; + Vector3 position = default(Vector3); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + Quaternion rotation = default(Quaternion); + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList(boolList, position, color, title, textSize, forceHeightOfWholeTableBox, rotation, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + WithThisName + + + +
+ + +
+ drawListOfBool_in2D_func + drawListOfBool_in2D_func + Encapsulated in a function: Draw ListOfBool in the Unity Editor. + Draw XXL +
+ + + boolList = $end$; + Vector2 position = default(Vector2); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + float custom_zPos = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList2D(boolList, position, color, title, textSize, forceHeightOfWholeTableBox, custom_zPos, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + WithThisName + + + +
+ + +
+ drawListOfBool_screenspace_3Dpos_func + drawListOfBool_screenspace_3Dpos_func + Encapsulated in a function: Draw ListOfBool in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + boolList = $end$; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(boolList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + WithThisName + + + +
+ + +
+ drawListOfBool_screenspace_3Dpos_cam_func + drawListOfBool_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ListOfBool in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + boolList = ; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, boolList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + WithThisName + + + +
+ + +
+ drawListOfBool_screenspace_2Dpos_func + drawListOfBool_screenspace_2Dpos_func + Encapsulated in a function: Draw ListOfBool in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + boolList = $end$; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(boolList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + WithThisName + + + +
+ + +
+ drawListOfBool_screenspace_2Dpos_cam_func + drawListOfBool_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ListOfBool in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + boolList = ; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, boolList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfBool + WithThisName + + + +
+ + +
+ drawArrayOfInt_func + drawArrayOfInt_func + Encapsulated in a function: Draw ArrayOfInt in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + WithThisName + + + +
+ + +
+ drawArrayOfInt_in2D_func + drawArrayOfInt_in2D_func + Encapsulated in a function: Draw ArrayOfInt in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + WithThisName + + + +
+ + +
+ drawArrayOfInt_screenspace_3Dpos_func + drawArrayOfInt_screenspace_3Dpos_func + Encapsulated in a function: Draw ArrayOfInt in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + WithThisName + + + +
+ + +
+ drawArrayOfInt_screenspace_3Dpos_cam_func + drawArrayOfInt_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ArrayOfInt in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + WithThisName + + + +
+ + +
+ drawArrayOfInt_screenspace_2Dpos_func + drawArrayOfInt_screenspace_2Dpos_func + Encapsulated in a function: Draw ArrayOfInt in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + WithThisName + + + +
+ + +
+ drawArrayOfInt_screenspace_2Dpos_cam_func + drawArrayOfInt_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ArrayOfInt in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfInt + WithThisName + + + +
+ + +
+ drawListOfInt_func + drawListOfInt_func + Encapsulated in a function: Draw ListOfInt in the Unity Editor. + Draw XXL +
+ + + intList = $end$; + Vector3 position = default(Vector3); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + Quaternion rotation = default(Quaternion); + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList(intList, position, color, title, textSize, forceHeightOfWholeTableBox, rotation, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + WithThisName + + + +
+ + +
+ drawListOfInt_in2D_func + drawListOfInt_in2D_func + Encapsulated in a function: Draw ListOfInt in the Unity Editor. + Draw XXL +
+ + + intList = $end$; + Vector2 position = default(Vector2); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + float custom_zPos = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList2D(intList, position, color, title, textSize, forceHeightOfWholeTableBox, custom_zPos, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + WithThisName + + + +
+ + +
+ drawListOfInt_screenspace_3Dpos_func + drawListOfInt_screenspace_3Dpos_func + Encapsulated in a function: Draw ListOfInt in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + intList = $end$; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(intList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + WithThisName + + + +
+ + +
+ drawListOfInt_screenspace_3Dpos_cam_func + drawListOfInt_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ListOfInt in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + intList = ; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, intList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + WithThisName + + + +
+ + +
+ drawListOfInt_screenspace_2Dpos_func + drawListOfInt_screenspace_2Dpos_func + Encapsulated in a function: Draw ListOfInt in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + intList = $end$; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(intList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + WithThisName + + + +
+ + +
+ drawListOfInt_screenspace_2Dpos_cam_func + drawListOfInt_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ListOfInt in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + intList = ; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, intList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfInt + WithThisName + + + +
+ + +
+ drawArrayOfFloat_func + drawArrayOfFloat_func + Encapsulated in a function: Draw ArrayOfFloat in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + WithThisName + + + +
+ + +
+ drawArrayOfFloat_in2D_func + drawArrayOfFloat_in2D_func + Encapsulated in a function: Draw ArrayOfFloat in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + WithThisName + + + +
+ + +
+ drawArrayOfFloat_screenspace_3Dpos_func + drawArrayOfFloat_screenspace_3Dpos_func + Encapsulated in a function: Draw ArrayOfFloat in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + WithThisName + + + +
+ + +
+ drawArrayOfFloat_screenspace_3Dpos_cam_func + drawArrayOfFloat_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ArrayOfFloat in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + WithThisName + + + +
+ + +
+ drawArrayOfFloat_screenspace_2Dpos_func + drawArrayOfFloat_screenspace_2Dpos_func + Encapsulated in a function: Draw ArrayOfFloat in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + WithThisName + + + +
+ + +
+ drawArrayOfFloat_screenspace_2Dpos_cam_func + drawArrayOfFloat_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ArrayOfFloat in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfFloat + WithThisName + + + +
+ + +
+ drawListOfFloat_func + drawListOfFloat_func + Encapsulated in a function: Draw ListOfFloat in the Unity Editor. + Draw XXL +
+ + + floatList = $end$; + Vector3 position = default(Vector3); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + Quaternion rotation = default(Quaternion); + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList(floatList, position, color, title, textSize, forceHeightOfWholeTableBox, rotation, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + WithThisName + + + +
+ + +
+ drawListOfFloat_in2D_func + drawListOfFloat_in2D_func + Encapsulated in a function: Draw ListOfFloat in the Unity Editor. + Draw XXL +
+ + + floatList = $end$; + Vector2 position = default(Vector2); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + float custom_zPos = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList2D(floatList, position, color, title, textSize, forceHeightOfWholeTableBox, custom_zPos, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + WithThisName + + + +
+ + +
+ drawListOfFloat_screenspace_3Dpos_func + drawListOfFloat_screenspace_3Dpos_func + Encapsulated in a function: Draw ListOfFloat in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + floatList = $end$; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(floatList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + WithThisName + + + +
+ + +
+ drawListOfFloat_screenspace_3Dpos_cam_func + drawListOfFloat_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ListOfFloat in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + floatList = ; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, floatList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + WithThisName + + + +
+ + +
+ drawListOfFloat_screenspace_2Dpos_func + drawListOfFloat_screenspace_2Dpos_func + Encapsulated in a function: Draw ListOfFloat in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + floatList = $end$; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(floatList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + WithThisName + + + +
+ + +
+ drawListOfFloat_screenspace_2Dpos_cam_func + drawListOfFloat_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ListOfFloat in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + floatList = ; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, floatList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfFloat + WithThisName + + + +
+ + +
+ drawArrayOfString_func + drawArrayOfString_func + Encapsulated in a function: Draw ArrayOfString in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + WithThisName + + + +
+ + +
+ drawArrayOfString_in2D_func + drawArrayOfString_in2D_func + Encapsulated in a function: Draw ArrayOfString in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + WithThisName + + + +
+ + +
+ drawArrayOfString_screenspace_3Dpos_func + drawArrayOfString_screenspace_3Dpos_func + Encapsulated in a function: Draw ArrayOfString in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + WithThisName + + + +
+ + +
+ drawArrayOfString_screenspace_3Dpos_cam_func + drawArrayOfString_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ArrayOfString in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + WithThisName + + + +
+ + +
+ drawArrayOfString_screenspace_2Dpos_func + drawArrayOfString_screenspace_2Dpos_func + Encapsulated in a function: Draw ArrayOfString in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + WithThisName + + + +
+ + +
+ drawArrayOfString_screenspace_2Dpos_cam_func + drawArrayOfString_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ArrayOfString in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfString + WithThisName + + + +
+ + +
+ drawListOfString_func + drawListOfString_func + Encapsulated in a function: Draw ListOfString in the Unity Editor. + Draw XXL +
+ + + stringList = $end$; + Vector3 position = default(Vector3); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + Quaternion rotation = default(Quaternion); + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList(stringList, position, color, title, textSize, forceHeightOfWholeTableBox, rotation, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + WithThisName + + + +
+ + +
+ drawListOfString_in2D_func + drawListOfString_in2D_func + Encapsulated in a function: Draw ListOfString in the Unity Editor. + Draw XXL +
+ + + stringList = $end$; + Vector2 position = default(Vector2); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + float custom_zPos = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList2D(stringList, position, color, title, textSize, forceHeightOfWholeTableBox, custom_zPos, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + WithThisName + + + +
+ + +
+ drawListOfString_screenspace_3Dpos_func + drawListOfString_screenspace_3Dpos_func + Encapsulated in a function: Draw ListOfString in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + stringList = $end$; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(stringList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + WithThisName + + + +
+ + +
+ drawListOfString_screenspace_3Dpos_cam_func + drawListOfString_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ListOfString in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + stringList = ; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, stringList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + WithThisName + + + +
+ + +
+ drawListOfString_screenspace_2Dpos_func + drawListOfString_screenspace_2Dpos_func + Encapsulated in a function: Draw ListOfString in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + stringList = $end$; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(stringList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + WithThisName + + + +
+ + +
+ drawListOfString_screenspace_2Dpos_cam_func + drawListOfString_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ListOfString in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + stringList = ; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, stringList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfString + WithThisName + + + +
+ + +
+ drawArrayOfVector2_func + drawArrayOfVector2_func + Encapsulated in a function: Draw ArrayOfVector2 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + WithThisName + + + +
+ + +
+ drawArrayOfVector2_in2D_func + drawArrayOfVector2_in2D_func + Encapsulated in a function: Draw ArrayOfVector2 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + WithThisName + + + +
+ + +
+ drawArrayOfVector2_screenspace_3Dpos_func + drawArrayOfVector2_screenspace_3Dpos_func + Encapsulated in a function: Draw ArrayOfVector2 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + WithThisName + + + +
+ + +
+ drawArrayOfVector2_screenspace_3Dpos_cam_func + drawArrayOfVector2_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ArrayOfVector2 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + WithThisName + + + +
+ + +
+ drawArrayOfVector2_screenspace_2Dpos_func + drawArrayOfVector2_screenspace_2Dpos_func + Encapsulated in a function: Draw ArrayOfVector2 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + WithThisName + + + +
+ + +
+ drawArrayOfVector2_screenspace_2Dpos_cam_func + drawArrayOfVector2_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ArrayOfVector2 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector2 + WithThisName + + + +
+ + +
+ drawListOfVector2_func + drawListOfVector2_func + Encapsulated in a function: Draw ListOfVector2 in the Unity Editor. + Draw XXL +
+ + + vector2List = $end$; + Vector3 position = default(Vector3); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + Quaternion rotation = default(Quaternion); + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList(vector2List, position, color, title, textSize, forceHeightOfWholeTableBox, rotation, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + WithThisName + + + +
+ + +
+ drawListOfVector2_in2D_func + drawListOfVector2_in2D_func + Encapsulated in a function: Draw ListOfVector2 in the Unity Editor. + Draw XXL +
+ + + vector2List = $end$; + Vector2 position = default(Vector2); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + float custom_zPos = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList2D(vector2List, position, color, title, textSize, forceHeightOfWholeTableBox, custom_zPos, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + WithThisName + + + +
+ + +
+ drawListOfVector2_screenspace_3Dpos_func + drawListOfVector2_screenspace_3Dpos_func + Encapsulated in a function: Draw ListOfVector2 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + vector2List = $end$; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(vector2List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + WithThisName + + + +
+ + +
+ drawListOfVector2_screenspace_3Dpos_cam_func + drawListOfVector2_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ListOfVector2 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector2List = ; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, vector2List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + WithThisName + + + +
+ + +
+ drawListOfVector2_screenspace_2Dpos_func + drawListOfVector2_screenspace_2Dpos_func + Encapsulated in a function: Draw ListOfVector2 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + vector2List = $end$; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(vector2List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + WithThisName + + + +
+ + +
+ drawListOfVector2_screenspace_2Dpos_cam_func + drawListOfVector2_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ListOfVector2 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector2List = ; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, vector2List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector2 + WithThisName + + + +
+ + +
+ drawArrayOfVector3_func + drawArrayOfVector3_func + Encapsulated in a function: Draw ArrayOfVector3 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + WithThisName + + + +
+ + +
+ drawArrayOfVector3_in2D_func + drawArrayOfVector3_in2D_func + Encapsulated in a function: Draw ArrayOfVector3 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + WithThisName + + + +
+ + +
+ drawArrayOfVector3_screenspace_3Dpos_func + drawArrayOfVector3_screenspace_3Dpos_func + Encapsulated in a function: Draw ArrayOfVector3 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + WithThisName + + + +
+ + +
+ drawArrayOfVector3_screenspace_3Dpos_cam_func + drawArrayOfVector3_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ArrayOfVector3 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + WithThisName + + + +
+ + +
+ drawArrayOfVector3_screenspace_2Dpos_func + drawArrayOfVector3_screenspace_2Dpos_func + Encapsulated in a function: Draw ArrayOfVector3 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + WithThisName + + + +
+ + +
+ drawArrayOfVector3_screenspace_2Dpos_cam_func + drawArrayOfVector3_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ArrayOfVector3 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector3 + WithThisName + + + +
+ + +
+ drawListOfVector3_func + drawListOfVector3_func + Encapsulated in a function: Draw ListOfVector3 in the Unity Editor. + Draw XXL +
+ + + vector3List = $end$; + Vector3 position = default(Vector3); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + Quaternion rotation = default(Quaternion); + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList(vector3List, position, color, title, textSize, forceHeightOfWholeTableBox, rotation, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + WithThisName + + + +
+ + +
+ drawListOfVector3_in2D_func + drawListOfVector3_in2D_func + Encapsulated in a function: Draw ListOfVector3 in the Unity Editor. + Draw XXL +
+ + + vector3List = $end$; + Vector2 position = default(Vector2); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + float custom_zPos = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList2D(vector3List, position, color, title, textSize, forceHeightOfWholeTableBox, custom_zPos, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + WithThisName + + + +
+ + +
+ drawListOfVector3_screenspace_3Dpos_func + drawListOfVector3_screenspace_3Dpos_func + Encapsulated in a function: Draw ListOfVector3 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + vector3List = $end$; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(vector3List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + WithThisName + + + +
+ + +
+ drawListOfVector3_screenspace_3Dpos_cam_func + drawListOfVector3_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ListOfVector3 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector3List = ; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, vector3List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + WithThisName + + + +
+ + +
+ drawListOfVector3_screenspace_2Dpos_func + drawListOfVector3_screenspace_2Dpos_func + Encapsulated in a function: Draw ListOfVector3 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + vector3List = $end$; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(vector3List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + WithThisName + + + +
+ + +
+ drawListOfVector3_screenspace_2Dpos_cam_func + drawListOfVector3_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ListOfVector3 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector3List = ; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, vector3List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector3 + WithThisName + + + +
+ + +
+ drawArrayOfVector4_func + drawArrayOfVector4_func + Encapsulated in a function: Draw ArrayOfVector4 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + WithThisName + + + +
+ + +
+ drawArrayOfVector4_in2D_func + drawArrayOfVector4_in2D_func + Encapsulated in a function: Draw ArrayOfVector4 in the Unity Editor. + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + WithThisName + + + +
+ + +
+ drawArrayOfVector4_screenspace_3Dpos_func + drawArrayOfVector4_screenspace_3Dpos_func + Encapsulated in a function: Draw ArrayOfVector4 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + WithThisName + + + +
+ + +
+ drawArrayOfVector4_screenspace_3Dpos_cam_func + drawArrayOfVector4_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ArrayOfVector4 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + WithThisName + + + +
+ + +
+ drawArrayOfVector4_screenspace_2Dpos_func + drawArrayOfVector4_screenspace_2Dpos_func + Encapsulated in a function: Draw ArrayOfVector4 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + WithThisName + + + +
+ + +
+ drawArrayOfVector4_screenspace_2Dpos_cam_func + drawArrayOfVector4_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ArrayOfVector4 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + + + + + DrawXXL + + + + + name + Name of drawn ArrayOfVector4 + WithThisName + + + +
+ + +
+ drawListOfVector4_func + drawListOfVector4_func + Encapsulated in a function: Draw ListOfVector4 in the Unity Editor. + Draw XXL +
+ + + vector4List = $end$; + Vector3 position = default(Vector3); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + Quaternion rotation = default(Quaternion); + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList(vector4List, position, color, title, textSize, forceHeightOfWholeTableBox, rotation, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + WithThisName + + + +
+ + +
+ drawListOfVector4_in2D_func + drawListOfVector4_in2D_func + Encapsulated in a function: Draw ListOfVector4 in the Unity Editor. + Draw XXL +
+ + + vector4List = $end$; + Vector2 position = default(Vector2); + Color color = default(Color); + string title = null; + float textSize = 0.05f; + float forceHeightOfWholeTableBox = 0.0f; + float custom_zPos = float.PositiveInfinity; + bool position_isTopLeft_notLowLeft = true; + float durationInSec = 0.0f; + bool hiddenByNearerObjects = true; + DrawText.WriteList2D(vector4List, position, color, title, textSize, forceHeightOfWholeTableBox, custom_zPos, position_isTopLeft_notLowLeft, durationInSec, hiddenByNearerObjects); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + WithThisName + + + +
+ + +
+ drawListOfVector4_screenspace_3Dpos_func + drawListOfVector4_screenspace_3Dpos_func + Encapsulated in a function: Draw ListOfVector4 in the Unity Editor. (position defined in 3D worldspace) (automatic detection of target camera) + Draw XXL +
+ + + vector4List = $end$; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(vector4List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + WithThisName + + + +
+ + +
+ drawListOfVector4_screenspace_3Dpos_cam_func + drawListOfVector4_screenspace_3Dpos_cam_func + Encapsulated in a function: Draw ListOfVector4 in the Unity Editor. (position defined in 3D worldspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector4List = ; + Vector3 position_in3DWorldspace = ; + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, vector4List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + WithThisName + + + +
+ + +
+ drawListOfVector4_screenspace_2Dpos_func + drawListOfVector4_screenspace_2Dpos_func + Encapsulated in a function: Draw ListOfVector4 in the Unity Editor. (position defined in 2D screenspace) (automatic detection of target camera) + Draw XXL +
+ + + vector4List = $end$; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(vector4List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + WithThisName + + + +
+ + +
+ drawListOfVector4_screenspace_2Dpos_cam_func + drawListOfVector4_screenspace_2Dpos_cam_func + Encapsulated in a function: Draw ListOfVector4 in the Unity Editor. (position defined in 2D screenspace) (explicitly defining the target camera) + Draw XXL +
+ + + vector4List = ; + Vector2 position_in2DViewportSpace = default(Vector2); + Color color = default(Color); + string title = null; + float textSize_relToViewportHeight = 0.025f; + float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f; + bool position_isTopLeft_notLowLeft = false; + float durationInSec = 0.0f; + DrawText.WriteListScreenspace(screenCamera, vector4List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + ]]> + + + + DrawXXL + + + + + name + Name of drawn ListOfVector4 + WithThisName + + + +
+ +
diff --git a/Editor/DrawDebugLibrary/code snippets/drawText_func.snippet.meta b/Editor/DrawDebugLibrary/code snippets/drawText_func.snippet.meta new file mode 100644 index 0000000..881a7dc --- /dev/null +++ b/Editor/DrawDebugLibrary/code snippets/drawText_func.snippet.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 02c5327a35011c94380ab649cf192916 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/XericLibraryEditor.dll b/Editor/XericLibraryEditor.dll index ab20fe4..a131db0 100644 Binary files a/Editor/XericLibraryEditor.dll and b/Editor/XericLibraryEditor.dll differ diff --git a/Runtime/DrawDebugLibrary.meta b/Runtime/DrawDebugLibrary.meta new file mode 100644 index 0000000..9acbc50 --- /dev/null +++ b/Runtime/DrawDebugLibrary.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bd689af0756ca4742853b83a72f12416 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawBasics.cs b/Runtime/DrawDebugLibrary/DrawBasics.cs new file mode 100644 index 0000000..de51e9c --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawBasics.cs @@ -0,0 +1,1350 @@ +namespace DrawXXL +{ + using System.Collections.Generic; + using UnityEngine; + + public class DrawBasics + { + public enum AutomaticAmplitudeAndTextAlignment + { + vertical, + perpendicularToCamera + }; + public static AutomaticAmplitudeAndTextAlignment automaticAmplitudeAndTextAlignment = AutomaticAmplitudeAndTextAlignment.vertical; + + public enum AutomaticTextDirectionOfLines + { + towardsLineEnd, + leftToRightInScreen + }; + public static AutomaticTextDirectionOfLines automaticTextDirectionOfLines = AutomaticTextDirectionOfLines.leftToRightInScreen; + + public enum CameraForAutomaticOrientation + { + sceneViewCamera, + gameViewCamera + }; + public static CameraForAutomaticOrientation cameraForAutomaticOrientation = CameraForAutomaticOrientation.sceneViewCamera; + + public enum LineStyle { solid, invisible, dotted, dottedDense, dottedWide, dashed, dashedLong, dotDash, dotDashLong, twoDash, disconnectedAnchors, spiral, sine, zigzag, rhombus, doubleRhombus, electricNoise, electricImpulses, freeHand2D, freeHand3D, arrows, alternatingColorStripes }; + + public enum BezierPosInterpretation + { + start_control1_control2_endIsNextStart, + start_control1_endIsNextStart, + onlySegmentStartPoints_backwardForwardIsAligned, + onlySegmentStartPoints_backwardForwardIsMirrored, + onlySegmentStartPoints_backwardForwardIsKinked + }; + + private static int maxAllowedDrawnLinesPerFrame = +#if UnityEditor + 60000 +#else + 200000; +#endif + public static int MaxAllowedDrawnLinesPerFrame + { + get { return maxAllowedDrawnLinesPerFrame; } + set + { + if (value < UtilitiesDXXL_DrawBasics.maxMaxAllowedDrawnLinesPerFrame) + { + maxAllowedDrawnLinesPerFrame = value; + } + else + { + Debug.LogError("The upper threshold of 'MaxAllowedDrawnLinesPerFrame' is currently " + UtilitiesDXXL_DrawBasics.maxMaxAllowedDrawnLinesPerFrame + ". You tried to set it to " + value + ". Was that intentional?"); + } + } + } + + public enum UsedUnityLineDrawingMethod + { + debugLinesInPlayMode_gizmoLinesInEditModeAndPlaymodePauses, + debugLines, + gizmoLines, + handlesLines, + wireMesh, + disabled + }; + public static UsedUnityLineDrawingMethod usedUnityLineDrawingMethod = UsedUnityLineDrawingMethod.debugLines; + + public enum LengthInterpretation { relativeToLineLength, absoluteUnits }; + public static LengthInterpretation endPlates_sizeInterpretation = LengthInterpretation.relativeToLineLength; + public static LengthInterpretation coneLength_interpretation_forStraightVectors = LengthInterpretation.relativeToLineLength; + public static LengthInterpretation coneLength_interpretation_forCircledVectors = LengthInterpretation.relativeToLineLength; + public static bool disableEndPlates_atLineStart = false; + public static bool disableEndPlates_atLineEnd = false; + + public enum MaxLinesExceededNotificationOnScreenType { ExplanationText, WarningSymbol, None }; + public static MaxLinesExceededNotificationOnScreenType maxLinesExceededNotificationOnScreenType = MaxLinesExceededNotificationOnScreenType.ExplanationText; //if you have problems with too many lines per frame and want to raise the "maxDrawnLinesPerFrame_preventingProgramFreeze"-value, then you can set this to "true". This replaces the warning text on screen which informs you of the exceeded limit with a simple warning-symbol. This saves around 7500 lines that would be used to draw the warning text which you then can use for your own draw operations. + public enum MaxLinesExceededNotificationInLogConsoleType { Error, Warning, Log, None }; + public static MaxLinesExceededNotificationInLogConsoleType maxLinesExceededNotificationInLogConsoleType = MaxLinesExceededNotificationInLogConsoleType.Error; //if you want to keep your console clean from warnings that state that you have exceeded the maxLinesPerFrameL-Limit. see also "logType_forExceededMaxLinesConsoleMessage" + + + private static float lineLength_aboveWhichToAutoEnlargeThePattern = 20.0f; //this prevents high computational effort for long lines that have a very fine grained pattern, which would result in drawing many single lines to compose the long patterned line. + //static float lineLengthSqr_aboveWhichToAutoEnlargeThePattern = lineLength_aboveWhichToAutoEnlargeThePattern * lineLength_aboveWhichToAutoEnlargeThePattern; //not precalculated, so that "lineLength_aboveWhichToAutoEnlargeThePattern" can be changed during runtime + public static float LineLength_aboveWhichToAutoEnlargeThePattern + { + get { return lineLength_aboveWhichToAutoEnlargeThePattern; } + set + { + lineLength_aboveWhichToAutoEnlargeThePattern = Mathf.Max(value, 0.1f); + } + } + + public static bool autoEnlargeBigPatternsLater_whichDistortsPatternSizeRatios = false; + public static Color defaultColor = Color.white; + public static Color defaultColor2_ofAlternatingColorLines = UtilitiesDXXL_Colors.red_boolFalse; + public static float thinestPossibleNonZeroWidthLine = 0.00005f; + + private static float density_ofThickLines = 100.0f; + public static float Density_ofThickLines + { + get { return density_ofThickLines; } + set + { + density_ofThickLines = value; + UtilitiesDXXL_DrawBasics.lowThreshold_ofLineWidth_forNumberOfThinLinesThatComposeTheThickLine = 0.6f / value; + } + } + + private static float stylePatternScaleFactor_alongLineDir_ignoringAmplitude = 1.0f; + public static float StylePatternScaleFactor_alongLineDir_ignoringAmplitude //Many line drawing function have a parameter called "stylePatternScaleFactor" (e.g. DrawBasics.Line), which can be used to scale line styles (link zu lineStyle-global enum)), so that they remain well recognizable even for far view distances. It keeps the general shape of the pattern, but only scales its size. Additionally to these "stylePatternScaleFactor" parameters there is the global setting "StylePatternScaleFactor_alongLineDir_ignoringAmplitude". This also scales the line styles, but only along the line direction, while the amplitude remains the same. It can be used e.g. to change the winding density of a spiral line. Both patternScaleFactors can also be used in conjunction. + { + get { return stylePatternScaleFactor_alongLineDir_ignoringAmplitude; } + set + { + if (UtilitiesDXXL_Math.FloatIsValid(value)) + { + stylePatternScaleFactor_alongLineDir_ignoringAmplitude = Mathf.Max(value, 0.01f); + } + else + { + Debug.LogError("Cannot set 'StylePatternScaleFactor_alongLineDir_ignoringAmplitude' to the invalid value of " + value); + } + } + } + + + private static Vector3 default_textOffsetDirection_forPointTags = UtilitiesDXXL_DrawBasics.default_default_textOffsetDirection_forPointTags; + public static Vector3 Default_textOffsetDirection_forPointTags //This is used by "DrawBasics.PointTag()" and "DrawBasics2D.PointTag()", if the "textOffsetDirection" parameter is not specified. It works in conjunction with "DrawText.automaticTextOrientation". That means: The z component should be 0 in most cases, which results in effectively a 2D vector inside the xy-plane. This 2D vector is then automatically rotated to fit the desired workflow as specified by "DrawText.automaticTextOrientation", e.g. rotated to screenspace if "DrawText.automaticTextOrientation" is at its default setting of of "screen". A z value would change the vector direction perpendicular to the 2D plane which "DrawText.automaticTextOrientation" specifies. "DrawBasics2D.PointTag()" ignores the z component in any case. The length of the vector is ignored. Only the direction has effect. + { + get { return default_textOffsetDirection_forPointTags; } + set + { + if (UtilitiesDXXL_Math.ApproximatelyZero(value)) + { + Debug.LogError("Cannot set 'default_textOffsetDirection_forPointTags' to zero."); + } + else + { + default_textOffsetDirection_forPointTags = value; + } + } + } + + public static bool drawerComponentsAutomaticallyProceedOneFrameStepOnPauseStarts_toPreventFrozenOverlayDraw = false; //With this setting you can change the behaviour of drawing components, that seem to draw twice when pausing a game. For example if you use a Text Drawer Component and write "some test text", then pause the game and change the text to "another test text", then both is displayed ("some test text" and "another test text") seemingly as overlay. The reason for this is that Draw XXL components use Debug.DrawLine() for drawing when the game runs and Gizmo.DrawLine() when the game pauses. Otherwise the drawing could not be changed during pauses. Though lines from Debug.DrawLine() don't get cleared during pauses, instead they remain fixed until the pause ends. With this setting it is possible to prevent that overlay, because the drawer components(link) automatically proceed one frame when the game is paused, in which they skip the drawing with Debug.DrawLine(), so that it is not displayed during the game pause.

// If this is enabled and you have a Draw XXL drawer component in your Scene, then everytime the game pauses it will automatically perform an additional "proceed one frame step", as it can also be done by the right one of the three play/pause-buttons on the upper end inside the Unity Editor. For cases where you want to pause the game at a specific defined frame (via Debug.Break() somewhere in your code) and this is enabled, then your game pause actually ends up one frame later. If you want to end up in the frame where you called your Debug.Break() then you should leave this setting at its default disabled state. // see also "DrawCharts.chartInspectorComponentsAutomaticallyProceedOneFrameStepOnPauseStarts_toPreventFrozenOverlayDraw" which does the same for Chart Inspector components. + public static int strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM = 0; //This can be set before drawing point visualizations via "Point","PointLocal","PointArray" or "PointList" (etc.), but not the equivalents in "DrawScreenspace"). The coordiante values that are drawn as text alongside these point visualization will use this value for their stroke width, given that the "drawCoordsAsText" parameter is active. It can be useful in busy environments with lots of lines that intersect and protrude each other so that the text stays distinct and readable. For example "DrawEngineBasics.Grid*()" uses it. "inPPM" means that the stroke width is measured in parts per million of the text size, the same way as "DrawText.MarkupStrokeWidth()" and "richTextMarkup-strokeWidth" expect it. + public static bool initial_drawOnlyIfSelected_forComponents = false; //Most of the drawer and visualizer components have a checkbox saying "Draw only if selected", which, by is intially disabled. Depending on your use case it may be better if it is initially enabled, for example if you add GridVisualizers to many Gameobjects, but want to see the grid only around the currently selected Gameobject. You can change the initial value here with this setting. + + private static float relSizeOfTextOnLines = 0.45f; + public static float RelSizeOfTextOnLines + { + get { return relSizeOfTextOnLines; } + set { relSizeOfTextOnLines = Mathf.Clamp(value, 0.01f, 1000.0f); } + } + + public static bool shiftTextPosOnLines_toNonIntersecting = false; + + public static float GlobalAlphaFactor + { + get { return DXXLWrapperForUntiysBuildInDrawLines.globalAlphaFactor; } + set + { + DXXLWrapperForUntiysBuildInDrawLines.globalAlphaFactor_is0 = (value <= 0.0f); + DXXLWrapperForUntiysBuildInDrawLines.globalAlphaFactor_is1 = Mathf.Approximately(value, 1.0f); + DXXLWrapperForUntiysBuildInDrawLines.globalAlphaFactor = value; + } + } + + public enum IconType + { + //system/operate: + dataDisc, + saveData, + loadData, + folder, + saveToFolder, + loadFromFolder, + share, + trashcan, + optionsSettingsGear, + adjustOptionsSettings, + homeHouse, + profileFoto, + imageLandscape, + cursorPointer, + timeHourglassCursor, + cursorHand, + magnifier, + magnifierPlus, + magnifierMinus, + switchOnOff, + playButton, + pauseButton, + stopButton, + playPauseButton, + camera, + videoCamera, + music, + microphone, + audioSpeaker, + audioSpeakerMute, + megaphone, + wlan_wifi, + telephone, + battery, + cloud, + timeClock, + locationPin, + stars5Rate, + + //human: + humanMale, + humanFemale, + thumbUp, + thumbDown, + speechBubble, + speechBubbleEmpty, + fist, + boxingGlove, + + //nature/weather: + sun, + moonHalf, + moonFullPlanet, + stars3, + shootingStar, + rain, + wind, + snow, + iceIcicle, + lightning, + fire, + tree, + palm, + leaf, + animal, + bird, + fish, + mushroom, + + //games: + heart, + trophy, + crown, + awardMedal, + star, + bomb, + bombExplosion, + health, + healthBox, + pill, + potion, + death, + gemDiamond, + gold, + coin, + coins, + moneyBills, + moneyBag, + presentGift, + chestTreasureBox_closed, + chestTreasureBox_open, + lootbox, + shoppingCart, + map, + compass, + car, + fuelStation, + fuelCan, + foodPlate, + foodMeat, + flag, + flagChequered, + crosshair, + ball, + dice, + tower, + jigsawPuzzle, + rocket, + magnet, + doorClosed, + doorOpen, + doorEnter, + doorLeave, + key, + lockLocked, + lockUnlocked, + gamepad, + joystick, + lightBulbOn, + lightBulbOff, + + //tools/weapons: + pen, + gun, + bullet, + sword, + shield, + hammer, + shovel, + axe, + pickAxe, + arrow, + arrowBow, + + //signs/warning: + warning, + fireWarning, + nukeNuclearWarning, + biohazardWarning, + emergencyExit, + logMessage, + logMessageError, + logMessageException, + logMessageAssertion, + + //basics: + questionMark, + exclamationMark, + checkmarkChecked, + checkmarkUnchecked, + arrowLeft, + arrowRight, + arrowUp, + arrowDown, + up_oneStroke, + up_twoStroke, + up_threeStroke, + down_oneStroke, + down_twoStroke, + down_threeStroke, + left_oneStroke, + left_twoStroke, + left_threeStroke, + right_oneStroke, + right_twoStroke, + right_threeStroke, + circleDotFilled, + circleDotUnfilled, + unitCircle, + unitSquareCrossed, + unitSquare, + unitSquareIncl1Right, + unitSquareIncl2Right, + unitSquareIncl3Right, + unitSquareIncl4Right, + unitSquareIncl5Right, + unitSquareIncl6Right, + + //miscellaneous: + leftHandRule, + rightHandRule + }; + + /// 从起点到终点绘制线段。 + public static void Line(Vector3 start, Vector3 end, Color color = default(Color), float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Line_fadeableAnimSpeed.InternalDraw(start, end, color, width, text, style, stylePatternScaleFactor, animationSpeed, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 从起点沿方向绘制射线。 + public static void Ray(Vector3 start, Vector3 direction, Color color = default(Color), float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Ray_fadeableAnimSpeed.InternalDraw(start, direction, color, width, text, style, stylePatternScaleFactor, animationSpeed, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 从起点沿方向向量绘制线段。 + public static void LineFrom(Vector3 start, Vector3 direction, Color color = default(Color), float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + LineFrom_fadeableAnimSpeed.InternalDraw(start, direction, color, width, text, style, stylePatternScaleFactor, animationSpeed, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 根据方向向量和终点绘制线段。 + public static void LineTo(Vector3 direction, Vector3 end, Color color = default(Color), float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + LineTo_fadeableAnimSpeed.InternalDraw(direction, end, color, width, text, style, stylePatternScaleFactor, animationSpeed, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制颜色从起点渐变到终点的线段。 + public static void LineColorFade(Vector3 start, Vector3 end, Color startColor, Color endColor, float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Line_fadeableAnimSpeed.InternalDrawColorFade(start, end, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制颜色从起点渐变到终点的射线。 + public static void RayColorFade(Vector3 start, Vector3 direction, Color startColor, Color endColor, float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Ray_fadeableAnimSpeed.InternalDrawColorFade(start, direction, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 带颜色渐变的 LineFrom,从起点沿方向绘制颜色渐变的线段。 + public static void LineFrom_withColorFade(Vector3 start, Vector3 direction, Color startColor, Color endColor, float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + LineFrom_fadeableAnimSpeed.InternalDraw_withColorFade(start, direction, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 带颜色渐变的 LineTo,根据方向和终点绘制颜色渐变的线段。 + public static void LineTo_withColorFade(Vector3 direction, Vector3 end, Color startColor, Color endColor, float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + LineTo_fadeableAnimSpeed.InternalDraw_withColorFade(direction, end, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 根据圆心和两个方向向量绘制圆弧线段。 + public static void LineCircled(Vector3 circleCenter, Vector3 circleCenter_to_start, Vector3 circleCenter_to_end, Color color = default(Color), float forceRadius = 0.0f, float width = 0.0f, string text = null, bool useReflexAngleOver180deg = false, bool skipFallbackDisplayOfZeroAngles = false, bool flattenThickRoundLineIntoCirclePlane = true, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_LineCircled.LineCircled(circleCenter, circleCenter_to_start, circleCenter_to_end, color, forceRadius, width, text, useReflexAngleOver180deg, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects); + } + + /// 根据圆心、旋转和角度绘制圆弧线段。 + public static void LineCircled(Vector3 circleCenterPos, Quaternion orientation, float turnAngleDegCC_startingFromUp, float radius, Color color, float width = 0.0f, string text = null, bool skipFallbackDisplayOfZeroAngles = false, bool flattenThickRoundLineIntoCirclePlane = true, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenterPos, "circleCenterPos")) { return; } + + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + + Vector3 startPos = circleCenterPos + orientation * Vector3.up * radius; + Vector3 turnAxis_origin = circleCenterPos; + Vector3 turnAxis_direction = orientation * Vector3.forward; + LineCircled(startPos, turnAxis_origin, turnAxis_direction, turnAngleDegCC_startingFromUp, color, width, text, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects); + } + + /// 根据圆心、旋转和起止角度绘制圆弧线段。 + public static void LineCircled(Vector3 circleCenterPos, Quaternion orientation, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius = 1.0f, Color color = default(Color), float width = 0.0f, string text = null, bool skipFallbackDisplayOfZeroAngles = false, bool flattenThickRoundLineIntoCirclePlane = true, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(startAngleDegCC_relativeToUp, "startAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(endAngleDegCC_relativeToUp, "endAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenterPos, "circleCenterPos")) { return; } + + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + Vector3 turnAxis_direction = orientation * Vector3.forward; + Quaternion fromOrientation_toOrientationSoThatTheStartAngleMarksTheRotationsUpwardDir = Quaternion.AngleAxis(startAngleDegCC_relativeToUp, turnAxis_direction); + float turnedAngleDegCC_fromStartAngle = endAngleDegCC_relativeToUp - startAngleDegCC_relativeToUp; + Vector3 startPos = circleCenterPos + fromOrientation_toOrientationSoThatTheStartAngleMarksTheRotationsUpwardDir * orientation * Vector3.up * radius; + Vector3 turnAxis_origin = circleCenterPos; + LineCircled(startPos, turnAxis_origin, turnAxis_direction, turnedAngleDegCC_fromStartAngle, color, width, text, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects); + } + + /// 根据起点和旋转轴(Ray)绘制圆弧线段。 + public static void LineCircled(Vector3 startPos, Ray turnAxis, float turnAngleDegCC, Color color = default(Color), float width = 0.0f, string text = null, bool skipFallbackDisplayOfZeroAngles = false, bool flattenThickRoundLineIntoCirclePlane = true, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + LineCircled(startPos, turnAxis.origin, turnAxis.direction, turnAngleDegCC, color, width, text, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects); + } + + /// 根据起点、旋转轴原点和方向绘制圆弧线段。 + public static void LineCircled(Vector3 startPos, Vector3 turnAxis_origin, Vector3 turnAxis_direction, float turnAngleDegCC, Color color = default(Color), float width = 0.0f, string text = null, bool skipFallbackDisplayOfZeroAngles = false, bool flattenThickRoundLineIntoCirclePlane = true, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_LineCircled.LineCircled(startPos, turnAxis_origin, turnAxis_direction, turnAngleDegCC, color, width, text, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + + /// 根据圆心和两个方向向量绘制扇形/圆弧段。 + public static void CircleSegment(Vector3 centerOfCircle, Vector3 circleCenter_to_startPosOnPerimeter, Vector3 circleCenter_to_endPosOnPerimeter, Color color = default(Color), float forceRadius = 0.0f, string text = null, bool useReflexAngleOver180deg = false, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_LineCircled.CircleSegment(centerOfCircle, circleCenter_to_startPosOnPerimeter, circleCenter_to_endPosOnPerimeter, color, forceRadius, fillDensity, text, useReflexAngleOver180deg, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL.LowerLeftOfWholeTextBlock, durationInSec, hiddenByNearerObjects); + } + + /// 根据圆心、旋转和角度绘制扇形/圆弧段。 + public static void CircleSegment(Vector3 centerOfCircle, Quaternion orientation, float turnAngleDegCC_startingFromUp, float radius, Color color, string text = null, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerOfCircle, "centerOfCircle")) { return; } + + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + + Vector3 startPos = centerOfCircle + orientation * Vector3.up * radius; + Vector3 turnAxis_origin = centerOfCircle; + Vector3 turnAxis_direction = orientation * Vector3.forward; + CircleSegment(startPos, turnAxis_origin, turnAxis_direction, turnAngleDegCC_startingFromUp, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, minAngleDeg_withoutTextLineBreak, durationInSec, hiddenByNearerObjects); + } + + /// 根据圆心、旋转和起止角度绘制扇形/圆弧段。 + public static void CircleSegment(Vector3 centerOfCircle, Quaternion orientation, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius = 1.0f, Color color = default(Color), string text = null, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(startAngleDegCC_relativeToUp, "startAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(endAngleDegCC_relativeToUp, "endAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerOfCircle, "centerOfCircle")) { return; } + + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + Vector3 turnAxis_direction = orientation * Vector3.forward; + Quaternion fromOrientation_toOrientationSoThatTheStartAngleMarksTheRotationsUpwardDir = Quaternion.AngleAxis(startAngleDegCC_relativeToUp, turnAxis_direction); + float turnedAngleDegCC_fromStartAngle = endAngleDegCC_relativeToUp - startAngleDegCC_relativeToUp; + Vector3 startPos = centerOfCircle + fromOrientation_toOrientationSoThatTheStartAngleMarksTheRotationsUpwardDir * orientation * Vector3.up * radius; + Vector3 turnAxis_origin = centerOfCircle; + CircleSegment(startPos, turnAxis_origin, turnAxis_direction, turnedAngleDegCC_fromStartAngle, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, minAngleDeg_withoutTextLineBreak, durationInSec, hiddenByNearerObjects); + } + + /// 根据起点和旋转轴(Ray)绘制扇形/圆弧段。 + public static void CircleSegment(Vector3 startPos, Ray turnAxis, float turnAngleDegCC, Color color = default(Color), string text = null, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + CircleSegment(startPos, turnAxis.origin, turnAxis.direction, turnAngleDegCC, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, minAngleDeg_withoutTextLineBreak, durationInSec, hiddenByNearerObjects); + } + + /// 根据圆周起点、圆心和法线绘制扇形/圆弧段。 + public static void CircleSegment(Vector3 startPosOnPerimeter, Vector3 centerOfCircle, Vector3 normalOfCircle, float turnAngleDegCC, Color color = default(Color), string text = null, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_LineCircled.CircleSegment(startPosOnPerimeter, centerOfCircle, normalOfCircle, turnAngleDegCC, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL.LowerLeftOfWholeTextBlock); + } + + /// 通过点数组绘制连续折线。 + public static void LineString(Vector3[] points, Color color = default(Color), bool closeGapBetweenLastAndFirstPoint = false, float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + + if (points == null) + { + Debug.LogError("'points' is 'null'"); + return; + } + + if (points.Length == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + for (int i = 0; i < (points.Length - 1); i++) + { + Line_fadeableAnimSpeed.InternalDraw(points[i], points[i + 1], color, width, null, style, stylePatternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed.InternalDraw(points[points.Length - 1], points[0], color, width, null, style, stylePatternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (text != null && text != "") + { + TagLineString(text, points, width, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + /// 通过点列表绘制连续折线。 + public static void LineString(List points, Color color = default(Color), bool closeGapBetweenLastAndFirstPoint = false, float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + if (points == null) + { + Debug.LogError("'points' is 'null'"); + return; + } + + if (points.Count == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + for (int i = 0; i < (points.Count - 1); i++) + { + Line_fadeableAnimSpeed.InternalDraw(points[i], points[i + 1], color, width, null, style, stylePatternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed.InternalDraw(points[points.Count - 1], points[0], color, width, null, style, stylePatternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (text != null && text != "") + { + TagLineString(text, points, width, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + /// 绘制颜色渐变的连续折线(点数组)。 + public static void LineStringColorFade(Vector3[] points, Color startColor, Color endColor, bool closeGapBetweenLastAndFirstPoint = false, float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + if (points == null) + { + Debug.LogError("'points' is 'null'"); + return; + } + + if (points.Length == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + int iOffset_forColorFade = -1; + if (closeGapBetweenLastAndFirstPoint) + { + iOffset_forColorFade = 0; + } + + for (int i = 0; i < (points.Length - 1); i++) + { + Color color = UtilitiesDXXL_DrawBasics.GetFadedColorFromSegments(startColor, endColor, i, points.Length + iOffset_forColorFade); + Line_fadeableAnimSpeed.InternalDraw(points[i], points[i + 1], color, width, null, style, stylePatternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed.InternalDraw(points[points.Length - 1], points[0], endColor, width, null, style, stylePatternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (text != null && text != "") + { + Color averageColor = Color.Lerp(startColor, endColor, 0.5f); + TagLineString(text, points, width, averageColor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + /// 绘制颜色渐变的连续折线(点列表)。 + public static void LineStringColorFade(List points, Color startColor, Color endColor, bool closeGapBetweenLastAndFirstPoint = false, float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + if (points == null) + { + Debug.LogError("'points' is 'null'"); + return; + } + + if (points.Count == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + int iOffset_forColorFade = -1; + if (closeGapBetweenLastAndFirstPoint) + { + iOffset_forColorFade = 0; + } + + for (int i = 0; i < (points.Count - 1); i++) + { + Color color = UtilitiesDXXL_DrawBasics.GetFadedColorFromSegments(startColor, endColor, i, points.Count + iOffset_forColorFade); + Line_fadeableAnimSpeed.InternalDraw(points[i], points[i + 1], color, width, null, style, stylePatternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed.InternalDraw(points[points.Count - 1], points[0], endColor, width, null, style, stylePatternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (text != null && text != "") + { + Color averageColor = Color.Lerp(startColor, endColor, 0.5f); + TagLineString(text, points, width, averageColor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + static void TagLineString(string text, Vector3[] lineStringVerticesGlobal, float linesWidth, Color colorOfLines, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (text != null && text != "") + { + float xMin = UtilitiesDXXL_Math.GetLowestXComponent(lineStringVerticesGlobal); + float xMax = UtilitiesDXXL_Math.GetHighestXComponent(lineStringVerticesGlobal); + float yMin = UtilitiesDXXL_Math.GetLowestYComponent(lineStringVerticesGlobal); + float yMax = UtilitiesDXXL_Math.GetHighestYComponent(lineStringVerticesGlobal); + float zMin = UtilitiesDXXL_Math.GetLowestZComponent(lineStringVerticesGlobal); + float zMax = UtilitiesDXXL_Math.GetHighestZComponent(lineStringVerticesGlobal); + Vector3 virtualScale = new Vector3(xMax - xMin, yMax - yMin, zMax - zMin); + Vector3 centerPosition = lineStringVerticesGlobal[0]; + for (int i = 0; i < lineStringVerticesGlobal.Length; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref UtilitiesDXXL_Shapes.verticesLocal, lineStringVerticesGlobal[i] - centerPosition, i); + } + Color invertedColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(colorOfLines); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centerPosition, lineStringVerticesGlobal.Length, 0.1f * linesWidth, virtualScale, invertedColor, invertedColor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + static void TagLineString(string text, List lineStringVerticesGlobal, float linesWidth, Color colorOfLines, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (text != null && text != "") + { + float xMin = UtilitiesDXXL_Math.GetLowestXComponent(lineStringVerticesGlobal); + float xMax = UtilitiesDXXL_Math.GetHighestXComponent(lineStringVerticesGlobal); + float yMin = UtilitiesDXXL_Math.GetLowestYComponent(lineStringVerticesGlobal); + float yMax = UtilitiesDXXL_Math.GetHighestYComponent(lineStringVerticesGlobal); + float zMin = UtilitiesDXXL_Math.GetLowestZComponent(lineStringVerticesGlobal); + float zMax = UtilitiesDXXL_Math.GetHighestZComponent(lineStringVerticesGlobal); + Vector3 virtualScale = new Vector3(xMax - xMin, yMax - yMin, zMax - zMin); + Vector3 centerPosition = lineStringVerticesGlobal[0]; + for (int i = 0; i < lineStringVerticesGlobal.Count; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref UtilitiesDXXL_Shapes.verticesLocal, lineStringVerticesGlobal[i] - centerPosition, i); + } + Color invertedColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(colorOfLines); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centerPosition, lineStringVerticesGlobal.Count, 0.1f * linesWidth, virtualScale, invertedColor, invertedColor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + /// 在多个点位置绘制标记十字。 + public static void PointArray(Vector3[] points, Color color = default(Color), float sizeOfMarkingCross = 1.0f, float markingCrossLinesWidth = 0.0f, bool drawCoordsAsText = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + + for (int i = 0; i < points.Length; i++) + { + Point(points[i], color, sizeOfMarkingCross, Quaternion.identity, markingCrossLinesWidth, null, color, false, drawCoordsAsText, hideZDir, durationInSec, hiddenByNearerObjects); + } + } + + /// 在多个点位置绘制标记十字(点列表)。 + public static void PointList(List points, Color color = default(Color), float sizeOfMarkingCross = 1.0f, float markingCrossLinesWidth = 0.0f, bool drawCoordsAsText = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + + for (int i = 0; i < points.Count; i++) + { + Point(points[i], color, sizeOfMarkingCross, Quaternion.identity, markingCrossLinesWidth, null, color, false, drawCoordsAsText, hideZDir, durationInSec, hiddenByNearerObjects); + } + } + + /// 在指定位置绘制带标记十字的点。 + public static void Point(Vector3 position, Color markingCrossColor, float sizeOfMarkingCross = 1.0f, Quaternion rotation = default(Quaternion), float markingCrossLinesWidth = 0.0f, string text = null, Color textColor = default(Color), bool pointer_as_textAttachStyle = false, bool drawCoordsAsText = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Point(position, text, textColor, sizeOfMarkingCross, markingCrossLinesWidth, markingCrossColor, rotation, pointer_as_textAttachStyle, drawCoordsAsText, hideZDir, durationInSec, hiddenByNearerObjects); + } + + /// 在指定位置绘制带文本标记和标记十字的点。 + public static void Point(Vector3 position, string text = null, Color textColor = default(Color), float sizeOfMarkingCross = 1.0f, float markingCrossLinesWidth = 0.0f, Color overwrite_markingCrossColor = default(Color), Quaternion rotation = default(Quaternion), bool pointer_as_textAttachStyle = true, bool drawCoordsAsText = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_DrawBasics.Point(false, position, text, textColor, sizeOfMarkingCross, markingCrossLinesWidth, overwrite_markingCrossColor, rotation, pointer_as_textAttachStyle, drawCoordsAsText, false, true, Vector3.zero, Quaternion.identity, Vector3.one, hideZDir, durationInSec, hiddenByNearerObjects); + } + + /// 在局部坐标点数组位置绘制标记十字(使用 Transform)。 + public static void PointLocalArray(Vector3[] localPoints, Transform parentTransform, Color color = default(Color), float sizeOfMarkingCross_global = 1.0f, float markingCrossLinesWidth = 0.0f, bool drawCoordsAsText = true, bool additionallyDrawGlobalCoords = false, bool drawLocalOrigin = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(localPoints, "points")) { return; } + if (parentTransform == null) + { + PointArray(localPoints, color, sizeOfMarkingCross_global, markingCrossLinesWidth, drawCoordsAsText, hideZDir, durationInSec, hiddenByNearerObjects); + } + else + { + for (int i = 0; i < localPoints.Length; i++) + { + PointLocal(localPoints[i], parentTransform.position, parentTransform.rotation, parentTransform.lossyScale, null, color, sizeOfMarkingCross_global, markingCrossLinesWidth, color, Quaternion.identity, false, drawCoordsAsText, additionallyDrawGlobalCoords, drawLocalOrigin, hideZDir, durationInSec, hiddenByNearerObjects); + } + } + } + + /// 在局部坐标点列表位置绘制标记十字(使用 Transform)。 + public static void PointLocalList(List localPoints, Transform parentTransform, Color color = default(Color), float sizeOfMarkingCross_global = 1.0f, float markingCrossLinesWidth = 0.0f, bool drawCoordsAsText = true, bool additionallyDrawGlobalCoords = false, bool drawLocalOrigin = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(localPoints, "points")) { return; } + if (parentTransform == null) + { + PointList(localPoints, color, sizeOfMarkingCross_global, markingCrossLinesWidth, drawCoordsAsText, hideZDir, durationInSec, hiddenByNearerObjects); + } + else + { + for (int i = 0; i < localPoints.Count; i++) + { + PointLocal(localPoints[i], parentTransform.position, parentTransform.rotation, parentTransform.lossyScale, null, color, sizeOfMarkingCross_global, markingCrossLinesWidth, color, Quaternion.identity, false, drawCoordsAsText, additionallyDrawGlobalCoords, drawLocalOrigin, hideZDir, durationInSec, hiddenByNearerObjects); + } + } + } + + /// 在局部坐标点数组位置绘制标记十字(直接指定父级变换)。 + public static void PointLocalArray(Vector3[] localPoints, Vector3 parentPositionGlobal, Quaternion parentRotationGlobal, Vector3 parentScaleGlobal, Color color = default(Color), float sizeOfMarkingCross_global = 1.0f, float markingCrossLinesWidth = 0.0f, bool drawCoordsAsText = true, bool additionallyDrawGlobalCoords = false, bool drawLocalOrigin = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(localPoints, "points")) { return; } + + for (int i = 0; i < localPoints.Length; i++) + { + PointLocal(localPoints[i], parentPositionGlobal, parentRotationGlobal, parentScaleGlobal, null, color, sizeOfMarkingCross_global, markingCrossLinesWidth, color, Quaternion.identity, false, drawCoordsAsText, additionallyDrawGlobalCoords, drawLocalOrigin, hideZDir, durationInSec, hiddenByNearerObjects); + } + } + + /// 在局部坐标点列表位置绘制标记十字(直接指定父级变换)。 + public static void PointLocalList(List localPoints, Vector3 parentPositionGlobal, Quaternion parentRotationGlobal, Vector3 parentScaleGlobal, Color color = default(Color), float sizeOfMarkingCross_global = 1.0f, float markingCrossLinesWidth = 0.0f, bool drawCoordsAsText = true, bool additionallyDrawGlobalCoords = false, bool drawLocalOrigin = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(localPoints, "points")) { return; } + + for (int i = 0; i < localPoints.Count; i++) + { + PointLocal(localPoints[i], parentPositionGlobal, parentRotationGlobal, parentScaleGlobal, null, color, sizeOfMarkingCross_global, markingCrossLinesWidth, color, Quaternion.identity, false, drawCoordsAsText, additionallyDrawGlobalCoords, drawLocalOrigin, hideZDir, durationInSec, hiddenByNearerObjects); + } + } + + /// 在局部坐标位置绘制标记十字(使用 Transform 和标记十字颜色)。 + public static void PointLocal(Vector3 localPosition, Transform parentTransform, Color markingCrossColor, float sizeOfMarkingCross_global = 1.0f, Quaternion localRotation = default(Quaternion), float markingCrossLinesWidth = 0.0f, string text = null, Color textColor = default(Color), bool pointer_as_textAttachStyle = false, bool drawCoordsAsText = true, bool additionallyDrawGlobalCoords = false, bool drawLocalOrigin = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransform == null) + { + text = "[ parent transform that defines
the local space is 'null'
-> fallback to global coordinates]
" + text; + Point(localPosition, markingCrossColor, sizeOfMarkingCross_global, localRotation, markingCrossLinesWidth, text, textColor, pointer_as_textAttachStyle, drawCoordsAsText, hideZDir, durationInSec, hiddenByNearerObjects); + } + else + { + PointLocal(localPosition, parentTransform.position, parentTransform.rotation, parentTransform.lossyScale, markingCrossColor, sizeOfMarkingCross_global, localRotation, markingCrossLinesWidth, text, textColor, pointer_as_textAttachStyle, drawCoordsAsText, additionallyDrawGlobalCoords, drawLocalOrigin, hideZDir, durationInSec, hiddenByNearerObjects); + } + } + + /// 在局部坐标位置绘制标记十字(使用 Transform 和文本)。 + public static void PointLocal(Vector3 localPosition, Transform parentTransform, string text = null, Color textColor = default(Color), float sizeOfMarkingCross_global = 1.0f, float markingCrossLinesWidth = 0.0f, Color overwrite_markingCrossColor = default(Color), Quaternion localRotation = default(Quaternion), bool pointer_as_textAttachStyle = true, bool drawCoordsAsText = true, bool additionallyDrawGlobalCoords = true, bool drawLocalOrigin = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransform == null) + { + text = "[ parent transform that defines
the local space is 'null'
-> fallback to global coordinates]
" + text; + Point(localPosition, text, textColor, sizeOfMarkingCross_global, markingCrossLinesWidth, overwrite_markingCrossColor, localRotation, pointer_as_textAttachStyle, drawCoordsAsText, hideZDir, durationInSec, hiddenByNearerObjects); + } + else + { + PointLocal(localPosition, parentTransform.position, parentTransform.rotation, parentTransform.lossyScale, text, textColor, sizeOfMarkingCross_global, markingCrossLinesWidth, overwrite_markingCrossColor, localRotation, pointer_as_textAttachStyle, drawCoordsAsText, additionallyDrawGlobalCoords, drawLocalOrigin, hideZDir, durationInSec, hiddenByNearerObjects); + } + } + + /// 在局部坐标位置绘制标记十字(直接指定父级变换和标记十字颜色)。 + public static void PointLocal(Vector3 localPosition, Vector3 parentPositionGlobal, Quaternion parentRotationGlobal, Vector3 parentScaleGlobal, Color markingCrossColor, float sizeOfMarkingCross_global = 1.0f, Quaternion localRotation = default(Quaternion), float markingCrossLinesWidth = 0.0f, string text = null, Color textColor = default(Color), bool pointer_as_textAttachStyle = false, bool drawCoordsAsText = true, bool additionallyDrawGlobalCoords = false, bool drawLocalOrigin = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + PointLocal(localPosition, parentPositionGlobal, parentRotationGlobal, parentScaleGlobal, text, textColor, sizeOfMarkingCross_global, markingCrossLinesWidth, markingCrossColor, localRotation, pointer_as_textAttachStyle, drawCoordsAsText, additionallyDrawGlobalCoords, drawLocalOrigin, hideZDir, durationInSec, hiddenByNearerObjects); + } + + /// 在局部坐标位置绘制标记十字(直接指定父级变换和文本)。 + public static void PointLocal(Vector3 localPosition, Vector3 parentPositionGlobal, Quaternion parentRotationGlobal, Vector3 parentScaleGlobal, string text = null, Color textColor = default(Color), float sizeOfMarkingCross_global = 1.0f, float markingCrossLinesWidth = 0.0f, Color overwrite_markingCrossColor = default(Color), Quaternion localRotation = default(Quaternion), bool pointer_as_textAttachStyle = true, bool drawCoordsAsText = true, bool additionallyDrawGlobalCoords = true, bool drawLocalOrigin = true, bool hideZDir = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_DrawBasics.Point(false, localPosition, text, textColor, sizeOfMarkingCross_global, markingCrossLinesWidth, overwrite_markingCrossColor, localRotation, pointer_as_textAttachStyle, drawCoordsAsText, additionallyDrawGlobalCoords, false, parentPositionGlobal, parentRotationGlobal, parentScaleGlobal, hideZDir, durationInSec, hiddenByNearerObjects); + if (drawLocalOrigin) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(sizeOfMarkingCross_global, "sizeOfMarkingCross_global")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(localPosition, "localPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(parentPositionGlobal, "parentPositionGlobal")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(parentScaleGlobal, "parentScaleGlobal")) { return; } + + parentRotationGlobal = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(parentRotationGlobal); + + Vector3 parentForward = parentRotationGlobal * Vector3.forward; + Vector3 parentUp = parentRotationGlobal * Vector3.up; + Vector3 parentRight = parentRotationGlobal * Vector3.right; + Vector3 worldPosition = parentPositionGlobal + parentRight * parentScaleGlobal.x * localPosition.x + parentUp * parentScaleGlobal.y * localPosition.y + parentForward * parentScaleGlobal.z * localPosition.z; + DrawConnection_fromLocalPoint_toLocalOrigin(parentPositionGlobal, worldPosition, 0.3f * sizeOfMarkingCross_global, parentRotationGlobal, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawConnection_fromLocalPoint_toLocalOrigin(Vector3 originWorldPosition, Vector3 markedPointWorldPosition, float sizeOfMarkingCross, Quaternion parentRotationGlobal, float durationInSec, bool hiddenByNearerObjects) + { + Color originColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(Color.white, 0.2f); + UtilitiesDXXL_DrawBasics.Point(false, originWorldPosition, "local
origin", originColor, sizeOfMarkingCross, 0.0f, originColor, parentRotationGlobal, false, false, false, true, Vector3.zero, Quaternion.identity, Vector3.one, false, durationInSec, hiddenByNearerObjects); + Vector3 localOriginToMarkedPoint = markedPointWorldPosition - originWorldPosition; + float distanceToLocalOrigin = localOriginToMarkedPoint.magnitude; + Line_fadeableAnimSpeed.InternalDraw(originWorldPosition, markedPointWorldPosition, originColor, 0.0f, null, LineStyle.dashedLong, distanceToLocalOrigin, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + /// 在指定位置绘制带引出线的文本标签。 + public static void PointTag(Vector3 position, string text = null, Color color = default(Color), float linesWidth = 0.0f, float size_asTextOffsetDistance = 1.0f, Vector3 textOffsetDirection = default(Vector3), float textSizeScaleFactor = 1.0f, bool skipConeDrawing = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_DrawBasics.PointTag(position, text, color, linesWidth, size_asTextOffsetDistance, textOffsetDirection, textSizeScaleFactor, skipConeDrawing, durationInSec, hiddenByNearerObjects); + } + + /// 绘制带箭头的向量(从起点到终点)。 + public static void Vector(Vector3 vectorStartPos, Vector3 vectorEndPos, Color color = default(Color), float lineWidth = 0.0f, string text = null, float coneLength = 0.17f, bool pointerAtBothSides = false, bool flattenThickRoundLineIntoAmplitudePlane = false, Vector3 customAmplitudeAndTextDir = default(Vector3), bool addNormalizedMarkingText = false, float enlargeSmallTextToThisMinTextSize = 0.0f, bool writeComponentValuesAsText = false, float endPlates_size = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_DrawBasics.Vector(vectorStartPos, vectorEndPos, color, lineWidth, text, coneLength, pointerAtBothSides, flattenThickRoundLineIntoAmplitudePlane, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, durationInSec, hiddenByNearerObjects, customAmplitudeAndTextDir, false, endPlates_size); + } + + /// 从起点沿方向向量绘制带箭头的向量。 + public static void VectorFrom(Vector3 vectorStartPos, Vector3 vector, Color color = default(Color), float lineWidth = 0.0f, string text = null, float coneLength = 0.17f, bool pointerAtBothSides = false, bool flattenThickRoundLineIntoAmplitudePlane = false, Vector3 customAmplitudeAndTextDir = default(Vector3), bool addNormalizedMarkingText = false, float enlargeSmallTextToThisMinTextSize = 0.0f, bool writeComponentValuesAsText = false, float endPlates_size = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_DrawBasics.VectorFrom(vectorStartPos, vector, color, lineWidth, text, coneLength, pointerAtBothSides, flattenThickRoundLineIntoAmplitudePlane, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, durationInSec, hiddenByNearerObjects, customAmplitudeAndTextDir, false, endPlates_size); + } + + /// 根据方向向量和终点绘制带箭头的向量。 + public static void VectorTo(Vector3 vector, Vector3 vectorEndPos, Color color = default(Color), float lineWidth = 0.0f, string text = null, float coneLength = 0.17f, bool pointerAtBothSides = false, bool flattenThickRoundLineIntoAmplitudePlane = false, Vector3 customAmplitudeAndTextDir = default(Vector3), bool addNormalizedMarkingText = false, float enlargeSmallTextToThisMinTextSize = 0.0f, bool writeComponentValuesAsText = false, float endPlates_size = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector, "vector")) { return; } + VectorFrom(vectorEndPos - vector, vector, color, lineWidth, text, coneLength, pointerAtBothSides, flattenThickRoundLineIntoAmplitudePlane, customAmplitudeAndTextDir, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, endPlates_size, durationInSec, hiddenByNearerObjects); + } + + /// 根据圆心和两个方向向量绘制带箭头的圆弧向量。 + public static void VectorCircled(Vector3 circleCenter, Vector3 circleCenter_to_start, Vector3 circleCenter_to_end, Color color = default(Color), float forceRadius = 0.0f, float lineWidth = 0.0f, string text = null, bool useReflexAngleOver180deg = false, float coneLength = 0.17f, bool pointerAtBothSides = false, bool skipFallbackDisplayOfZeroAngles = false, bool flattenThickRoundLineIntoCirclePlane = true, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_LineCircled.VectorCircled(circleCenter, circleCenter_to_start, circleCenter_to_end, color, forceRadius, lineWidth, text, useReflexAngleOver180deg, coneLength, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects); + } + + /// 根据圆心、旋转和角度绘制带箭头的圆弧向量。 + public static void VectorCircled(Vector3 circleCenterPos, Quaternion orientation, float turnAngleDegCC_startingFromUp, float radius, Color color, float lineWidth = 0.0f, string text = null, float coneLength = 0.17f, bool pointerAtBothSides = false, bool skipFallbackDisplayOfZeroAngles = false, bool flattenThickRoundLineIntoCirclePlane = true, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenterPos, "circleCenterPos")) { return; } + + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + + Vector3 startPos = circleCenterPos + orientation * Vector3.up * radius; + Vector3 turnAxis_origin = circleCenterPos; + Vector3 turnAxis_direction = orientation * Vector3.forward; + VectorCircled(startPos, turnAxis_origin, turnAxis_direction, turnAngleDegCC_startingFromUp, color, lineWidth, text, coneLength, pointerAtBothSides, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects); + } + + /// 根据圆心、旋转和起止角度绘制带箭头的圆弧向量。 + public static void VectorCircled(Vector3 circleCenterPos, Quaternion orientation, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius = 1.0f, Color color = default(Color), float lineWidth = 0.0f, string text = null, float coneLength = 0.17f, bool pointerAtBothSides = false, bool skipFallbackDisplayOfZeroAngles = false, bool flattenThickRoundLineIntoCirclePlane = true, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(startAngleDegCC_relativeToUp, "startAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(endAngleDegCC_relativeToUp, "endAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenterPos, "circleCenterPos")) { return; } + + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + Vector3 turnAxis_direction = orientation * Vector3.forward; + Quaternion fromOrientation_toOrientationSoThatTheStartAngleMarksTheRotationsUpwardDir = Quaternion.AngleAxis(startAngleDegCC_relativeToUp, turnAxis_direction); + float turnedAngleDegCC_fromStartAngle = endAngleDegCC_relativeToUp - startAngleDegCC_relativeToUp; + Vector3 startPos = circleCenterPos + fromOrientation_toOrientationSoThatTheStartAngleMarksTheRotationsUpwardDir * orientation * Vector3.up * radius; + Vector3 turnAxis_origin = circleCenterPos; + VectorCircled(startPos, turnAxis_origin, turnAxis_direction, turnedAngleDegCC_fromStartAngle, color, lineWidth, text, coneLength, pointerAtBothSides, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects); + } + + /// 根据起点和旋转轴(Ray)绘制带箭头的圆弧向量。 + public static void VectorCircled(Vector3 startPos, Ray turnAxis, float turnAngleDegCC, Color color = default(Color), float lineWidth = 0.0f, string text = null, float coneLength = 0.17f, bool pointerAtBothSides = false, bool skipFallbackDisplayOfZeroAngles = false, bool flattenThickRoundLineIntoCirclePlane = true, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + VectorCircled(startPos, turnAxis.origin, turnAxis.direction, turnAngleDegCC, color, lineWidth, text, coneLength, pointerAtBothSides, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects); + } + + /// 根据起点、旋转轴原点和方向绘制带箭头的圆弧向量。 + public static void VectorCircled(Vector3 startPos, Vector3 turnAxis_origin, Vector3 turnAxis_direction, float turnAngleDegCC, Color color = default(Color), float lineWidth = 0.0f, string text = null, float coneLength = 0.17f, bool pointerAtBothSides = false, bool skipFallbackDisplayOfZeroAngles = false, bool flattenThickRoundLineIntoCirclePlane = true, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_LineCircled.VectorCircled(startPos, turnAxis_origin, turnAxis_direction, turnAngleDegCC, color, lineWidth, text, coneLength, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects, 1.0f); + } + + /// 在指定位置绘制图标(通过法线和向上方向定义朝向)。 + public static void Icon(Vector3 position, IconType icon, Color color, float size, string text, Vector3 normal, Vector3 up_insideIconPlane = default(Vector3), int strokeWidth_asPPMofSize = 0, bool mirrorHorizontally = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal, "normal")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideIconPlane, "up_insideIconPlane")) { return; } + + Quaternion rotation = UtilitiesDXXL_DrawBasics.GetRotationOfIcon(position, normal, up_insideIconPlane); + Icon(position, icon, color, size, text, rotation, strokeWidth_asPPMofSize, mirrorHorizontally, durationInSec, hiddenByNearerObjects); + } + + /// 在指定位置绘制图标(通过旋转定义朝向)。 + public static void Icon(Vector3 position, IconType icon, Color color = default(Color), float size = 1.0f, string text = null, Quaternion rotation = default(Quaternion), int strokeWidth_asPPMofSize = 0, bool mirrorHorizontally = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_DrawBasics.Icon(position, icon, color, size, text, rotation, strokeWidth_asPPMofSize, mirrorHorizontally, durationInSec, hiddenByNearerObjects, 0.1f, 0.004f, true); + } + + /// 绘制所有图标的图集并显示其名称。 + public static void DrawAtlasOfAllIconsWithTheirNames(Vector3 position = default(Vector3), Color iconsColor = default(Color), Color textColor = default(Color), bool displayNameTexts = true, float sizeOfIconWall = 10.0f) + { + UtilitiesDXXL_CharsAndIcons.DrawAllIconsWithTheirNames(position, iconsColor, textColor, displayNameTexts, sizeOfIconWall); + } + + /// 在指定位置绘制圆点。 + public static void Dot(Vector3 position, float radius = 0.5f, Vector3 normal = default(Vector3), Color color = default(Color), string text = null, float density = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + UtilitiesDXXL_DrawBasics.Dot(position, radius, normal, color, text, density, durationInSec, hiddenByNearerObjects, true); + } + + /// 绘制沿射线方向移动的箭头动画。 + public static void MovingArrowsRay(Vector3 start, Vector3 direction, Color color = default(Color), float lineWidth = 0.05f, float distanceBetweenArrows = 0.5f, float lengthOfArrows = 0.15f, string text = null, float animationSpeed = 0.5f, bool backwardAnimationFlipsArrowDirection = true, bool flattenThickRoundLineIntoAmplitudePlane = true, Vector3 customAmplitudeAndTextDir = default(Vector3), float endPlates_size = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + MovingArrowsRay_fadeableAnimSpeed.InternalDraw(start, direction, color, lineWidth, distanceBetweenArrows, lengthOfArrows, text, animationSpeed, null, backwardAnimationFlipsArrowDirection, flattenThickRoundLineIntoAmplitudePlane, customAmplitudeAndTextDir, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制沿线段方向移动的箭头动画。 + public static void MovingArrowsLine(Vector3 start, Vector3 end, Color color = default(Color), float lineWidth = 0.05f, float distanceBetweenArrows = 0.5f, float lengthOfArrows = 0.15f, string text = null, float animationSpeed = 0.5f, bool backwardAnimationFlipsArrowDirection = true, bool flattenThickRoundLineIntoAmplitudePlane = true, Vector3 customAmplitudeAndTextDir = default(Vector3), float endPlates_size = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + MovingArrowsLine_fadeableAnimSpeed.InternalDraw(start, end, color, lineWidth, distanceBetweenArrows, lengthOfArrows, text, animationSpeed, null, backwardAnimationFlipsArrowDirection, flattenThickRoundLineIntoAmplitudePlane, customAmplitudeAndTextDir, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制交替颜色的射线。 + public static void RayWithAlternatingColors(Vector3 start, Vector3 direction, Color color1 = default(Color), Color color2 = default(Color), float width = 0.0f, float lengthOfStripes = 0.04f, string text = null, float animationSpeed = 0.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + RayWithAlternatingColors_fadeableAnimSpeed.InternalDraw(start, direction, color1, color2, width, lengthOfStripes, text, animationSpeed, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制交替颜色的线段。 + public static void LineWithAlternatingColors(Vector3 start, Vector3 end, Color color1 = default(Color), Color color2 = default(Color), float width = 0.0f, float lengthOfStripes = 0.04f, string text = null, float animationSpeed = 0.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + LineWithAlternatingColors_fadeableAnimSpeed.InternalDraw(start, end, color1, color2, width, lengthOfStripes, text, animationSpeed, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制闪烁的射线。 + public static void BlinkingRay(Vector3 start, Vector3 direction, Color primaryColor = default(Color), float blinkDurationInSec = 0.5f, float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, Color blinkColor = default(Color), float stylePatternScaleFactor = 1.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return; } + + Vector3 end = start + direction; + BlinkingLine(start, end, primaryColor, blinkDurationInSec, width, text, style, blinkColor, stylePatternScaleFactor, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制闪烁的线段。 + public static void BlinkingLine(Vector3 start, Vector3 end, Color primaryColor = default(Color), float blinkDurationInSec = 0.5f, float width = 0.0f, string text = null, LineStyle style = LineStyle.solid, Color blinkColor = default(Color), float stylePatternScaleFactor = 1.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(blinkDurationInSec, "blinkDurationInSec")) { return; } + + blinkDurationInSec = Mathf.Max(blinkDurationInSec, UtilitiesDXXL_DrawBasics.min_blinkDurationInSec); + float passedBlinkIntervallsSinceStartup = UtilitiesDXXL_LineStyles.GetTime() / blinkDurationInSec; + primaryColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(primaryColor); + if (UtilitiesDXXL_Math.CheckIf_givenNumberIs_evenNotOdd(Mathf.FloorToInt(passedBlinkIntervallsSinceStartup))) + { + Line_fadeableAnimSpeed.InternalDraw(start, end, primaryColor, width, text, style, stylePatternScaleFactor, 0.0f, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + if (UtilitiesDXXL_Colors.IsDefaultColor(blinkColor)) + { + Color alternatingBlinkColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(primaryColor); + alternatingBlinkColor = UtilitiesDXXL_Colors.OverwriteColorNearGreyWithBlack(alternatingBlinkColor); + Line_fadeableAnimSpeed.InternalDraw(start, end, alternatingBlinkColor, width, text, style, stylePatternScaleFactor, 0.0f, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + Line_fadeableAnimSpeed.InternalDraw(start, end, blinkColor, width, text, style, stylePatternScaleFactor, 0.0f, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + } + + /// 绘制张力射线(根据拉伸/压缩状态改变颜色和样式)。 + public static void RayUnderTension(Vector3 start, Vector3 direction, float relaxedLength = 1.0f, Color relaxedColor = default(Color), LineStyle style = LineStyle.spiral, float stretchFactor_forStretchedTensionColor = 2.0f, Color color_forStretchedTension = default(Color), float stretchFactor_forSqueezedTensionColor = 0.0f, Color color_forSqueezedTension = default(Color), float width = 0.0f, string text = null, float alphaOfReferenceLengthDisplay = 0.15f, float stylePatternScaleFactor = 1.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return; } + LineUnderTension(start, start + direction, relaxedLength, relaxedColor, style, stretchFactor_forStretchedTensionColor, color_forStretchedTension, stretchFactor_forSqueezedTensionColor, color_forSqueezedTension, width, text, alphaOfReferenceLengthDisplay, stylePatternScaleFactor, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制张力线段(根据拉伸/压缩状态改变颜色和样式)。 + public static void LineUnderTension(Vector3 start, Vector3 end, float relaxedLength = 1.0f, Color relaxedColor = default(Color), LineStyle style = LineStyle.spiral, float stretchFactor_forStretchedTensionColor = 2.0f, Color color_forStretchedTension = default(Color), float stretchFactor_forSqueezedTensionColor = 0.0f, Color color_forSqueezedTension = default(Color), float width = 0.0f, string text = null, float alphaOfReferenceLengthDisplay = 0.15f, float stylePatternScaleFactor = 1.0f, Vector3 customAmplitudeAndTextDir = default(Vector3), bool flattenThickRoundLineIntoAmplitudePlane = false, float endPlates_size = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + bool parametersAreInvalid = UtilitiesDXXL_DrawBasics.GetSpecsOfLineUnderTension(out float tensionFactor, out Color usedColor, out float lineLength, start, end, relaxedLength, relaxedColor, color_forStretchedTension, color_forSqueezedTension, stretchFactor_forStretchedTensionColor, stretchFactor_forSqueezedTensionColor); + if (parametersAreInvalid) { return; } + UtilitiesDXXL_DrawBasics.TryDrawReferenceLengthDisplay_ofLineUnderTension(start, end, alphaOfReferenceLengthDisplay, relaxedLength, relaxedColor, lineLength, null, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Line(start, end, usedColor, width, text, style, stylePatternScaleFactor, 0.0f, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, 0.0f, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, null, false, endPlates_size, tensionFactor); + } + + /// 绘制二次贝塞尔曲线(GameObject 指定起点方向和终点)。 + public static void BezierSegmentQuadratic(GameObject startPositionAndDirection, GameObject endPosition, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPositionAndDirection, "startPositionAndDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + BezierSegmentQuadratic(startPositionAndDirection.transform, endPosition.transform, color, text, width, straightSubDivisions, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制二次贝塞尔曲线(Transform 指定起点方向和终点)。 + public static void BezierSegmentQuadratic(Transform startPositionAndDirection, Transform endPosition, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPositionAndDirection, "startPositionAndDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + Vector3 controlPosInBetween = startPositionAndDirection.position + startPositionAndDirection.forward * startPositionAndDirection.localScale.z; + BezierSegmentQuadratic(startPositionAndDirection.position, endPosition.position, controlPosInBetween, color, text, width, straightSubDivisions, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制二次贝塞尔曲线(GameObject 指定起点、终点和控制点)。 + public static void BezierSegmentQuadratic(GameObject startPosition, GameObject endPosition, GameObject controlPosInBetween, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosInBetween, "controlPosInBetween")) { return; } + BezierSegmentQuadratic(startPosition.transform.position, endPosition.transform.position, controlPosInBetween.transform.position, color, text, width, straightSubDivisions, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制二次贝塞尔曲线(Transform 指定起点、终点和控制点)。 + public static void BezierSegmentQuadratic(Transform startPosition, Transform endPosition, Transform controlPosInBetween, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosInBetween, "controlPosInBetween")) { return; } + BezierSegmentQuadratic(startPosition.position, endPosition.position, controlPosInBetween.position, color, text, width, straightSubDivisions, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制二次贝塞尔曲线(Vector3 指定起点、终点和控制点)。 + public static void BezierSegmentQuadratic(Vector3 startPosition, Vector3 endPosition, Vector3 controlPosInBetween, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(controlPosInBetween, "controlPosInBetween")) { return; } + + UtilitiesDXXL_Bezier.BezierSegmentQuadratic(false, startPosition, endPosition, controlPosInBetween, color, text, width, straightSubDivisions, textSize, true, durationInSec, hiddenByNearerObjects); + } + + /// 绘制三次贝塞尔曲线(GameObject 指定起点方向和终点方向)。 + public static void BezierSegmentCubic(GameObject startPositionAndDirection, GameObject endPositionAndDirection, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, bool closeGapFromEndToStart = false, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPositionAndDirection, "startPositionAndDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPositionAndDirection, "endPositionAndDirection")) { return; } + BezierSegmentCubic(startPositionAndDirection.transform, endPositionAndDirection.transform, color, text, width, straightSubDivisions, closeGapFromEndToStart, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制三次贝塞尔曲线(Transform 指定起点方向和终点方向)。 + public static void BezierSegmentCubic(Transform startPositionAndDirection, Transform endPositionAndDirection, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, bool closeGapFromEndToStart = false, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPositionAndDirection, "startPositionAndDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPositionAndDirection, "endPositionAndDirection")) { return; } + Vector3 controlPosOfStartDirection = startPositionAndDirection.position + startPositionAndDirection.forward * startPositionAndDirection.localScale.z; + Vector3 controlPosOfEndDirection = endPositionAndDirection.position - endPositionAndDirection.forward * endPositionAndDirection.localScale.z; + BezierSegmentCubic(startPositionAndDirection.position, endPositionAndDirection.position, controlPosOfStartDirection, controlPosOfEndDirection, color, text, width, straightSubDivisions, closeGapFromEndToStart, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制三次贝塞尔曲线(GameObject 指定起点、终点和两个控制点)。 + public static void BezierSegmentCubic(GameObject startPosition, GameObject endPosition, GameObject controlPosOfStartDirection, GameObject controlPosOfEndDirection, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, bool closeGapFromEndToStart = false, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosOfStartDirection, "controlPosOfStartDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosOfEndDirection, "controlPosOfEndDirection")) { return; } + BezierSegmentCubic(startPosition.transform.position, endPosition.transform.position, controlPosOfStartDirection.transform.position, controlPosOfEndDirection.transform.position, color, text, width, straightSubDivisions, closeGapFromEndToStart, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制三次贝塞尔曲线(Transform 指定起点、终点和两个控制点)。 + public static void BezierSegmentCubic(Transform startPosition, Transform endPosition, Transform controlPosOfStartDirection, Transform controlPosOfEndDirection, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, bool closeGapFromEndToStart = false, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosOfStartDirection, "controlPosOfStartDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosOfEndDirection, "controlPosOfEndDirection")) { return; } + BezierSegmentCubic(startPosition.position, endPosition.position, controlPosOfStartDirection.position, controlPosOfEndDirection.position, color, text, width, straightSubDivisions, closeGapFromEndToStart, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制三次贝塞尔曲线(Vector3 指定起点、终点和两个控制点)。 + public static void BezierSegmentCubic(Vector3 startPosition, Vector3 endPosition, Vector3 controlPosOfStartDirection, Vector3 controlPosOfEndDirection, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, bool closeGapFromEndToStart = false, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(controlPosOfStartDirection, "controlPosOfStartDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(controlPosOfEndDirection, "controlPosOfEndDirection")) { return; } + + UtilitiesDXXL_Bezier.BezierSegmentCubic(false, startPosition, endPosition, controlPosOfStartDirection, controlPosOfEndDirection, color, text, width, straightSubDivisions, textSize, true, durationInSec, hiddenByNearerObjects); + if (closeGapFromEndToStart) + { + Vector3 startPos_to_startControlPos = controlPosOfStartDirection - startPosition; + Vector3 endPos_to_endControlPos = controlPosOfEndDirection - endPosition; + Vector3 controlPosOfStartDirection_ofSecondCurve = startPosition - startPos_to_startControlPos; + Vector3 controlPosOfEndDirection_ofSecondCurve = endPosition - endPos_to_endControlPos; + UtilitiesDXXL_Bezier.BezierSegmentCubic(false, startPosition, endPosition, controlPosOfStartDirection_ofSecondCurve, controlPosOfEndDirection_ofSecondCurve, color, null, width, straightSubDivisions, textSize, true, durationInSec, hiddenByNearerObjects); + } + } + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex GetPositionsFromGameObjectsArray_preAllocated = UtilitiesDXXL_Bezier.GetPositionsFromGameObjectsArray; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform GetForwardControlPosFromGameObjectsArray_preAllocated = UtilitiesDXXL_Bezier.GetForwardControlPosFromGameObjectsArray; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform GetBackwardControlPosFromGameObjectsArray_preAllocated = UtilitiesDXXL_Bezier.GetBackwardControlPosFromGameObjectsArray; + /// 通过 GameObject 数组绘制贝塞尔样条曲线。 + public static void BezierSpline(GameObject[] points, Color color = default(Color), BezierPosInterpretation interpretationOfArray = BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + UtilitiesDXXL_Bezier.BezierSpline(false, 0.0f, points, GetPositionsFromGameObjectsArray_preAllocated, GetForwardControlPosFromGameObjectsArray_preAllocated, GetBackwardControlPosFromGameObjectsArray_preAllocated, points.Length, color, interpretationOfArray, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex> GetPositionsFromGameObjectsList_preAllocated = UtilitiesDXXL_Bezier.GetPositionsFromGameObjectsList; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform> GetForwardControlPosFromGameObjectsList_preAllocated = UtilitiesDXXL_Bezier.GetForwardControlPosFromGameObjectsList; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform> GetBackwardControlPosFromGameObjectsList_preAllocated = UtilitiesDXXL_Bezier.GetBackwardControlPosFromGameObjectsList; + /// 通过 GameObject 列表绘制贝塞尔样条曲线。 + public static void BezierSpline(List points, Color color = default(Color), BezierPosInterpretation interpretationOfList = BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + UtilitiesDXXL_Bezier.BezierSpline>(false, 0.0f, points, GetPositionsFromGameObjectsList_preAllocated, GetForwardControlPosFromGameObjectsList_preAllocated, GetBackwardControlPosFromGameObjectsList_preAllocated, points.Count, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex GetPositionsFromTransformsArray_preAllocated = UtilitiesDXXL_Bezier.GetPositionsFromTransformsArray; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform GetForwardControlPosFromTransformsArray_preAllocated = UtilitiesDXXL_Bezier.GetForwardControlPosFromTransformsArray; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform GetBackwardControlPosFromTransformsArray_preAllocated = UtilitiesDXXL_Bezier.GetBackwardControlPosFromTransformsArray; + /// 通过 Transform 数组绘制贝塞尔样条曲线。 + public static void BezierSpline(Transform[] points, Color color = default(Color), BezierPosInterpretation interpretationOfArray = BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + UtilitiesDXXL_Bezier.BezierSpline(false, 0.0f, points, GetPositionsFromTransformsArray_preAllocated, GetForwardControlPosFromTransformsArray_preAllocated, GetBackwardControlPosFromTransformsArray_preAllocated, points.Length, color, interpretationOfArray, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex> GetPositionsFromTransformsList_preAllocated = UtilitiesDXXL_Bezier.GetPositionsFromTransformsList; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform> GetForwardControlPosFromTransformsList_preAllocated = UtilitiesDXXL_Bezier.GetForwardControlPosFromTransformsList; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform> GetBackwardControlPosFromTransformsList_preAllocated = UtilitiesDXXL_Bezier.GetBackwardControlPosFromTransformsList; + /// 通过 Transform 列表绘制贝塞尔样条曲线。 + public static void BezierSpline(List points, Color color = default(Color), BezierPosInterpretation interpretationOfList = BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + UtilitiesDXXL_Bezier.BezierSpline>(false, 0.0f, points, GetPositionsFromTransformsList_preAllocated, GetForwardControlPosFromTransformsList_preAllocated, GetBackwardControlPosFromTransformsList_preAllocated, points.Count, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex GetPositionsFromVector3Array_preAllocated = UtilitiesDXXL_Bezier.GetPositionsFromVector3Array; + /// 通过 Vector3 数组绘制贝塞尔样条曲线。 + public static void BezierSpline(Vector3[] points, Color color = default(Color), BezierPosInterpretation interpretationOfArray = BezierPosInterpretation.start_control1_control2_endIsNextStart, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //"interpretationOfArray": only "start_control1_control2_endIsNextStart" and "start_control1_endIsNextStart" are supported for the "BezierSpline" overloads that supply the spline positions as "Vector3". For the other "BezierPosInterpretation": Use a function overload that takes "Transform" or "GameObject" + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (interpretationOfArray == BezierPosInterpretation.start_control1_control2_endIsNextStart || interpretationOfArray == BezierPosInterpretation.start_control1_endIsNextStart) + { + UtilitiesDXXL_Bezier.BezierSpline(false, 0.0f, points, GetPositionsFromVector3Array_preAllocated, null, null, points.Length, color, interpretationOfArray, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + else + { + Debug.LogError("The specified interpretationOfArray ('" + interpretationOfArray + "') is not supported for BezierSpline() function overloads that take 'Vector3'-collections. You may choose an overload that takes 'Transform'- or 'GameObject'-collections."); + } + } + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex> GetPositionsFromVector3List_preAllocated = UtilitiesDXXL_Bezier.GetPositionsFromVector3List; + /// 通过 Vector3 列表绘制贝塞尔样条曲线。 + public static void BezierSpline(List points, Color color = default(Color), BezierPosInterpretation interpretationOfList = BezierPosInterpretation.start_control1_control2_endIsNextStart, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //"interpretationOfArray": only "start_control1_control2_endIsNextStart" and "start_control1_endIsNextStart" are supported for the "BezierSpline" overloads that supply the spline positions as "Vector3". For the other "BezierPosInterpretation": Use a function overload that takes "Transform" or "GameObject" + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (interpretationOfList == BezierPosInterpretation.start_control1_control2_endIsNextStart || interpretationOfList == BezierPosInterpretation.start_control1_endIsNextStart) + { + UtilitiesDXXL_Bezier.BezierSpline>(false, 0.0f, points, GetPositionsFromVector3List_preAllocated, null, null, points.Count, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + else + { + Debug.LogError("The specified interpretationOfList ('" + interpretationOfList + "') is not supported for BezierSpline() function overloads that take 'Vector3'-collections. You may choose an overload that takes 'Transform'- or 'GameObject'-collections."); + } + } + + /// 获取自当前周期开始以来已绘制的线段数量。 + public static int GetNumberOfDrawnLinesSinceCycleStart() + { + return DXXLWrapperForUntiysBuildInDrawLines.DrawnLinesSinceFrameStart; + } + + /// 全局覆盖 durationInSec 参数的开关。 + public static void ToggleGlobalOverwriteFor_durationInSec(bool globalOverwriteIsEnabled, float valueOf_durationInSec_thatShouldAlwaysBeEnforced = 0.0f) + { + DXXLWrapperForUntiysBuildInDrawLines.ToggleGlobalOverwriteFor_durationInSec(globalOverwriteIsEnabled, valueOf_durationInSec_thatShouldAlwaysBeEnforced); + } + + /// 全局覆盖 hiddenByNearerObjects 参数的开关。 + public static void ToggleGlobalOverwriteFor_hiddenByNearerObjects(bool globalOverwriteIsEnabled, bool valueOf_hiddenByNearerObjects_thatShouldAlwaysBeEnforced = true) + { + DXXLWrapperForUntiysBuildInDrawLines.ToggleGlobalOverwriteFor_hiddenByNearerObjects(globalOverwriteIsEnabled, valueOf_hiddenByNearerObjects_thatShouldAlwaysBeEnforced); + } + + /// 将屏幕空间的样式模式缩放因子转换为世界空间(基于线段起点和终点)。 + public static float StylePatternScaleFactor_screenspaceToWorldspace(Vector3 positionOfLineStart, Vector3 positionOfLineEnd, float stylePatternScaleFactor_inScreenspace = 1.0f, Camera screenspaceDefiningCamera = null) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(positionOfLineStart, "positionOfLineStart")) { return 1.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(positionOfLineEnd, "positionOfLineEnd")) { return 1.0f; } + + Vector3 centerOfLine = 0.5f * (positionOfLineStart + positionOfLineEnd); + return StylePatternScaleFactor_screenspaceToWorldspace(centerOfLine, stylePatternScaleFactor_inScreenspace, screenspaceDefiningCamera); + } + + public static float StylePatternScaleFactor_screenspaceToWorldspace(Vector3 positionOfStyledObject, float stylePatternScaleFactor_inScreenspace = 1.0f, Camera screenspaceDefiningCamera = null) + { + //Many draw functions (e.g. like "DrawBasics.Line()"(link) have a "stylePatternScaleFactor" paramter, which scales the line style pattern, so different camera distances can be served with a recognizable pattern. This function can be used to generate "stylePatternScaleFactors" with which the line styles always appear with a constant screenspace pattern size. Just fill the return value of this function into the "stylePatternScaleFactor" parameter of the other drawing functions. + //The downside of fixed screenspace size patterns is, that if you change the camera position so that a line comes closer or gets farer, then the pattern is not "mounted/fixed" at the line start and end position, since the line changes its length on the screen, but the pattern remains with constant size in the screen. This can compromise the viewers intuitive perception of the line as an object in 3D space. + //The function is only a rough approximation, and the returned values may have a notable error span when "positionOfStyledObject" is more and more in a screen corner or for certain distances from the camera. + //"stylePatternScaleFactor_inScreenspace": scales the pattern inside the screenspace + //"screenspaceDefiningCamera": if it is not specified then "DrawScreenspace.defaultCameraForDrawing" or "DrawScreenspace.defaultScreenspaceWindowForDrawing" is used as fallback. + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(positionOfStyledObject, "positionOfStyledObject")) { return 1.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stylePatternScaleFactor_inScreenspace, "stylePatternScaleFactor_inScreenspace")) { return 1.0f; } + + stylePatternScaleFactor_inScreenspace = Mathf.Abs(stylePatternScaleFactor_inScreenspace); + stylePatternScaleFactor_inScreenspace = Mathf.Max(stylePatternScaleFactor_inScreenspace, 0.01f); + + Camera usedCamera; + if (screenspaceDefiningCamera == null) + { + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out usedCamera, "DrawBasics.ScreenspaceStylePatternScaleFactor_to_WorldspaceStylePatternScaleFactor") == false) { return 1.0f; } + } + else + { + usedCamera = screenspaceDefiningCamera; + } + + float distanceToCamera = (positionOfStyledObject - usedCamera.transform.position).magnitude; + //float diagonalExtentOfViewport_at_distanceFromCam = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(usedCamera, distanceToCamera); + float diagonalExtentOfViewport_at_distanceFromCam = UtilitiesDXXL_Screenspace.Get_vertExtentOfViewport_at_distanceFromCam(usedCamera, distanceToCamera); + float stylePatternScaleFactor_inWorldspace = diagonalExtentOfViewport_at_distanceFromCam * stylePatternScaleFactor_inScreenspace; + stylePatternScaleFactor_inWorldspace = Mathf.Max(stylePatternScaleFactor_inWorldspace, UtilitiesDXXL_LineStyles.minStylePatternScaleFactor); + return stylePatternScaleFactor_inWorldspace; + } + + } + +} + + + + + diff --git a/Runtime/DrawDebugLibrary/DrawBasics.cs.meta b/Runtime/DrawDebugLibrary/DrawBasics.cs.meta new file mode 100644 index 0000000..101c608 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawBasics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c21f47c57d3aec440a8bdea3d5e3cf58 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawBasics2D.cs b/Runtime/DrawDebugLibrary/DrawBasics2D.cs new file mode 100644 index 0000000..7429c46 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawBasics2D.cs @@ -0,0 +1,857 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class DrawBasics2D + { + private static float default_zPos_forDrawing = 0.0f; + public static float Default_zPos_forDrawing + { + get { return default_zPos_forDrawing; } + set + { + if (float.IsNaN(value) || float.IsInfinity(value)) + { + Debug.LogError("Cannot set 'default_zPos_forDrawing' to " + value); + } + else + { + default_zPos_forDrawing = value; + } + } + } + + /// 在2D平面上绘制一条线段。 + public static void Line(Vector2 start, Vector2 end, Color color = default(Color), float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Line_fadeableAnimSpeed_2D.InternalDraw(start, end, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 在2D平面上绘制一条射线。 + public static void Ray(Vector2 start, Vector2 direction, Color color = default(Color), float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Ray_fadeableAnimSpeed_2D.InternalDraw(start, direction, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 从起点沿指定方向绘制一条2D线段。 + public static void LineFrom(Vector2 start, Vector2 direction, Color color = default(Color), float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + LineFrom_fadeableAnimSpeed_2D.InternalDraw(start, direction, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 从指定方向朝向终点绘制一条2D线段。 + public static void LineTo(Vector2 direction, Vector2 end, Color color = default(Color), float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + LineTo_fadeableAnimSpeed_2D.InternalDraw(direction, end, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制一条颜色从起点渐变到终点的2D线段。 + public static void LineColorFade(Vector2 start, Vector2 end, Color startColor, Color endColor, float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Line_fadeableAnimSpeed_2D.InternalDrawColorFade(start, end, startColor, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制一条颜色从起点渐变到终点的2D射线。 + public static void RayColorFade(Vector2 start, Vector2 direction, Color startColor, Color endColor, float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Ray_fadeableAnimSpeed_2D.InternalDrawColorFade(start, direction, startColor, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 从起点沿方向绘制一条颜色渐变的2D线段。 + public static void LineFrom_withColorFade(Vector2 start, Vector2 direction, Color startColor, Color endColor, float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + LineFrom_fadeableAnimSpeed_2D.InternalDraw_withColorFade(start, direction, startColor, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 朝向终点绘制一条颜色渐变的2D线段。 + public static void LineTo_withColorFade(Vector2 direction, Vector2 end, Color startColor, Color endColor, float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + LineTo_fadeableAnimSpeed_2D.InternalDraw_withColorFade(direction, end, startColor, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 在2D平面上绘制一段圆弧线(通过圆心和起止方向向量)。 + public static void LineCircled(Vector2 circleCenter, Vector2 circleCenter_to_start, Vector2 circleCenter_to_end, Color color = default(Color), float forceRadius = 0.0f, float width = 0.0f, string text = null, bool useReflexAngleOver180deg = false, float custom_zPos = float.PositiveInfinity, bool skipFallbackDisplayOfZeroAngles = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 circleCenterV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenter, zPos); + Vector3 circleCenter_to_startV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(circleCenter_to_start); + Vector3 circleCenter_to_endV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(circleCenter_to_end); + UtilitiesDXXL_LineCircled.LineCircled(circleCenterV3, circleCenter_to_startV3, circleCenter_to_endV3, color, forceRadius, width, text, useReflexAngleOver180deg, skipFallbackDisplayOfZeroAngles, true, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一段圆弧线(通过起点、圆心和转角)。 + public static void LineCircled(Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color = default(Color), float width = 0.0f, string text = null, float custom_zPos = float.PositiveInfinity, bool skipFallbackDisplayOfZeroAngles = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 startPosV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(startPos, zPos); + Vector3 turnAxis_originV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenter, zPos); + UtilitiesDXXL_LineCircled.LineCircled(startPosV3, turnAxis_originV3, Vector3.forward, turnAngleDegCC, color, width, text, skipFallbackDisplayOfZeroAngles, true, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + + /// 在2D平面上绘制一段圆弧线(通过圆心、起始角度和结束角度)。 + public static void LineCircled(Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius = 0.5f, Color color = default(Color), float width = 0.0f, string text = null, float custom_zPos = float.PositiveInfinity, bool skipFallbackDisplayOfZeroAngles = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(startAngleDegCC_relativeToUp, "startAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(endAngleDegCC_relativeToUp, "endAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 turnAxis_originV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenter, zPos); + float turnedAngleDegCC_fromStartAngle = endAngleDegCC_relativeToUp - startAngleDegCC_relativeToUp; + Quaternion rotation_fromUp_toLineStart = Quaternion.AngleAxis(startAngleDegCC_relativeToUp, Vector3.forward); + Vector3 cirleCenter_towards_lineStart_normalized = rotation_fromUp_toLineStart * Vector3.up; + Vector3 startPosV3 = turnAxis_originV3 + cirleCenter_towards_lineStart_normalized * radius; + UtilitiesDXXL_LineCircled.LineCircled(startPosV3, turnAxis_originV3, Vector3.forward, turnedAngleDegCC_fromStartAngle, color, width, text, skipFallbackDisplayOfZeroAngles, true, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + + /// 在2D平面上绘制一个扇形(通过圆心和起止方向向量)。 + public static void CircleSegment(Vector2 circleCenter, Vector2 circleCenter_to_startPosOnPerimeter, Vector2 circleCenter_to_endPosOnPerimeter, Color color = default(Color), float forceRadius = 0.0f, string text = null, bool useReflexAngleOver180deg = false, float custom_zPos = float.PositiveInfinity, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 circleCenterV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenter, zPos); + Vector3 circleCenter_to_startV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(circleCenter_to_startPosOnPerimeter); + Vector3 circleCenter_to_endV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(circleCenter_to_endPosOnPerimeter); + UtilitiesDXXL_LineCircled.CircleSegment(circleCenterV3, circleCenter_to_startV3, circleCenter_to_endV3, color, forceRadius, fillDensity, text, useReflexAngleOver180deg, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL.LowerLeftOfWholeTextBlock, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个扇形(通过起点、圆心和转角)。 + public static void CircleSegment(Vector2 startPosOnPerimeter, Vector2 circleCenter, float turnAngleDegCC, Color color = default(Color), string text = null, float custom_zPos = float.PositiveInfinity, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 startPosV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(startPosOnPerimeter, zPos); + Vector3 turnAxis_originV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenter, zPos); + UtilitiesDXXL_LineCircled.CircleSegment(startPosV3, turnAxis_originV3, Vector3.forward, turnAngleDegCC, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL.LowerLeftOfWholeTextBlock); + } + + /// 在2D平面上绘制一个扇形(通过圆心、起始角度和结束角度)。 + public static void CircleSegment(Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius = 0.5f, Color color = default(Color), string text = null, float custom_zPos = float.PositiveInfinity, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(startAngleDegCC_relativeToUp, "startAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(endAngleDegCC_relativeToUp, "endAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 turnAxis_originV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenter, zPos); + float turnedAngleDegCC_fromStartAngle = endAngleDegCC_relativeToUp - startAngleDegCC_relativeToUp; + Quaternion rotation_fromUp_toLineStart = Quaternion.AngleAxis(startAngleDegCC_relativeToUp, Vector3.forward); + Vector3 cirleCenter_towards_lineStart_normalized = rotation_fromUp_toLineStart * Vector3.up; + Vector3 startPosV3 = turnAxis_originV3 + cirleCenter_towards_lineStart_normalized * radius; + UtilitiesDXXL_LineCircled.CircleSegment(startPosV3, turnAxis_originV3, Vector3.forward, turnedAngleDegCC_fromStartAngle, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL.LowerLeftOfWholeTextBlock); + } + + /// 通过一组点数组绘制一条2D折线。 + public static void LineString(Vector2[] points, Color color = default(Color), bool closeGapBetweenLastAndFirstPoint = false, float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + + if (points.Length == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + for (int i = 0; i < (points.Length - 1); i++) + { + Line_fadeableAnimSpeed_2D.InternalDraw(points[i], points[i + 1], color, width, null, style, zPos, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed_2D.InternalDraw(points[points.Length - 1], points[0], color, width, null, style, zPos, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (text != null && text != "") + { + TagLineString(zPos, text, points, width, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + /// 通过一组点列表绘制一条2D折线。 + public static void LineString(List points, Color color = default(Color), bool closeGapBetweenLastAndFirstPoint = false, float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + + if (points.Count == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + for (int i = 0; i < (points.Count - 1); i++) + { + Line_fadeableAnimSpeed_2D.InternalDraw(points[i], points[i + 1], color, width, null, style, zPos, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed_2D.InternalDraw(points[points.Count - 1], points[0], color, width, null, style, zPos, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (text != null && text != "") + { + TagLineString(zPos, text, points, width, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + /// 绘制一条颜色渐变的2D折线(使用点数组)。 + public static void LineStringColorFade(Vector2[] points, Color startColor, Color endColor, bool closeGapBetweenLastAndFirstPoint = false, float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + + if (points.Length == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + int iOffset_forColorFade = -1; + if (closeGapBetweenLastAndFirstPoint) + { + iOffset_forColorFade = 0; + } + + for (int i = 0; i < (points.Length - 1); i++) + { + Color color = UtilitiesDXXL_DrawBasics.GetFadedColorFromSegments(startColor, endColor, i, points.Length + iOffset_forColorFade); + Line_fadeableAnimSpeed_2D.InternalDraw(points[i], points[i + 1], color, width, null, style, zPos, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed_2D.InternalDraw(points[points.Length - 1], points[0], endColor, width, null, style, zPos, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (text != null && text != "") + { + Color averageColor = Color.Lerp(startColor, endColor, 0.5f); + TagLineString(zPos, text, points, width, averageColor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + /// 绘制一条颜色渐变的2D折线(使用点列表)。 + public static void LineStringColorFade(List points, Color startColor, Color endColor, bool closeGapBetweenLastAndFirstPoint = false, float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + + if (points.Count == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + int iOffset_forColorFade = -1; + if (closeGapBetweenLastAndFirstPoint) + { + iOffset_forColorFade = 0; + } + + for (int i = 0; i < (points.Count - 1); i++) + { + Color color = UtilitiesDXXL_DrawBasics.GetFadedColorFromSegments(startColor, endColor, i, points.Count + iOffset_forColorFade); + Line_fadeableAnimSpeed_2D.InternalDraw(points[i], points[i + 1], color, width, null, style, zPos, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed_2D.InternalDraw(points[points.Count - 1], points[0], endColor, width, null, style, zPos, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (text != null && text != "") + { + Color averageColor = Color.Lerp(startColor, endColor, 0.5f); + TagLineString(zPos, text, points, width, averageColor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + static void TagLineString(float zPos, string text, Vector2[] lineStringVerticesGlobal, float linesWidth, Color colorOfLines, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (lineStringVerticesGlobal.Length <= 0) + { + Debug.LogError("lineStringVerticesGlobal has " + lineStringVerticesGlobal.Length + " items -> no 'drawTag' operation"); + return; + } + + if (text != null && text != "") + { + float xMin = UtilitiesDXXL_Math.GetLowestXComponent(lineStringVerticesGlobal); + float xMax = UtilitiesDXXL_Math.GetHighestXComponent(lineStringVerticesGlobal); + float yMin = UtilitiesDXXL_Math.GetLowestYComponent(lineStringVerticesGlobal); + float yMax = UtilitiesDXXL_Math.GetHighestYComponent(lineStringVerticesGlobal); + Vector3 virtualScale = new Vector3(xMax - xMin, yMax - yMin, 0.0f); + Vector3 centerPosition = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(lineStringVerticesGlobal[0], zPos); + for (int i = 0; i < lineStringVerticesGlobal.Length; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref UtilitiesDXXL_Shapes.verticesLocal, UtilitiesDXXL_DrawBasics2D.Position_V2toV3(lineStringVerticesGlobal[i], zPos) - centerPosition, i); + } + Color invertedColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(colorOfLines); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centerPosition, lineStringVerticesGlobal.Length, 0.1f * linesWidth, virtualScale, invertedColor, invertedColor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + static void TagLineString(float zPos, string text, List lineStringVerticesGlobal, float linesWidth, Color colorOfLines, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (lineStringVerticesGlobal.Count <= 0) + { + Debug.LogError("lineStringVerticesGlobal has " + lineStringVerticesGlobal.Count + " items -> no 'drawTag' operation"); + return; + } + + if (text != null && text != "") + { + float xMin = UtilitiesDXXL_Math.GetLowestXComponent(lineStringVerticesGlobal); + float xMax = UtilitiesDXXL_Math.GetHighestXComponent(lineStringVerticesGlobal); + float yMin = UtilitiesDXXL_Math.GetLowestYComponent(lineStringVerticesGlobal); + float yMax = UtilitiesDXXL_Math.GetHighestYComponent(lineStringVerticesGlobal); + Vector3 virtualScale = new Vector3(xMax - xMin, yMax - yMin, 0.0f); + Vector3 centerPosition = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(lineStringVerticesGlobal[0], zPos); + for (int i = 0; i < lineStringVerticesGlobal.Count; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref UtilitiesDXXL_Shapes.verticesLocal, UtilitiesDXXL_DrawBasics2D.Position_V2toV3(lineStringVerticesGlobal[i], zPos) - centerPosition, i); + } + Color invertedColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(colorOfLines); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centerPosition, lineStringVerticesGlobal.Count, 0.1f * linesWidth, virtualScale, invertedColor, invertedColor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + /// 在2D平面上绘制一组点数组,每个点以十字标记表示。 + public static void PointArray(Vector2[] points, Color color = default(Color), float sizeOfMarkingCross = 1.0f, float markingCrossLinesWidth = 0.0f, bool drawCoordsAsText = true, float custom_zPos = float.PositiveInfinity, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + for (int i = 0; i < points.Length; i++) + { + Point(points[i], color, sizeOfMarkingCross, 0.0f, markingCrossLinesWidth, null, color, zPos, false, drawCoordsAsText, durationInSec, hiddenByNearerObjects); + } + } + + /// 在2D平面上绘制一组点列表,每个点以十字标记表示。 + public static void PointList(List points, Color color = default(Color), float sizeOfMarkingCross = 1.0f, float markingCrossLinesWidth = 0.0f, bool drawCoordsAsText = true, float custom_zPos = float.PositiveInfinity, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + for (int i = 0; i < points.Count; i++) + { + Point(points[i], color, sizeOfMarkingCross, 0.0f, markingCrossLinesWidth, null, color, zPos, false, drawCoordsAsText, durationInSec, hiddenByNearerObjects); + } + } + + /// 在2D平面上绘制一个点,以十字标记表示(指定十字颜色)。 + public static void Point(Vector2 position, Color markingCrossColor, float sizeOfMarkingCross = 1.0f, float angleDegCC = 0.0f, float markingCrossLinesWidth = 0.0f, string text = null, Color textColor = default(Color), float custom_zPos = float.PositiveInfinity, bool pointer_as_textAttachStyle = false, bool drawCoordsAsText = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Point(position, text, textColor, sizeOfMarkingCross, markingCrossLinesWidth, zPos, markingCrossColor, angleDegCC, pointer_as_textAttachStyle, drawCoordsAsText, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个点,以十字标记表示(指定文本颜色)。 + public static void Point(Vector2 position, string text = null, Color textColor = default(Color), float sizeOfMarkingCross = 1.0f, float markingCrossLinesWidth = 0.0f, float custom_zPos = float.PositiveInfinity, Color overwrite_markingCrossColor = default(Color), float angleDegCC = 0.0f, bool pointer_as_textAttachStyle = true, bool drawCoordsAsText = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 positionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(position, zPos); + Quaternion rotation = UtilitiesDXXL_DrawBasics2D.QuaternionFromAngle(angleDegCC); + UtilitiesDXXL_DrawBasics.Point(true, positionV3, text, textColor, sizeOfMarkingCross, markingCrossLinesWidth, overwrite_markingCrossColor, rotation, pointer_as_textAttachStyle, drawCoordsAsText, false, true, Vector3.zero, Quaternion.identity, Vector3.one, true, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上为指定位置绘制一个带标签的标注点。 + public static void PointTag(Vector2 position, string text = null, Color color = default(Color), float linesWidth = 0.0f, float size_asTextOffsetDistance = 1.0f, Vector2 textOffsetDirection = default(Vector2), float custom_zPos = float.PositiveInfinity, float textSizeScaleFactor = 1.0f, bool skipConeDrawing = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 positionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(position, zPos); + Vector3 textOffsetDirV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(textOffsetDirection); + UtilitiesDXXL_DrawBasics2D.PointTag(positionV3, text, color, linesWidth, size_asTextOffsetDistance, textOffsetDirV3, textSizeScaleFactor, skipConeDrawing, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个从起点到终点的向量。 + public static void Vector(Vector2 vectorStartPos, Vector2 vectorEndPos, Color color = default(Color), float lineWidth = 0.0f, string text = null, float coneLength = 0.17f, bool pointerAtBothSides = false, float custom_zPos = float.PositiveInfinity, bool addNormalizedMarkingText = false, float enlargeSmallTextToThisMinTextSize = 0.0f, bool writeComponentValuesAsText = false, float endPlates_size = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 vectorStartPosV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(vectorStartPos, zPos); + Vector3 vectorEndPosV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(vectorEndPos, zPos); + UtilitiesDXXL_DrawBasics.Vector(vectorStartPosV3, vectorEndPosV3, color, lineWidth, text, coneLength, pointerAtBothSides, true, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, durationInSec, hiddenByNearerObjects, UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero, true, endPlates_size); + } + + /// 从起点沿指定方向绘制一个2D向量。 + public static void VectorFrom(Vector2 vectorStartPos, Vector2 vector, Color color = default(Color), float lineWidth = 0.0f, string text = null, float coneLength = 0.17f, bool pointerAtBothSides = false, float custom_zPos = float.PositiveInfinity, bool addNormalizedMarkingText = false, float enlargeSmallTextToThisMinTextSize = 0.0f, bool writeComponentValuesAsText = false, float endPlates_size = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 vectorStartPosV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(vectorStartPos, zPos); + Vector3 vectorV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(vector); + UtilitiesDXXL_DrawBasics.VectorFrom(vectorStartPosV3, vectorV3, color, lineWidth, text, coneLength, pointerAtBothSides, true, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, durationInSec, hiddenByNearerObjects, UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero, true, endPlates_size); + } + + /// 从指定方向朝向终点绘制一个2D向量。 + public static void VectorTo(Vector2 vector, Vector2 vectorEndPos, Color color = default(Color), float lineWidth = 0.0f, string text = null, float coneLength = 0.17f, bool pointerAtBothSides = false, float custom_zPos = float.PositiveInfinity, bool addNormalizedMarkingText = false, float enlargeSmallTextToThisMinTextSize = 0.0f, bool writeComponentValuesAsText = false, float endPlates_size = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector, "vector")) { return; } + VectorFrom(vectorEndPos - vector, vector, color, lineWidth, text, coneLength, pointerAtBothSides, custom_zPos, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, endPlates_size, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个带箭头的圆弧向量(通过圆心和起止方向向量)。 + public static void VectorCircled(Vector2 circleCenter, Vector2 circleCenter_to_start, Vector2 circleCenter_to_end, Color color = default(Color), float forceRadius = 0.0f, float lineWidth = 0.0f, string text = null, bool useReflexAngleOver180deg = false, float custom_zPos = float.PositiveInfinity, float coneLength = 0.17f, bool skipFallbackDisplayOfZeroAngles = false, bool pointerAtBothSides = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 circleCenterV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenter, zPos); + Vector3 circleCenter_to_startV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(circleCenter_to_start); + Vector3 circleCenter_to_endV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(circleCenter_to_end); + UtilitiesDXXL_LineCircled.VectorCircled(circleCenterV3, circleCenter_to_startV3, circleCenter_to_endV3, color, forceRadius, lineWidth, text, useReflexAngleOver180deg, coneLength, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, true, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个带箭头的圆弧向量(通过起点、圆心和转角)。 + public static void VectorCircled(Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color = default(Color), float lineWidth = 0.0f, string text = null, float custom_zPos = float.PositiveInfinity, float coneLength = 0.17f, bool skipFallbackDisplayOfZeroAngles = false, bool pointerAtBothSides = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 startPosV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(startPos, zPos); + Vector3 circleCenterV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenter, zPos); + UtilitiesDXXL_LineCircled.VectorCircled(startPosV3, circleCenterV3, Vector3.forward, turnAngleDegCC, color, lineWidth, text, coneLength, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, true, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects, 1.0f); + } + + /// 在2D平面上绘制一个带箭头的圆弧向量(通过圆心、起始角度和结束角度)。 + public static void VectorCircled(Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius = 0.5f, Color color = default(Color), float lineWidth = 0.0f, string text = null, float custom_zPos = float.PositiveInfinity, float coneLength = 0.17f, bool skipFallbackDisplayOfZeroAngles = false, bool pointerAtBothSides = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(startAngleDegCC_relativeToUp, "startAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(endAngleDegCC_relativeToUp, "endAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 circleCenterV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenter, zPos); + float turnedAngleDegCC_fromStartAngle = endAngleDegCC_relativeToUp - startAngleDegCC_relativeToUp; + Quaternion rotation_fromUp_toLineStart = Quaternion.AngleAxis(startAngleDegCC_relativeToUp, Vector3.forward); + Vector3 cirleCenter_towards_lineStart_normalized = rotation_fromUp_toLineStart * Vector3.up; + Vector3 startPosV3 = circleCenterV3 + cirleCenter_towards_lineStart_normalized * radius; + UtilitiesDXXL_LineCircled.VectorCircled(startPosV3, circleCenterV3, Vector3.forward, turnedAngleDegCC_fromStartAngle, color, lineWidth, text, coneLength, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, true, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects, 1.0f); + } + + /// 沿2D射线方向绘制移动箭头动画。 + public static void MovingArrowsRay(Vector2 start, Vector2 direction, Color color = default(Color), float lineWidth = 0.05f, float distanceBetweenArrows = 0.5f, float lengthOfArrows = 0.15f, string text = null, float custom_zPos = float.PositiveInfinity, float animationSpeed = 0.5f, bool backwardAnimationFlipsArrowDirection = true, float endPlates_size = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + MovingArrowsRay_fadeableAnimSpeed_2D.InternalDraw(start, direction, color, lineWidth, distanceBetweenArrows, lengthOfArrows, text, custom_zPos, animationSpeed, null, backwardAnimationFlipsArrowDirection, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + /// 沿2D线段绘制移动箭头动画。 + public static void MovingArrowsLine(Vector2 start, Vector2 end, Color color = default(Color), float lineWidth = 0.05f, float distanceBetweenArrows = 0.5f, float lengthOfArrows = 0.15f, string text = null, float custom_zPos = float.PositiveInfinity, float animationSpeed = 0.5f, bool backwardAnimationFlipsArrowDirection = true, float endPlates_size = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + MovingArrowsLine_fadeableAnimSpeed_2D.InternalDraw(start, end, color, lineWidth, distanceBetweenArrows, lengthOfArrows, text, custom_zPos, animationSpeed, null, backwardAnimationFlipsArrowDirection, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制交替换色的2D射线。 + public static void RayWithAlternatingColors(Vector2 start, Vector2 direction, Color color1 = default(Color), Color color2 = default(Color), float width = 0.0f, float lengthOfStripes = 0.04f, string text = null, float custom_zPos = float.PositiveInfinity, float animationSpeed = 0.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + RayWithAlternatingColors_fadeableAnimSpeed_2D.InternalDraw(start, direction, color1, color2, width, lengthOfStripes, text, custom_zPos, animationSpeed, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制交替换色的2D线段。 + public static void LineWithAlternatingColors(Vector2 start, Vector2 end, Color color1 = default(Color), Color color2 = default(Color), float width = 0.0f, float lengthOfStripes = 0.04f, string text = null, float custom_zPos = float.PositiveInfinity, float animationSpeed = 0.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + //Lines drawn with this function have a higher likelyhood of accidentially using up high numbers of drawnLinePerFrame, because "lengthOfStripes" can be set manually instead of beeing determined by the lineStyle-code + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + LineWithAlternatingColors_fadeableAnimSpeed_2D.InternalDraw(start, end, color1, color2, width, lengthOfStripes, text, custom_zPos, animationSpeed, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制闪烁的2D射线。 + public static void BlinkingRay(Vector2 start, Vector2 direction, Color primaryColor = default(Color), float blinkDurationInSec = 0.5f, float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, Color blinkColor = default(Color), float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return; } + + Vector2 end = start + direction; + BlinkingLine(start, end, primaryColor, blinkDurationInSec, width, text, style, blinkColor, custom_zPos, stylePatternScaleFactor, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制闪烁的2D线段。 + public static void BlinkingLine(Vector2 start, Vector2 end, Color primaryColor = default(Color), float blinkDurationInSec = 0.5f, float width = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, Color blinkColor = default(Color), float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float endPlates_size = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(blinkDurationInSec, "blinkDurationInSec")) { return; } + + blinkDurationInSec = Mathf.Max(blinkDurationInSec, UtilitiesDXXL_DrawBasics.min_blinkDurationInSec); + float passedBlinkIntervallsSinceStartup = UtilitiesDXXL_LineStyles.GetTime() / blinkDurationInSec; + primaryColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(primaryColor); + if (UtilitiesDXXL_Math.CheckIf_givenNumberIs_evenNotOdd(Mathf.FloorToInt(passedBlinkIntervallsSinceStartup))) + { + Line_fadeableAnimSpeed_2D.InternalDraw(start, end, primaryColor, width, text, style, custom_zPos, stylePatternScaleFactor, 0.0f, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + if (UtilitiesDXXL_Colors.IsDefaultColor(blinkColor)) + { + Color alternatingBlinkColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(primaryColor); + alternatingBlinkColor = UtilitiesDXXL_Colors.OverwriteColorNearGreyWithBlack(alternatingBlinkColor); + Line_fadeableAnimSpeed_2D.InternalDraw(start, end, alternatingBlinkColor, width, text, style, custom_zPos, stylePatternScaleFactor, 0.0f, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + Line_fadeableAnimSpeed_2D.InternalDraw(start, end, blinkColor, width, text, style, custom_zPos, stylePatternScaleFactor, 0.0f, null, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + } + + /// 绘制带有张力指示的2D射线。 + public static void RayUnderTension(Vector2 start, Vector2 direction, float relaxedLength = 1.0f, Color relaxedColor = default(Color), DrawBasics.LineStyle style = DrawBasics.LineStyle.sine, float stretchFactor_forStretchedTensionColor = 2.0f, Color color_forStretchedTension = default(Color), float stretchFactor_forSqueezedTensionColor = 0.0f, Color color_forSqueezedTension = default(Color), float width = 0.0f, string text = null, float alphaOfReferenceLengthDisplay = 0.15f, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float endPlates_size = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return; } + LineUnderTension(start, start + direction, relaxedLength, relaxedColor, style, stretchFactor_forStretchedTensionColor, color_forStretchedTension, stretchFactor_forSqueezedTensionColor, color_forSqueezedTension, width, text, alphaOfReferenceLengthDisplay, custom_zPos, stylePatternScaleFactor, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + /// 绘制带有张力指示的2D线段。 + public static void LineUnderTension(Vector2 start, Vector2 end, float relaxedLength = 1.0f, Color relaxedColor = default(Color), DrawBasics.LineStyle style = DrawBasics.LineStyle.sine, float stretchFactor_forStretchedTensionColor = 2.0f, Color color_forStretchedTension = default(Color), float stretchFactor_forSqueezedTensionColor = 0.0f, Color color_forSqueezedTension = default(Color), float width = 0.0f, string text = null, float alphaOfReferenceLengthDisplay = 0.15f, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, float endPlates_size = 0.0f, float enlargeSmallTextToThisMinTextSize = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true, bool skipPatternEnlargementForLongLines = false, bool skipPatternEnlargementForShortLines = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 startV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(start, zPos); + Vector3 endV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(end, zPos); + style = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(style); + + bool parametersAreInvalid = UtilitiesDXXL_DrawBasics.GetSpecsOfLineUnderTension(out float tensionFactor, out Color usedColor, out float lineLength, startV3, endV3, relaxedLength, relaxedColor, color_forStretchedTension, color_forSqueezedTension, stretchFactor_forStretchedTensionColor, stretchFactor_forSqueezedTensionColor); + if (parametersAreInvalid) { return; } + + UtilitiesDXXL_DrawBasics.TryDrawReferenceLengthDisplay_ofLineUnderTension(startV3, endV3, alphaOfReferenceLengthDisplay, relaxedLength, relaxedColor, lineLength, UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Line(startV3, endV3, usedColor, width, text, style, stylePatternScaleFactor, 0.0f, null, UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero, true, 0.0f, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, null, true, endPlates_size, tensionFactor); + } + + /// 在2D平面上绘制一个图标。 + public static void Icon(Vector2 position, DrawBasics.IconType icon, Color color = default(Color), float size = 1.0f, string text = null, float turnAngleDegCC = 0.0f, int strokeWidth_asPPMofSize = 0, float custom_zPos = float.PositiveInfinity, bool mirrorHorizontally = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 positionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(position, zPos); + Quaternion rotation = UtilitiesDXXL_DrawBasics2D.QuaternionFromAngle(turnAngleDegCC); + UtilitiesDXXL_DrawBasics.Icon(positionV3, icon, color, size, text, rotation, strokeWidth_asPPMofSize, mirrorHorizontally, durationInSec, hiddenByNearerObjects, 0.1f, 0.004f, true); + } + + /// 在2D平面上绘制指定形状(使用矩形包围盒)。 + public static void Shape(Rect boxRect, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, Color color = default(Color), float angleDegCC = 0.0f, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Box(boxRect, color, angleDegCC, shape, linesWidth, text, lineStyle, zPos, stylePatternScaleFactor, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制指定形状(使用中心位置和尺寸)。 + public static void Shape(Vector2 centerPosition, DrawShapes.Shape2DType shape, Vector2 size, Color color = default(Color), float angleDegCC = 0.0f, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Box(centerPosition, size, color, angleDegCC, shape, linesWidth, text, lineStyle, zPos, stylePatternScaleFactor, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个实心圆点。 + public static void Dot(Vector2 position, float radius = 0.5f, Color color = default(Color), string text = null, float custom_zPos = float.PositiveInfinity, float density = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 centerPositionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(position, zPos); + DrawBasics.Dot(centerPositionV3, radius, Vector3.forward, color, text, density, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个矩形框(通过 Rect 包围盒)。 + public static void Box(Rect boxRect, Color color = default(Color), float angleDegCC = 0.0f, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + DrawShapes.Box2D(boxRect, color, zPos, angleDegCC, shape, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个矩形框(通过中心位置和尺寸)。 + public static void Box(Vector2 centerPosition, Vector2 size, Color color = default(Color), float angleDegCC = 0.0f, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + DrawShapes.Box2D(centerPosition, size, color, zPos, angleDegCC, shape, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个圆形(通过矩形包围盒)。 + public static void Circle(Rect hullRect, Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + DrawShapes.Circle2D(hullRect, color, zPos, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个圆形(通过中心位置和半径)。 + public static void Circle(Vector2 centerPosition, float radius = 0.5f, Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + DrawShapes.Circle2D(centerPosition, radius, color, zPos, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个胶囊体(通过两个圆心位置)。 + public static void Capsule(Vector2 posOfCircle1, Vector2 posOfCircle2, float radius = 0.5f, Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + DrawShapes.Capsule2D(posOfCircle1, posOfCircle2, radius, color, zPos, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个胶囊体(通过矩形包围盒)。 + public static void Capsule(Rect hullRect, Color color = default(Color), CapsuleDirection2D capsuleDirection = CapsuleDirection2D.Vertical, float angleDegCC = 0.0f, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + DrawShapes.Capsule2D(hullRect, color, zPos, capsuleDirection, angleDegCC, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 在2D平面上绘制一个胶囊体(通过中心位置和尺寸)。 + public static void Capsule(Vector2 centerPosition, Vector2 size, Color color = default(Color), CapsuleDirection2D capsuleDirection = CapsuleDirection2D.Vertical, float angleDegCC = 0.0f, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float custom_zPos = float.PositiveInfinity, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + DrawShapes.Capsule2D(centerPosition, size, color, zPos, capsuleDirection, angleDegCC, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 绘制2D二次贝塞尔曲线(使用两个 GameObject 定义起点方向和终点)。 + public static void BezierSegmentQuadratic(GameObject startPositionAndDirection, GameObject endPosition, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPositionAndDirection, "startPositionAndDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + BezierSegmentQuadratic(startPositionAndDirection.transform, endPosition.transform, color, text, width, straightSubDivisions, custom_zPos, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制2D二次贝塞尔曲线(使用两个 Transform 定义起点方向和终点)。 + public static void BezierSegmentQuadratic(Transform startPositionAndDirection, Transform endPosition, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPositionAndDirection, "startPositionAndDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + Vector3 controlPosInBetween = startPositionAndDirection.position + startPositionAndDirection.right * startPositionAndDirection.localScale.x; + BezierSegmentQuadratic(startPositionAndDirection.position, endPosition.position, controlPosInBetween, color, text, width, straightSubDivisions, custom_zPos, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制2D二次贝塞尔曲线(使用三个 GameObject 作为起点、终点和控制点)。 + public static void BezierSegmentQuadratic(GameObject startPosition, GameObject endPosition, GameObject controlPosInBetween, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosInBetween, "controlPosInBetween")) { return; } + BezierSegmentQuadratic(startPosition.transform.position, endPosition.transform.position, controlPosInBetween.transform.position, color, text, width, straightSubDivisions, custom_zPos, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制2D二次贝塞尔曲线(使用三个 Transform 作为起点、终点和控制点)。 + public static void BezierSegmentQuadratic(Transform startPosition, Transform endPosition, Transform controlPosInBetween, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosInBetween, "controlPosInBetween")) { return; } + BezierSegmentQuadratic(startPosition.position, endPosition.position, controlPosInBetween.position, color, text, width, straightSubDivisions, custom_zPos, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制2D二次贝塞尔曲线(使用三个 Vector2 作为起点、终点和控制点)。 + public static void BezierSegmentQuadratic(Vector2 startPosition, Vector2 endPosition, Vector2 controlPosInBetween, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(controlPosInBetween, "controlPosInBetween")) { return; } + + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 startPositionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(startPosition, zPos); + Vector3 endPositionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(endPosition, zPos); + Vector3 controlPosInBetweenV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(controlPosInBetween, zPos); + UtilitiesDXXL_Bezier.BezierSegmentQuadratic(true, startPositionV3, endPositionV3, controlPosInBetweenV3, color, text, width, straightSubDivisions, textSize, true, durationInSec, hiddenByNearerObjects); + } + + /// 绘制2D三次贝塞尔曲线(使用两个 GameObject 定义起点和终点的方向)。 + public static void BezierSegmentCubic(GameObject startPositionAndDirection, GameObject endPositionAndDirection, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float custom_zPos = float.PositiveInfinity, bool closeGapFromEndToStart = false, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPositionAndDirection, "startPositionAndDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPositionAndDirection, "endPositionAndDirection")) { return; } + BezierSegmentCubic(startPositionAndDirection.transform, endPositionAndDirection.transform, color, text, width, straightSubDivisions, custom_zPos, closeGapFromEndToStart, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制2D三次贝塞尔曲线(使用两个 Transform 定义起点和终点的方向)。 + public static void BezierSegmentCubic(Transform startPositionAndDirection, Transform endPositionAndDirection, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float custom_zPos = float.PositiveInfinity, bool closeGapFromEndToStart = false, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPositionAndDirection, "startPositionAndDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPositionAndDirection, "endPositionAndDirection")) { return; } + Vector3 controlPosOfStartDirection = startPositionAndDirection.position + startPositionAndDirection.right * startPositionAndDirection.localScale.x; + Vector3 controlPosOfEndDirection = endPositionAndDirection.position - endPositionAndDirection.right * endPositionAndDirection.localScale.x; + BezierSegmentCubic(startPositionAndDirection.position, endPositionAndDirection.position, controlPosOfStartDirection, controlPosOfEndDirection, color, text, width, straightSubDivisions, custom_zPos, closeGapFromEndToStart, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制2D三次贝塞尔曲线(使用四个 GameObject 作为起点、终点和两个控制点)。 + public static void BezierSegmentCubic(GameObject startPosition, GameObject endPosition, GameObject controlPosOfStartDirection, GameObject controlPosOfEndDirection, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float custom_zPos = float.PositiveInfinity, bool closeGapFromEndToStart = false, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosOfStartDirection, "controlPosOfStartDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosOfEndDirection, "controlPosOfEndDirection")) { return; } + BezierSegmentCubic(startPosition.transform.position, endPosition.transform.position, controlPosOfStartDirection.transform.position, controlPosOfEndDirection.transform.position, color, text, width, straightSubDivisions, custom_zPos, closeGapFromEndToStart, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制2D三次贝塞尔曲线(使用四个 Transform 作为起点、终点和两个控制点)。 + public static void BezierSegmentCubic(Transform startPosition, Transform endPosition, Transform controlPosOfStartDirection, Transform controlPosOfEndDirection, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float custom_zPos = float.PositiveInfinity, bool closeGapFromEndToStart = false, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosOfStartDirection, "controlPosOfStartDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(controlPosOfEndDirection, "controlPosOfEndDirection")) { return; } + BezierSegmentCubic(startPosition.position, endPosition.position, controlPosOfStartDirection.position, controlPosOfEndDirection.position, color, text, width, straightSubDivisions, custom_zPos, closeGapFromEndToStart, textSize, durationInSec, hiddenByNearerObjects); + } + + /// 绘制2D三次贝塞尔曲线(使用四个 Vector2 作为起点、终点和两个控制点)。 + public static void BezierSegmentCubic(Vector2 startPosition, Vector2 endPosition, Vector2 controlPosOfStartDirection, Vector2 controlPosOfEndDirection, Color color = default(Color), string text = null, float width = 0.0f, int straightSubDivisions = 50, float custom_zPos = float.PositiveInfinity, bool closeGapFromEndToStart = false, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPosition, "startPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(endPosition, "endPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(controlPosOfStartDirection, "controlPosOfStartDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(controlPosOfEndDirection, "controlPosOfEndDirection")) { return; } + + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 startPositionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(startPosition, zPos); + Vector3 endPositionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(endPosition, zPos); + Vector3 controlPosOfStartDirectionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(controlPosOfStartDirection, zPos); + Vector3 controlPosOfEndDirectionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(controlPosOfEndDirection, zPos); + UtilitiesDXXL_Bezier.BezierSegmentCubic(true, startPositionV3, endPositionV3, controlPosOfStartDirectionV3, controlPosOfEndDirectionV3, color, text, width, straightSubDivisions, textSize, true, durationInSec, hiddenByNearerObjects); + if (closeGapFromEndToStart) + { + Vector3 startPos_to_startControlPosV3 = controlPosOfStartDirectionV3 - startPositionV3; + Vector3 endPos_to_endControlPosV3 = controlPosOfEndDirectionV3 - endPositionV3; + Vector3 controlPosOfStartDirection_ofSecondCurveV3 = startPositionV3 - startPos_to_startControlPosV3; + Vector3 controlPosOfEndDirection_ofSecondCurveV3 = endPositionV3 - endPos_to_endControlPosV3; + UtilitiesDXXL_Bezier.BezierSegmentCubic(true, startPositionV3, endPositionV3, controlPosOfStartDirection_ofSecondCurveV3, controlPosOfEndDirection_ofSecondCurveV3, color, null, width, straightSubDivisions, textSize, true, durationInSec, hiddenByNearerObjects); + } + } + + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex GetPositions3DFromGameObjectsArray_2D_preAllocated = UtilitiesDXXL_Bezier.GetPositions3DFromGameObjectsArray_2D; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform GetForwardControlPos3DFromGameObjectsArray_2D_preAllocated = UtilitiesDXXL_Bezier.GetForwardControlPos3DFromGameObjectsArray_2D; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform GetBackwardControlPos3DFromGameObjectsArray_2D_preAllocated = UtilitiesDXXL_Bezier.GetBackwardControlPos3DFromGameObjectsArray_2D; + /// 绘制2D贝塞尔样条曲线(使用 GameObject 数组定义控制点)。 + public static void BezierSpline(GameObject[] points, Color color = default(Color), DrawBasics.BezierPosInterpretation interpretationOfArray = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + UtilitiesDXXL_Bezier.BezierSpline(true, custom_zPos, points, GetPositions3DFromGameObjectsArray_2D_preAllocated, GetForwardControlPos3DFromGameObjectsArray_2D_preAllocated, GetBackwardControlPos3DFromGameObjectsArray_2D_preAllocated, points.Length, color, interpretationOfArray, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex> GetPositions3DFromGameObjectsList_2D_preAllocated = UtilitiesDXXL_Bezier.GetPositions3DFromGameObjectsList_2D; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform> GetForwardControlPos3DFromGameObjectsList_2D_preAllocated = UtilitiesDXXL_Bezier.GetForwardControlPos3DFromGameObjectsList_2D; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform> GetBackwardControlPos3DFromGameObjectsList_2D_preAllocated = UtilitiesDXXL_Bezier.GetBackwardControlPos3DFromGameObjectsList_2D; + /// 绘制2D贝塞尔样条曲线(使用 GameObject 列表定义控制点)。 + public static void BezierSpline(List points, Color color = default(Color), DrawBasics.BezierPosInterpretation interpretationOfList = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + UtilitiesDXXL_Bezier.BezierSpline>(true, custom_zPos, points, GetPositions3DFromGameObjectsList_2D_preAllocated, GetForwardControlPos3DFromGameObjectsList_2D_preAllocated, GetBackwardControlPos3DFromGameObjectsList_2D_preAllocated, points.Count, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex GetPositions3DFromTransformsArray_2D_preAllocated = UtilitiesDXXL_Bezier.GetPositions3DFromTransformsArray_2D; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform GetForwardControlPos3DFromTransformsArray_2D_preAllocated = UtilitiesDXXL_Bezier.GetForwardControlPos3DFromTransformsArray_2D; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform GetBackwardControlPos3DFromTransformsArray_2D_preAllocated = UtilitiesDXXL_Bezier.GetBackwardControlPos3DFromTransformsArray_2D; + /// 绘制2D贝塞尔样条曲线(使用 Transform 数组定义控制点)。 + public static void BezierSpline(Transform[] points, Color color = default(Color), DrawBasics.BezierPosInterpretation interpretationOfArray = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + UtilitiesDXXL_Bezier.BezierSpline(true, custom_zPos, points, GetPositions3DFromTransformsArray_2D_preAllocated, GetForwardControlPos3DFromTransformsArray_2D_preAllocated, GetBackwardControlPos3DFromTransformsArray_2D_preAllocated, points.Length, color, interpretationOfArray, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex> GetPositions3DFromTransformsList_2D_preAllocated = UtilitiesDXXL_Bezier.GetPositions3DFromTransformsList_2D; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform> GetForwardControlPos3DFromTransformsList_2D_preAllocated = UtilitiesDXXL_Bezier.GetForwardControlPos3DFromTransformsList_2D; + static UtilitiesDXXL_Bezier.FlexibleGetDirectionControlPosOfTransform> GetBackwardControlPos3DFromTransformsList_2D_preAllocated = UtilitiesDXXL_Bezier.GetBackwardControlPos3DFromTransformsList_2D; + /// 绘制2D贝塞尔样条曲线(使用 Transform 列表定义控制点)。 + public static void BezierSpline(List points, Color color = default(Color), DrawBasics.BezierPosInterpretation interpretationOfList = DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + UtilitiesDXXL_Bezier.BezierSpline>(true, custom_zPos, points, GetPositions3DFromTransformsList_2D_preAllocated, GetForwardControlPos3DFromTransformsList_2D_preAllocated, GetBackwardControlPos3DFromTransformsList_2D_preAllocated, points.Count, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex GetPositions3DFromVector2Array_2D_preAllocated = UtilitiesDXXL_Bezier.GetPositions3DFromVector2Array_2D; + /// 绘制2D贝塞尔样条曲线(使用 Vector2 数组定义控制点)。 + public static void BezierSpline(Vector2[] points, Color color = default(Color), DrawBasics.BezierPosInterpretation interpretationOfArray = DrawBasics.BezierPosInterpretation.start_control1_control2_endIsNextStart, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (interpretationOfArray == DrawBasics.BezierPosInterpretation.start_control1_control2_endIsNextStart || interpretationOfArray == DrawBasics.BezierPosInterpretation.start_control1_endIsNextStart) + { + UtilitiesDXXL_Bezier.BezierSpline(true, custom_zPos, points, GetPositions3DFromVector2Array_2D_preAllocated, null, null, points.Length, color, interpretationOfArray, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + else + { + Debug.LogError("The specified interpretationOfArray ('" + interpretationOfArray + "') is not supported for BezierSpline() function overloads that take 'Vector2'-collections. You may choose an overload that takes 'Transform'- or 'GameObject'-collections."); + } + } + + + static UtilitiesDXXL_Bezier.FlexibleGetPosAtIndex> GetPositions3DFromVector2List_2D_preAllocated = UtilitiesDXXL_Bezier.GetPositions3DFromVector2List_2D; + /// 绘制2D贝塞尔样条曲线(使用 Vector2 列表定义控制点)。 + public static void BezierSpline(List points, Color color = default(Color), DrawBasics.BezierPosInterpretation interpretationOfList = DrawBasics.BezierPosInterpretation.start_control1_control2_endIsNextStart, string text = null, float width = 0.0f, bool closeGapFromEndToStart = false, int straightSubDivisionsPerSegment = 50, float custom_zPos = float.PositiveInfinity, float textSize = 0.1f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (interpretationOfList == DrawBasics.BezierPosInterpretation.start_control1_control2_endIsNextStart || interpretationOfList == DrawBasics.BezierPosInterpretation.start_control1_endIsNextStart) + { + UtilitiesDXXL_Bezier.BezierSpline>(true, custom_zPos, points, GetPositions3DFromVector2List_2D_preAllocated, null, null, points.Count, color, interpretationOfList, text, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + else + { + Debug.LogError("The specified interpretationOfList ('" + interpretationOfList + "') is not supported for BezierSpline() function overloads that take 'Vector2'-collections. You may choose an overload that takes 'Transform'- or 'GameObject'-collections."); + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/DrawBasics2D.cs.meta b/Runtime/DrawDebugLibrary/DrawBasics2D.cs.meta new file mode 100644 index 0000000..bbb1441 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawBasics2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d236fb61fe8c99d42a855a5b130b7aaa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawCharts.cs b/Runtime/DrawDebugLibrary/DrawCharts.cs new file mode 100644 index 0000000..a52809c --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawCharts.cs @@ -0,0 +1,303 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class DrawCharts + { + + public static bool chartInspectorComponentsAutomaticallyProceedOneFrameStepOnPauseStarts_toPreventFrozenOverlayDraw = true; + + public static ChartDrawing premadeChart0; + public static ChartDrawing premadeChart1; + public static ChartDrawing premadeChart2; + public static ChartDrawing premadeChart3; + public static ChartDrawing premadeChart4; + public static ChartDrawing premadeChart5; + public static ChartDrawing premadeChart6; + public static ChartDrawing premadeChart7; + public static ChartDrawing premadeChart8; + public static ChartDrawing premadeChart9; + + public static PieChartDrawing premadePieChart0; + public static PieChartDrawing premadePieChart1; + public static PieChartDrawing premadePieChart2; + public static PieChartDrawing premadePieChart3; + public static PieChartDrawing premadePieChart4; + public static PieChartDrawing premadePieChart5; + public static PieChartDrawing premadePieChart6; + public static PieChartDrawing premadePieChart7; + public static PieChartDrawing premadePieChart8; + public static PieChartDrawing premadePieChart9; + + public static Vector3 positionOfPremadeCharts = Vector3.zero; + public static int premadeChartThatIsRotationPivot = 0; + + const float default_widthOfPremadeCharts = 1.7f; + const float default_heightOfPremadeCharts = 0.8f; + const float default_diameterOfPremadePieCharts = 0.65f; + static float factor_fromLineChartWidth_toPieChartDiameter_soThatTheyAppearWithApproxTheSameWidth = 0.382353f; + static float current_widthOfPremadeCharts = default_widthOfPremadeCharts; + static float current_heightOfPremadeCharts = default_heightOfPremadeCharts; + + static float xOffsetBetweenPremadeCharts_caseOf_onlyPieCharts = 1.06f; + // static float xOffsetBetweenPremadeCharts_caseOf_noNeedFor_pointOfInterestTextBoxes = 1.35f; + static float xOffsetBetweenPremadeCharts_caseOf_noNeedFor_pointOfInterestTextBoxes = 1.25f; + static float xOffsetBetweenPremadeCharts_caseOf_needs_pointOfInterestTextBoxes_onOneSide = 1.85f; + static float xOffsetBetweenPremadeCharts_caseOf_needs_pointOfInterestTextBoxes_onBothSides = 2.44f; + static float current_horizontalDistance_fromChartToChart_relativeToChartWidth = xOffsetBetweenPremadeCharts_caseOf_noNeedFor_pointOfInterestTextBoxes; + static float used_xOffsetBetweenPremadeCharts = default_widthOfPremadeCharts * current_horizontalDistance_fromChartToChart_relativeToChartWidth; + + static DrawCharts() + { + premadeChart0 = new ChartDrawing("premade chart #0"); + premadeChart1 = new ChartDrawing("premade chart #1"); + premadeChart2 = new ChartDrawing("premade chart #2"); + premadeChart3 = new ChartDrawing("premade chart #3"); + premadeChart4 = new ChartDrawing("premade chart #4"); + premadeChart5 = new ChartDrawing("premade chart #5"); + premadeChart6 = new ChartDrawing("premade chart #6"); + premadeChart7 = new ChartDrawing("premade chart #7"); + premadeChart8 = new ChartDrawing("premade chart #8"); + premadeChart9 = new ChartDrawing("premade chart #9"); + + premadePieChart0 = new PieChartDrawing("pie chart #0"); + premadePieChart1 = new PieChartDrawing("pie chart #1"); + premadePieChart2 = new PieChartDrawing("pie chart #2"); + premadePieChart3 = new PieChartDrawing("pie chart #3"); + premadePieChart4 = new PieChartDrawing("pie chart #4"); + premadePieChart5 = new PieChartDrawing("pie chart #5"); + premadePieChart6 = new PieChartDrawing("pie chart #6"); + premadePieChart7 = new PieChartDrawing("pie chart #7"); + premadePieChart8 = new PieChartDrawing("pie chart #8"); + premadePieChart9 = new PieChartDrawing("pie chart #9"); + + RevertPremadeChartsToAutomaticPositionLayout(); + SetWidth_forAllPremadeLineCharts(); + SetHeight_forAllPremadeLineCharts(); + SetSizeOfPieCircleDiameter_forAllPremadePieCharts(); + } + + public static Vector3 GetAutoLayoutedPositionOfPremadeLineChart(int indexNumberOfPremadeChart) + { + //The charts are arranged horizontally, because they potentially grow in their y-extent due to the tower of PointOfInterest-TextBoxes. Otherwise the could potentially intersect each other: + + float horizontalOffsetDistance; + Vector3 offsetVectorBetweenCharts_normalized; + + if (premadeChartThatIsRotationPivot < 0) + { + horizontalOffsetDistance = used_xOffsetBetweenPremadeCharts * indexNumberOfPremadeChart; + offsetVectorBetweenCharts_normalized = Vector3.right; + } + else + { + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, positionOfPremadeCharts, Vector3.zero, null); + horizontalOffsetDistance = used_xOffsetBetweenPremadeCharts * (indexNumberOfPremadeChart - premadeChartThatIsRotationPivot); + offsetVectorBetweenCharts_normalized = observerCamRight_normalized; + } + + return (positionOfPremadeCharts + offsetVectorBetweenCharts_normalized * horizontalOffsetDistance); + } + + public static Vector3 GetAutoLayoutedPositionOfPremadePieChart(PieChartDrawing requestingPieChartDrawing) + { + float yOffset; //-> shifting the pie charts to below of the line charts. The line charts potentially grow in size towards the top (due to the tower of PointOfInterest-textBoxes), while the pie charts potentially grow in size towards the downside, due to the segment name list, the grows downward. This way the line charts and pie charts don't intersect each other. + if (UtilitiesDXXL_Math.ApproximatelyZero(requestingPieChartDrawing.mostRecent_vertDistance_fromCircleCenter_toUpperBounderySquare)) + { + yOffset = -2.2f * requestingPieChartDrawing.Size_ofPieCircleDiameter; + } + else + { + yOffset = (-requestingPieChartDrawing.mostRecent_vertDistance_fromCircleCenter_toUpperBounderySquare - requestingPieChartDrawing.Size_ofPieCircleDiameter); + } + + float xPos_offset = requestingPieChartDrawing.Size_ofPieCircleDiameter;//-> shift offset, so the pie charts are vertically aligned with with the line charts. This works only correctly, if "pieChart.RelSize_ofSegmentsNameTexts" hasn't been altered. + float horizontalOffsetDistance; + Vector3 offsetVectorBetweenCharts_normalized; + + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, positionOfPremadeCharts, Vector3.zero, null); + if (premadeChartThatIsRotationPivot < 0) + { + horizontalOffsetDistance = used_xOffsetBetweenPremadeCharts * requestingPieChartDrawing.internal_indexNumberOfPremadeChart + xPos_offset; + offsetVectorBetweenCharts_normalized = Vector3.right; + } + else + { + horizontalOffsetDistance = used_xOffsetBetweenPremadeCharts * (requestingPieChartDrawing.internal_indexNumberOfPremadeChart - premadeChartThatIsRotationPivot) + xPos_offset; + offsetVectorBetweenCharts_normalized = observerCamRight_normalized; + } + + return (positionOfPremadeCharts + offsetVectorBetweenCharts_normalized * horizontalOffsetDistance + observerCamUp_normalized * yOffset); + } + + public static void SetDistanceBetweenNeighboringPremadeChartsTo_customDistance(float horizontalDistance_fromChartToChart_relativeToChartWidth) + { + current_horizontalDistance_fromChartToChart_relativeToChartWidth = horizontalDistance_fromChartToChart_relativeToChartWidth; + Apply_current_horizontalDistance_fromChartToChart_relativeToChartWidth(); + } + + public static void SetDistanceBetweenNeighboringPremadeChartsToFitCaseOf_noNeedForPointOfInterestTextBoxes() + { + current_horizontalDistance_fromChartToChart_relativeToChartWidth = xOffsetBetweenPremadeCharts_caseOf_noNeedFor_pointOfInterestTextBoxes; + Apply_current_horizontalDistance_fromChartToChart_relativeToChartWidth(); + } + + public static void SetDistanceBetweenNeighboringPremadeChartsToFitCaseOf_needsPointOfInterestTextBoxesOnOneSide() + { + current_horizontalDistance_fromChartToChart_relativeToChartWidth = xOffsetBetweenPremadeCharts_caseOf_needs_pointOfInterestTextBoxes_onOneSide; + Apply_current_horizontalDistance_fromChartToChart_relativeToChartWidth(); + } + + public static void SetDistanceBetweenNeighboringPremadeChartsToFitCaseOf_needsPointOfInterestTextBoxesOnBothSides() + { + current_horizontalDistance_fromChartToChart_relativeToChartWidth = xOffsetBetweenPremadeCharts_caseOf_needs_pointOfInterestTextBoxes_onBothSides; + Apply_current_horizontalDistance_fromChartToChart_relativeToChartWidth(); + } + + public static void SetDistanceBetweenNeighboringPremadeChartsToFitCaseOf_onlyPieCharts() + { + current_horizontalDistance_fromChartToChart_relativeToChartWidth = xOffsetBetweenPremadeCharts_caseOf_onlyPieCharts; + Apply_current_horizontalDistance_fromChartToChart_relativeToChartWidth(); + } + + static void Apply_current_horizontalDistance_fromChartToChart_relativeToChartWidth() + { + used_xOffsetBetweenPremadeCharts = current_widthOfPremadeCharts * current_horizontalDistance_fromChartToChart_relativeToChartWidth; + } + + public static void RevertPremadeChartsToAutomaticPositionLayout(bool revert_premadeChart0 = true, bool revert_premadeChart1 = true, bool revert_premadeChart2 = true, bool revert_premadeChart3 = true, bool revert_premadeChart4 = true, bool revert_premadeChart5 = true, bool revert_premadeChart6 = true, bool revert_premadeChart7 = true, bool revert_premadeChart8 = true, bool revert_premadeChart9 = true, bool revert_premadePieChart0 = true, bool revert_premadePieChart1 = true, bool revert_premadePieChart2 = true, bool revert_premadePieChart3 = true, bool revert_premadePieChart4 = true, bool revert_premadePieChart5 = true, bool revert_premadePieChart6 = true, bool revert_premadePieChart7 = true, bool revert_premadePieChart8 = true, bool revert_premadePieChart9 = true) + { + RevertPremadeLineChartsToAutomaticPositionLayout(revert_premadeChart0, revert_premadeChart1, revert_premadeChart2, revert_premadeChart3, revert_premadeChart4, revert_premadeChart5, revert_premadeChart6, revert_premadeChart7, revert_premadeChart8, revert_premadeChart9); + RevertPremadePieChartsToAutomaticPositionLayout(revert_premadePieChart0, revert_premadePieChart1, revert_premadePieChart2, revert_premadePieChart3, revert_premadePieChart4, revert_premadePieChart5, revert_premadePieChart6, revert_premadePieChart7, revert_premadePieChart8, revert_premadePieChart9); + } + + public static void RevertPremadeLineChartsToAutomaticPositionLayout(bool revert_premadeChart0 = true, bool revert_premadeChart1 = true, bool revert_premadeChart2 = true, bool revert_premadeChart3 = true, bool revert_premadeChart4 = true, bool revert_premadeChart5 = true, bool revert_premadeChart6 = true, bool revert_premadeChart7 = true, bool revert_premadeChart8 = true, bool revert_premadeChart9 = true) + { + if (revert_premadeChart0) { premadeChart0.internal_indexNumberOfPremadeChart = 0; } + if (revert_premadeChart1) { premadeChart1.internal_indexNumberOfPremadeChart = 1; } + if (revert_premadeChart2) { premadeChart2.internal_indexNumberOfPremadeChart = 2; } + if (revert_premadeChart3) { premadeChart3.internal_indexNumberOfPremadeChart = 3; } + if (revert_premadeChart4) { premadeChart4.internal_indexNumberOfPremadeChart = 4; } + if (revert_premadeChart5) { premadeChart5.internal_indexNumberOfPremadeChart = 5; } + if (revert_premadeChart6) { premadeChart6.internal_indexNumberOfPremadeChart = 6; } + if (revert_premadeChart7) { premadeChart7.internal_indexNumberOfPremadeChart = 7; } + if (revert_premadeChart8) { premadeChart8.internal_indexNumberOfPremadeChart = 8; } + if (revert_premadeChart9) { premadeChart9.internal_indexNumberOfPremadeChart = 9; } + } + + public static void RevertPremadePieChartsToAutomaticPositionLayout(bool revert_premadePieChart0 = true, bool revert_premadePieChart1 = true, bool revert_premadePieChart2 = true, bool revert_premadePieChart3 = true, bool revert_premadePieChart4 = true, bool revert_premadePieChart5 = true, bool revert_premadePieChart6 = true, bool revert_premadePieChart7 = true, bool revert_premadePieChart8 = true, bool revert_premadePieChart9 = true) + { + if (revert_premadePieChart0) { premadePieChart0.internal_indexNumberOfPremadeChart = 0; } + if (revert_premadePieChart1) { premadePieChart1.internal_indexNumberOfPremadeChart = 1; } + if (revert_premadePieChart2) { premadePieChart2.internal_indexNumberOfPremadeChart = 2; } + if (revert_premadePieChart3) { premadePieChart3.internal_indexNumberOfPremadeChart = 3; } + if (revert_premadePieChart4) { premadePieChart4.internal_indexNumberOfPremadeChart = 4; } + if (revert_premadePieChart5) { premadePieChart5.internal_indexNumberOfPremadeChart = 5; } + if (revert_premadePieChart6) { premadePieChart6.internal_indexNumberOfPremadeChart = 6; } + if (revert_premadePieChart7) { premadePieChart7.internal_indexNumberOfPremadeChart = 7; } + if (revert_premadePieChart8) { premadePieChart8.internal_indexNumberOfPremadeChart = 8; } + if (revert_premadePieChart9) { premadePieChart9.internal_indexNumberOfPremadeChart = 9; } + } + + public static void SetSize_forAllPremadeCharts(float newWidthPerChart) + { + SetWidth_forAllPremadeLineCharts(newWidthPerChart, true); + SetSizeOfPieCircleDiameter_forAllPremadePieCharts(newWidthPerChart * factor_fromLineChartWidth_toPieChartDiameter_soThatTheyAppearWithApproxTheSameWidth); + } + + public static void SetWidth_forAllPremadeLineCharts(float newWidth = default_widthOfPremadeCharts, bool scaleHeightAsWell = true) + { + float scaleFactor_comparedToBefore = newWidth / current_widthOfPremadeCharts; + current_widthOfPremadeCharts = newWidth; + Apply_current_horizontalDistance_fromChartToChart_relativeToChartWidth(); + + if (premadeChart0.internal_indexNumberOfPremadeChart != (-1)) { premadeChart0.Width_inWorldSpace = newWidth; } + if (premadeChart1.internal_indexNumberOfPremadeChart != (-1)) { premadeChart1.Width_inWorldSpace = newWidth; } + if (premadeChart2.internal_indexNumberOfPremadeChart != (-1)) { premadeChart2.Width_inWorldSpace = newWidth; } + if (premadeChart3.internal_indexNumberOfPremadeChart != (-1)) { premadeChart3.Width_inWorldSpace = newWidth; } + if (premadeChart4.internal_indexNumberOfPremadeChart != (-1)) { premadeChart4.Width_inWorldSpace = newWidth; } + if (premadeChart5.internal_indexNumberOfPremadeChart != (-1)) { premadeChart5.Width_inWorldSpace = newWidth; } + if (premadeChart6.internal_indexNumberOfPremadeChart != (-1)) { premadeChart6.Width_inWorldSpace = newWidth; } + if (premadeChart7.internal_indexNumberOfPremadeChart != (-1)) { premadeChart7.Width_inWorldSpace = newWidth; } + if (premadeChart8.internal_indexNumberOfPremadeChart != (-1)) { premadeChart8.Width_inWorldSpace = newWidth; } + if (premadeChart9.internal_indexNumberOfPremadeChart != (-1)) { premadeChart9.Width_inWorldSpace = newWidth; } + + if (scaleHeightAsWell) + { + SetHeight_forAllPremadeLineCharts(current_heightOfPremadeCharts * scaleFactor_comparedToBefore, false); + } + } + + public static void SetHeight_forAllPremadeLineCharts(float newHeight = default_heightOfPremadeCharts, bool scaleWidthAsWell = true) + { + float scaleFactor_comparedToBefore = newHeight / current_heightOfPremadeCharts; + current_heightOfPremadeCharts = newHeight; + + if (premadeChart0.internal_indexNumberOfPremadeChart != (-1)) { premadeChart0.Height_inWorldSpace = newHeight; } + if (premadeChart1.internal_indexNumberOfPremadeChart != (-1)) { premadeChart1.Height_inWorldSpace = newHeight; } + if (premadeChart2.internal_indexNumberOfPremadeChart != (-1)) { premadeChart2.Height_inWorldSpace = newHeight; } + if (premadeChart3.internal_indexNumberOfPremadeChart != (-1)) { premadeChart3.Height_inWorldSpace = newHeight; } + if (premadeChart4.internal_indexNumberOfPremadeChart != (-1)) { premadeChart4.Height_inWorldSpace = newHeight; } + if (premadeChart5.internal_indexNumberOfPremadeChart != (-1)) { premadeChart5.Height_inWorldSpace = newHeight; } + if (premadeChart6.internal_indexNumberOfPremadeChart != (-1)) { premadeChart6.Height_inWorldSpace = newHeight; } + if (premadeChart7.internal_indexNumberOfPremadeChart != (-1)) { premadeChart7.Height_inWorldSpace = newHeight; } + if (premadeChart8.internal_indexNumberOfPremadeChart != (-1)) { premadeChart8.Height_inWorldSpace = newHeight; } + if (premadeChart9.internal_indexNumberOfPremadeChart != (-1)) { premadeChart9.Height_inWorldSpace = newHeight; } + + if (scaleWidthAsWell) + { + SetWidth_forAllPremadeLineCharts(current_widthOfPremadeCharts * scaleFactor_comparedToBefore, false); + } + } + + public static void SetSizeOfPieCircleDiameter_forAllPremadePieCharts(float newDiameter = default_diameterOfPremadePieCharts) + { + if (premadePieChart0.internal_indexNumberOfPremadeChart != (-1)) { premadePieChart0.Size_ofPieCircleDiameter = newDiameter; } + if (premadePieChart1.internal_indexNumberOfPremadeChart != (-1)) { premadePieChart1.Size_ofPieCircleDiameter = newDiameter; } + if (premadePieChart2.internal_indexNumberOfPremadeChart != (-1)) { premadePieChart2.Size_ofPieCircleDiameter = newDiameter; } + if (premadePieChart3.internal_indexNumberOfPremadeChart != (-1)) { premadePieChart3.Size_ofPieCircleDiameter = newDiameter; } + if (premadePieChart4.internal_indexNumberOfPremadeChart != (-1)) { premadePieChart4.Size_ofPieCircleDiameter = newDiameter; } + if (premadePieChart5.internal_indexNumberOfPremadeChart != (-1)) { premadePieChart5.Size_ofPieCircleDiameter = newDiameter; } + if (premadePieChart6.internal_indexNumberOfPremadeChart != (-1)) { premadePieChart6.Size_ofPieCircleDiameter = newDiameter; } + if (premadePieChart7.internal_indexNumberOfPremadeChart != (-1)) { premadePieChart7.Size_ofPieCircleDiameter = newDiameter; } + if (premadePieChart8.internal_indexNumberOfPremadeChart != (-1)) { premadePieChart8.Size_ofPieCircleDiameter = newDiameter; } + if (premadePieChart9.internal_indexNumberOfPremadeChart != (-1)) { premadePieChart9.Size_ofPieCircleDiameter = newDiameter; } + } + + public static void ClearAllPremadeCharts(bool clear_premadeChart0 = true, bool clear_premadeChart1 = true, bool clear_premadeChart2 = true, bool clear_premadeChart3 = true, bool clear_premadeChart4 = true, bool clear_premadeChart5 = true, bool clear_premadeChart6 = true, bool clear_premadeChart7 = true, bool clear_premadeChart8 = true, bool clear_premadeChart9 = true, bool clear_premadePieChart0 = true, bool clear_premadePieChart1 = true, bool clear_premadePieChart2 = true, bool clear_premadePieChart3 = true, bool clear_premadePieChart4 = true, bool clear_premadePieChart5 = true, bool clear_premadePieChart6 = true, bool clear_premadePieChart7 = true, bool clear_premadePieChart8 = true, bool clear_premadePieChart9 = true) + { + ClearAllPremadeLineCharts(clear_premadeChart0, clear_premadeChart1, clear_premadeChart2, clear_premadeChart3, clear_premadeChart4, clear_premadeChart5, clear_premadeChart6, clear_premadeChart7, clear_premadeChart8, clear_premadeChart9); + ClearAllPremadePieCharts(clear_premadePieChart0, clear_premadePieChart1, clear_premadePieChart2, clear_premadePieChart3, clear_premadePieChart4, clear_premadePieChart5, clear_premadePieChart6, clear_premadePieChart7, clear_premadePieChart8, clear_premadePieChart9); + } + + public static void ClearAllPremadeLineCharts(bool clear_premadeChart0 = true, bool clear_premadeChart1 = true, bool clear_premadeChart2 = true, bool clear_premadeChart3 = true, bool clear_premadeChart4 = true, bool clear_premadeChart5 = true, bool clear_premadeChart6 = true, bool clear_premadeChart7 = true, bool clear_premadeChart8 = true, bool clear_premadeChart9 = true) + { + if (clear_premadeChart0) { premadeChart0.Clear(); } + if (clear_premadeChart1) { premadeChart1.Clear(); } + if (clear_premadeChart2) { premadeChart2.Clear(); } + if (clear_premadeChart3) { premadeChart3.Clear(); } + if (clear_premadeChart4) { premadeChart4.Clear(); } + if (clear_premadeChart5) { premadeChart5.Clear(); } + if (clear_premadeChart6) { premadeChart6.Clear(); } + if (clear_premadeChart7) { premadeChart7.Clear(); } + if (clear_premadeChart8) { premadeChart8.Clear(); } + if (clear_premadeChart9) { premadeChart9.Clear(); } + } + + public static void ClearAllPremadePieCharts(bool clear_premadePieChart0 = true, bool clear_premadePieChart1 = true, bool clear_premadePieChart2 = true, bool clear_premadePieChart3 = true, bool clear_premadePieChart4 = true, bool clear_premadePieChart5 = true, bool clear_premadePieChart6 = true, bool clear_premadePieChart7 = true, bool clear_premadePieChart8 = true, bool clear_premadePieChart9 = true) + { + if (clear_premadePieChart0) { premadePieChart0.Clear(); } + if (clear_premadePieChart1) { premadePieChart1.Clear(); } + if (clear_premadePieChart2) { premadePieChart2.Clear(); } + if (clear_premadePieChart3) { premadePieChart3.Clear(); } + if (clear_premadePieChart4) { premadePieChart4.Clear(); } + if (clear_premadePieChart5) { premadePieChart5.Clear(); } + if (clear_premadePieChart6) { premadePieChart6.Clear(); } + if (clear_premadePieChart7) { premadePieChart7.Clear(); } + if (clear_premadePieChart8) { premadePieChart8.Clear(); } + if (clear_premadePieChart9) { premadePieChart9.Clear(); } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/DrawCharts.cs.meta b/Runtime/DrawDebugLibrary/DrawCharts.cs.meta new file mode 100644 index 0000000..ac37034 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawCharts.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b95f03b066d204641be8a6bd70f033ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawEngineBasics.cs b/Runtime/DrawDebugLibrary/DrawEngineBasics.cs new file mode 100644 index 0000000..bc5425f --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawEngineBasics.cs @@ -0,0 +1,1481 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class DrawEngineBasics + { + public static Color colorOfVector1_forDotProduct = UtilitiesDXXL_Colors.green_boolTrue; //This only affects the dot product drawings. It specifies the color of "vector1_lhs". + public static Color colorOfVector2_forDotProduct = UtilitiesDXXL_Colors.red_boolFalse; //This only affects the dot product drawings. It specifies the color of "vector2_rhs". + public static Color colorOfAngle_forDotProduct = UtilitiesDXXL_Colors.orange_lineThresholdMiddleDistance; //This only affects the dot product drawings. It specifies the color of the displayed angle when using "DotProduct". + public static Color colorOfResult_forDotProduct = Color.white; //This only affects the dot product drawings. It specifies the color of the displayed result text when using "DotProduct". + + public static Color colorOfVector1_forCrossProduct = UtilitiesDXXL_Colors.green_boolTrue; //This only affects the cross product drawings. It specifies the color of "vector1_lhs_leftThumb". + public static Color colorOfVector2_forCrossProduct = UtilitiesDXXL_Colors.red_boolFalse; //This only affects the cross product drawings. It specifies the color of "vector2_rhs_leftIndexFinger". + public static Color colorOfAngle_forCrossProduct = UtilitiesDXXL_Colors.orange_lineThresholdMiddleDistance; //This only affects the cross product drawings. It specifies the color of the displayed angle when using "CrossProduct". + public static Color colorOfResultVector_forCrossProduct = UtilitiesDXXL_Colors.darkBlue; //This only affects the cross product drawings. It specifies the color of the displayed result vector when using "CrossProduct". + public static Color colorOfResultText_forCrossProduct = Color.white; //This only affects the cross product drawings. It specifies the color of the displayed result text when using "CrossProduct". + public static Color colorOfResultPlane_forCrossProduct = UtilitiesDXXL_Colors.violet; //This only affects the cross product drawings. It specifies the color of the displayed result plane when using "CrossProduct". + + public static Color overwriteColorForFrustumsHighlightedPlane = default(Color); //The default color for the highlighted plane of camera frustums is the color that has been specfied for the frustum itself, but with an adjusted brightness. You can overwrite this behaviour by setting this field. + public static float distanceOfFrustumsHighlightedPlane = 0.0f; + public static bool drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane = true; + + public static bool hide_positionAroundWhichToDraw_forGrids = false; + public static bool hide_distanceDisplay_forGrids = UtilitiesDXXL_Grid.default_hide_distanceDisplay_forGrids; + public static float offsetForDistanceDisplays_inGrids = UtilitiesDXXL_Grid.default_offsetForDistanceDisplays_inGrids; + public static float offsetForCoordinateTextDisplays_inGrids = UtilitiesDXXL_Grid.default_offsetForCoordinateTextDisplays_inGrids; + public static float coveredGridUnits_rel_forGridPlanes = UtilitiesDXXL_Grid.default_coveredGridUnits_rel_forGridPlanes; + + private static float sizeScalingForCoordinateTexts_inGrids = UtilitiesDXXL_Grid.default_sizeScalingForCoordinateTexts_inGrids; + public static float SizeScalingForCoordinateTexts_inGrids + { + get { return sizeScalingForCoordinateTexts_inGrids; } + set + { + if (value < UtilitiesDXXL_Grid.min_sizeScalingForCoordinateTexts_inGrids) + { + Debug.Log("Cannot set 'DrawEngineBasics.SizeScalingForCoordinateTexts_inGrids' to a smaller value than " + UtilitiesDXXL_Grid.min_sizeScalingForCoordinateTexts_inGrids); + sizeScalingForCoordinateTexts_inGrids = UtilitiesDXXL_Grid.min_sizeScalingForCoordinateTexts_inGrids; + } + else + { + sizeScalingForCoordinateTexts_inGrids = value; + } + } + } + + public static bool skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes = false; + public static bool skipLocalPrefix_inCoordinateTextsOnGridAxes = false; + + public static void Vector(Vector3 vectorStartPos, Vector3 vectorEndPos, Color color = default(Color), float lineWidth = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + VectorFrom(vectorStartPos, vectorEndPos - vectorStartPos, color, lineWidth, text, durationInSec, hiddenByNearerObjects); + } + + public static void VectorFrom(Vector3 vectorStartPos, Vector3 vector, Color color = default(Color), float lineWidth = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_EngineBasics.VectorFrom_local(Vector3.zero, Vector3.one, Quaternion.identity, vectorStartPos, vector, color, lineWidth, text, durationInSec, hiddenByNearerObjects, false); + } + + public static void VectorTo(Vector3 vector, Vector3 vectorEndPos, Color color = default(Color), float lineWidth = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector, "vector")) { return; } + VectorFrom(vectorEndPos - vector, vector, color, lineWidth, text, durationInSec, hiddenByNearerObjects); + } + + public static void Position(GameObject gameObject, Color color = default(Color), float lineWidth = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + VectorFrom(Vector3.zero, gameObject.transform.position, color, lineWidth, text, durationInSec, hiddenByNearerObjects); + } + + public static void Position(Transform transform, Color color = default(Color), float lineWidth = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + VectorFrom(Vector3.zero, transform.position, color, lineWidth, text, durationInSec, hiddenByNearerObjects); + } + + public static void Position(Vector3 position, Color color = default(Color), float lineWidth = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + VectorFrom(Vector3.zero, position, color, lineWidth, text, durationInSec, hiddenByNearerObjects); + } + + public static void Vector_local(Transform parentTransform_thatDefinesTheLocalSpace, Vector3 vectorStartPos, Vector3 vectorEndPos, Color color = default(Color), float lineWidth_inGlobalUnits = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + VectorFrom_local(parentTransform_thatDefinesTheLocalSpace, vectorStartPos, vectorEndPos - vectorStartPos, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + } + + public static void VectorFrom_local(Transform parentTransform_thatDefinesTheLocalSpace, Vector3 vectorStartPos, Vector3 vector, Color color = default(Color), float lineWidth_inGlobalUnits = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + if (parentTransform_thatDefinesTheLocalSpace == null) + { + text = "[ parent transform that defines the local space is 'null'
-> fallback to global space]
" + text; + UtilitiesDXXL_EngineBasics.VectorFrom_local(Vector3.zero, Vector3.one, Quaternion.identity, vectorStartPos, vector, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects, false); + } + else + { + bool aParentHasANonUniformScale = UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(parentTransform_thatDefinesTheLocalSpace); + if (aParentHasANonUniformScale) + { + text = "[ A parent transform that defines the local space has a non-uniform scale
-> possibly weird results]
" + text; + } + UtilitiesDXXL_EngineBasics.VectorFrom_local(parentTransform_thatDefinesTheLocalSpace.position, parentTransform_thatDefinesTheLocalSpace.lossyScale, parentTransform_thatDefinesTheLocalSpace.rotation, vectorStartPos, vector, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects, true); + } + } + + public static void VectorTo_local(Transform parentTransform_thatDefinesTheLocalSpace, Vector3 vector, Vector3 vectorEndPos, Color color = default(Color), float lineWidth_inGlobalUnits = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector, "vector")) { return; } + VectorFrom_local(parentTransform_thatDefinesTheLocalSpace, vectorEndPos - vector, vector, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + } + + public static void Position_local(GameObject gameObject_insideLocalSpace, Color color = default(Color), float lineWidth_inGlobalUnits = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject_insideLocalSpace, "gameObject_insideLocalSpace")) { return; } + Position_local(gameObject_insideLocalSpace.transform, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + } + + public static void Position_local(Transform transform_insideLocalSpace, Color color = default(Color), float lineWidth_inGlobalUnits = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform_insideLocalSpace, "transform_insideLocalSpace")) { return; } + VectorFrom_local(transform_insideLocalSpace.parent, Vector3.zero, transform_insideLocalSpace.localPosition, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + } + + public static void Position_local(Transform parentTransform_thatDefinesTheLocalSpace, Vector3 positionToDraw, Color color = default(Color), float lineWidth_inGlobalUnits = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + VectorFrom_local(parentTransform_thatDefinesTheLocalSpace, Vector3.zero, positionToDraw, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + } + + public static void Scale(GameObject gameObject, float lineWidth = 0.0035f, string text = null, bool drawXDim = true, bool drawYDim = true, bool drawZDim = true, float relSizeOfPlanes = 0.5f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject, "gameObject")) { return; } + Scale(gameObject.transform, lineWidth, text, drawXDim, drawYDim, drawZDim, relSizeOfPlanes, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void Scale(Transform transform, float lineWidth = 0.0035f, string text = null, bool drawXDim = true, bool drawYDim = true, bool drawZDim = true, float relSizeOfPlanes = 0.5f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform, "transform")) { return; } + + if (transform.parent != null) + { + text = "[ Try drawing 'Scale', but the transform has a parent
-> fallback to 'LocalScale', but the displayed length units fit global space]
" + text; + } + Scale(transform.position, transform.lossyScale, lineWidth, text, transform.rotation, drawXDim, drawYDim, drawZDim, relSizeOfPlanes, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void Scale(Vector3 centerPos, Vector3 scale, float lineWidth = 0.0035f, string text = null, Quaternion rotation = default(Quaternion), bool drawXDim = true, bool drawYDim = true, bool drawZDim = true, float relSizeOfPlanes = 0.5f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_EngineBasics.LocalScale(centerPos, scale, null, rotation, lineWidth, text, drawXDim, drawYDim, drawZDim, relSizeOfPlanes, overwriteColor, durationInSec, hiddenByNearerObjects, true); + } + + public static void LocalScale(GameObject gameObject_insideLocalSpace, float lineWidth_inGlobalUnits = 0.0035f, string text = null, bool drawXDim = true, bool drawYDim = true, bool drawZDim = true, float relSizeOfPlanes = 0.5f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject_insideLocalSpace, "gameObject_insideLocalSpace")) { return; } + LocalScale(gameObject_insideLocalSpace.transform, lineWidth_inGlobalUnits, text, drawXDim, drawYDim, drawZDim, relSizeOfPlanes, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void LocalScale(Transform transform_insideLocalSpace, float lineWidth_inGlobalUnits = 0.0035f, string text = null, bool drawXDim = true, bool drawYDim = true, bool drawZDim = true, float relSizeOfPlanes = 0.5f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform_insideLocalSpace, "transform_insideLocalSpace")) { return; } + LocalScale(transform_insideLocalSpace.localPosition, transform_insideLocalSpace.localScale, transform_insideLocalSpace.parent, transform_insideLocalSpace.localRotation, lineWidth_inGlobalUnits, text, drawXDim, drawYDim, drawZDim, relSizeOfPlanes, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void LocalScale(Vector3 localPosition, Vector3 localScale, Transform parentTransform, Quaternion localRotation = default(Quaternion), float lineWidth_inGlobalUnits = 0.0035f, string text = null, bool drawXDim = true, bool drawYDim = true, bool drawZDim = true, float relSizeOfPlanes = 0.5f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransform == null) + { + text = "[ parent transform that defines the local space is 'null'
-> fallback to global scale]
" + text; + UtilitiesDXXL_EngineBasics.LocalScale(localPosition, localScale, parentTransform, localRotation, lineWidth_inGlobalUnits, text, drawXDim, drawYDim, drawZDim, relSizeOfPlanes, overwriteColor, durationInSec, hiddenByNearerObjects, true); + } + else + { + UtilitiesDXXL_EngineBasics.LocalScale(localPosition, localScale, parentTransform, localRotation, lineWidth_inGlobalUnits, text, drawXDim, drawYDim, drawZDim, relSizeOfPlanes, overwriteColor, durationInSec, hiddenByNearerObjects, false); + } + } + + public static void QuaternionRotation(GameObject gameObject, Vector3 customVectorToRotate = default(Vector3), float length_ofUpAndForwardVectors = 1.0f, Color color_ofTurnAxis = default(Color), float lineWidth = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject, "gameObject")) { return; } + QuaternionRotation(gameObject.transform, customVectorToRotate, length_ofUpAndForwardVectors, color_ofTurnAxis, lineWidth, text, durationInSec, hiddenByNearerObjects); + } + + public static void QuaternionRotation(Transform transform, Vector3 customVectorToRotate = default(Vector3), float length_ofUpAndForwardVectors = 1.0f, Color color_ofTurnAxis = default(Color), float lineWidth = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform, "transform")) { return; } + QuaternionRotation(transform.rotation, transform.position, customVectorToRotate, length_ofUpAndForwardVectors, color_ofTurnAxis, lineWidth, text, durationInSec, hiddenByNearerObjects); + } + + public static void QuaternionRotation(Quaternion quaternion, Vector3 posWhereToDraw = default(Vector3), Vector3 customVectorToRotate = default(Vector3), float length_ofUpAndForwardVectors = 1.0f, Color color_ofTurnAxis = default(Color), float lineWidth = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Quaternion.QuaternionRotation_local(quaternion, posWhereToDraw, color_ofTurnAxis, lineWidth, text, length_ofUpAndForwardVectors, customVectorToRotate, durationInSec, hiddenByNearerObjects, false, null); + } + + public static void QuaternionRotation_local(GameObject gameObject_insideLocalSpace, Vector3 customVectorToRotate_local = default(Vector3), float length_ofUpAndForwardVectors_local = 1.0f, Color color_ofTurnAxis = default(Color), float lineWidth_inGlobalUnits = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject_insideLocalSpace, "gameObject_insideLocalSpace")) { return; } + QuaternionRotation_local(gameObject_insideLocalSpace.transform, customVectorToRotate_local, length_ofUpAndForwardVectors_local, color_ofTurnAxis, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + } + + public static void QuaternionRotation_local(Transform transform_insideLocalSpace, Vector3 customVectorToRotate_local = default(Vector3), float length_ofUpAndForwardVectors_local = 1.0f, Color color_ofTurnAxis = default(Color), float lineWidth_inGlobalUnits = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform_insideLocalSpace, "transform_insideLocalSpace")) { return; } + + if (transform_insideLocalSpace.parent == null) + { + text = "[ parent transform that defines
the local space is 'null'
-> fallback to global rotation]
" + text; + UtilitiesDXXL_Quaternion.QuaternionRotation_local(transform_insideLocalSpace.localRotation, transform_insideLocalSpace.position, color_ofTurnAxis, lineWidth_inGlobalUnits, text, length_ofUpAndForwardVectors_local, customVectorToRotate_local, durationInSec, hiddenByNearerObjects, false, null); + } + else + { + bool aParentHasANonUniformScale = UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(transform_insideLocalSpace.parent); + if (aParentHasANonUniformScale) + { + text = "[ A parent transform that defines the
local space has a non-uniform scale
-> possibly weird results]
" + text; + } + UtilitiesDXXL_Quaternion.QuaternionRotation_local(transform_insideLocalSpace.localRotation, transform_insideLocalSpace.position, color_ofTurnAxis, lineWidth_inGlobalUnits, text, length_ofUpAndForwardVectors_local, customVectorToRotate_local, durationInSec, hiddenByNearerObjects, true, transform_insideLocalSpace.parent); + } + } + + public static void QuaternionRotation_local(Transform parentTransform_thatDefinesTheLocalSpace, Quaternion quaternionToDraw_local, Vector3 posWhereToDraw_global = default(Vector3), Vector3 customVectorToRotate_local = default(Vector3), float length_ofUpAndForwardVectors_local = 1.0f, Color color_ofTurnAxis = default(Color), float lineWidth_inGlobalUnits = 0.0f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + if (parentTransform_thatDefinesTheLocalSpace == null) + { + text = "[ parent transform that defines
the local space is 'null'
-> fallback to global rotation]
" + text; + UtilitiesDXXL_Quaternion.QuaternionRotation_local(quaternionToDraw_local, posWhereToDraw_global, color_ofTurnAxis, lineWidth_inGlobalUnits, text, length_ofUpAndForwardVectors_local, customVectorToRotate_local, durationInSec, hiddenByNearerObjects, false, null); + } + else + { + bool aParentHasANonUniformScale = UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(parentTransform_thatDefinesTheLocalSpace); + if (aParentHasANonUniformScale) + { + text = "[ A parent transform that defines the
local space has a non-uniform scale
-> possibly weird results]
" + text; + } + UtilitiesDXXL_Quaternion.QuaternionRotation_local(quaternionToDraw_local, posWhereToDraw_global, color_ofTurnAxis, lineWidth_inGlobalUnits, text, length_ofUpAndForwardVectors_local, customVectorToRotate_local, durationInSec, hiddenByNearerObjects, true, parentTransform_thatDefinesTheLocalSpace); + } + } + + public static void EulerRotation(GameObject gameObject, Vector3 customVectorToRotate = default(Vector3), float length_ofUpAndForwardVectors = 0.0f, float alpha_ofSquareSpannedByForwardAndUp = 0.0f, string text = null, bool useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay = false, float alpha_ofUnrotatedGimbalAxes = 0.06f, float gimbalSize = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject, "gameObject")) { return; } + EulerRotation(gameObject.transform, customVectorToRotate, length_ofUpAndForwardVectors, alpha_ofSquareSpannedByForwardAndUp, text, useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay, alpha_ofUnrotatedGimbalAxes, gimbalSize, durationInSec, hiddenByNearerObjects); + } + + public static void EulerRotation(Transform transform, Vector3 customVectorToRotate = default(Vector3), float length_ofUpAndForwardVectors = 0.0f, float alpha_ofSquareSpannedByForwardAndUp = 0.0f, string text = null, bool useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay = false, float alpha_ofUnrotatedGimbalAxes = 0.06f, float gimbalSize = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform, "transform")) { return; } + + if (useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay == false) + { + if (transform.parent != null) + { + text = "[ The transform has a parent, but the angle values from the inspector show the local rotation
-> fallback to values from transform.eulerAngles
-> for further infos see documentation of 'useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay']
" + text; + useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay = true; + } + } + Vector3 eulerAnglesToDraw = UtilitiesDXXL_Euler.GetEulerAnglesFromNonNullTransform(transform, useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay, false); + UtilitiesDXXL_Euler.EulerRotation_local(eulerAnglesToDraw, transform.position, customVectorToRotate, length_ofUpAndForwardVectors, alpha_ofSquareSpannedByForwardAndUp, alpha_ofUnrotatedGimbalAxes, gimbalSize, text, false, durationInSec, hiddenByNearerObjects, null); + } + + public static void EulerRotation(Vector3 eulerAnglesToDraw, Vector3 posWhereToDraw = default(Vector3), Vector3 customVectorToRotate = default(Vector3), float length_ofUpAndForwardVectors = 0.0f, float alpha_ofSquareSpannedByForwardAndUp = 0.0f, string text = null, float alpha_ofUnrotatedGimbalAxes = 0.06f, float gimbalSize = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Euler.EulerRotation_local(eulerAnglesToDraw, posWhereToDraw, customVectorToRotate, length_ofUpAndForwardVectors, alpha_ofSquareSpannedByForwardAndUp, alpha_ofUnrotatedGimbalAxes, gimbalSize, text, false, durationInSec, hiddenByNearerObjects, null); + } + + public static void EulerRotation(Quaternion quaternionToDrawAsEulerAngles, Vector3 posWhereToDraw = default(Vector3), Vector3 customVectorToRotate = default(Vector3), float length_ofUpAndForwardVectors = 0.0f, float alpha_ofSquareSpannedByForwardAndUp = 0.0f, string text = null, float alpha_ofUnrotatedGimbalAxes = 0.06f, float gimbalSize = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + EulerRotation(quaternionToDrawAsEulerAngles.eulerAngles, posWhereToDraw, customVectorToRotate, length_ofUpAndForwardVectors, alpha_ofSquareSpannedByForwardAndUp, text, alpha_ofUnrotatedGimbalAxes, gimbalSize, durationInSec, hiddenByNearerObjects); + } + + public static void EulerRotation_local(GameObject gameObject_insideLocalSpace, Vector3 customVectorToRotate_local = default(Vector3), float length_ofUpAndForwardVectors_local = 0.0f, float alpha_ofSquareSpannedByForwardAndUp = 0.0f, string text = null, bool useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay = false, float alpha_ofUnrotatedGimbalAxes = 0.06f, float gimbalSize_local = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject_insideLocalSpace, "gameObject_insideLocalSpace")) { return; } + EulerRotation_local(gameObject_insideLocalSpace.transform, customVectorToRotate_local, length_ofUpAndForwardVectors_local, alpha_ofSquareSpannedByForwardAndUp, text, useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay, alpha_ofUnrotatedGimbalAxes, gimbalSize_local, durationInSec, hiddenByNearerObjects); + } + + public static void EulerRotation_local(Transform transform_insideLocalSpace, Vector3 customVectorToRotate_local = default(Vector3), float length_ofUpAndForwardVectors_local = 0.0f, float alpha_ofSquareSpannedByForwardAndUp = 0.0f, string text = null, bool useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay = false, float alpha_ofUnrotatedGimbalAxes = 0.06f, float gimbalSize_local = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform_insideLocalSpace, "transform_insideLocalSpace")) { return; } + Vector3 eulerAnglesToDraw = UtilitiesDXXL_Euler.GetEulerAnglesFromNonNullTransform(transform_insideLocalSpace, useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay, true); + if (transform_insideLocalSpace.parent == null) + { + text = "[ parent transform that defines the local space is 'null'
-> fallback to global rotation]
" + text; + UtilitiesDXXL_Euler.EulerRotation_local(eulerAnglesToDraw, transform_insideLocalSpace.position, customVectorToRotate_local, length_ofUpAndForwardVectors_local, alpha_ofSquareSpannedByForwardAndUp, alpha_ofUnrotatedGimbalAxes, gimbalSize_local, text, false, durationInSec, hiddenByNearerObjects, null); + } + else + { + bool aParentHasANonUniformScale = UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(transform_insideLocalSpace.parent); + if (aParentHasANonUniformScale) + { + text = "[ A parent transform that defines the local space has a non-uniform scale
-> possibly weird results]
" + text; + } + float gimbalSize_global = transform_insideLocalSpace.parent.lossyScale.x * gimbalSize_local; + UtilitiesDXXL_Euler.EulerRotation_local(eulerAnglesToDraw, transform_insideLocalSpace.position, customVectorToRotate_local, length_ofUpAndForwardVectors_local, alpha_ofSquareSpannedByForwardAndUp, alpha_ofUnrotatedGimbalAxes, gimbalSize_global, text, true, durationInSec, hiddenByNearerObjects, transform_insideLocalSpace.parent); + } + } + + public static void EulerRotation_local(Transform parentTransform_thatDefinesTheLocalSpace, Vector3 eulerAnglesToDraw_local, Vector3 posWhereToDraw_global = default(Vector3), Vector3 customVectorToRotate_local = default(Vector3), float length_ofUpAndForwardVectors_local = 0.0f, float alpha_ofSquareSpannedByForwardAndUp = 0.0f, string text = null, float alpha_ofUnrotatedGimbalAxes = 0.06f, float gimbalSize_local = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + if (parentTransform_thatDefinesTheLocalSpace == null) + { + text = "[ parent transform that defines the local space is 'null'
-> fallback to global rotation]
" + text; + UtilitiesDXXL_Euler.EulerRotation_local(eulerAnglesToDraw_local, posWhereToDraw_global, customVectorToRotate_local, length_ofUpAndForwardVectors_local, alpha_ofSquareSpannedByForwardAndUp, alpha_ofUnrotatedGimbalAxes, gimbalSize_local, text, false, durationInSec, hiddenByNearerObjects, null); + } + else + { + bool aParentHasANonUniformScale = UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(parentTransform_thatDefinesTheLocalSpace); + if (aParentHasANonUniformScale) + { + text = "[ A parent transform that defines the local space has a non-uniform scale
-> possibly weird results]
" + text; + } + float gimbalSize_global = parentTransform_thatDefinesTheLocalSpace.lossyScale.x * gimbalSize_local; + UtilitiesDXXL_Euler.EulerRotation_local(eulerAnglesToDraw_local, posWhereToDraw_global, customVectorToRotate_local, length_ofUpAndForwardVectors_local, alpha_ofSquareSpannedByForwardAndUp, alpha_ofUnrotatedGimbalAxes, gimbalSize_global, text, true, durationInSec, hiddenByNearerObjects, parentTransform_thatDefinesTheLocalSpace); + } + } + + public static void EulerRotation_local(Transform parentTransform_thatDefinesTheLocalSpace, Quaternion quaternionToDrawAsEulerAngles_local, Vector3 posWhereToDraw_global = default(Vector3), Vector3 customVectorToRotate_local = default(Vector3), float length_ofUpAndForwardVectors_local = 0.0f, float alpha_ofSquareSpannedByForwardAndUp = 0.0f, string text = null, float alpha_ofUnrotatedGimbalAxes = 0.06f, float gimbalSize_local = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + EulerRotation_local(parentTransform_thatDefinesTheLocalSpace, quaternionToDrawAsEulerAngles_local.eulerAngles, posWhereToDraw_global, customVectorToRotate_local, length_ofUpAndForwardVectors_local, alpha_ofSquareSpannedByForwardAndUp, text, alpha_ofUnrotatedGimbalAxes, gimbalSize_local, durationInSec, hiddenByNearerObjects); + } + + public static void Bounds(GameObject gameObject, Color color = default(Color), bool alsoDrawLocalBounds = true, bool showAlsoBoundsOfChildren = true, float linesWidth = 0.01f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject, "gameObject")) { return; } + Bounds(gameObject.transform, color, alsoDrawLocalBounds, showAlsoBoundsOfChildren, linesWidth, text, durationInSec, hiddenByNearerObjects); + } + + public static void LocalBounds(GameObject gameObject, Color color = default(Color), bool showAlsoBoundsOfChildren = true, float lineWidth_inGlobalUnits = 0.01f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject, "gameObject")) { return; } + LocalBounds(gameObject.transform, color, showAlsoBoundsOfChildren, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + } + + public static void Bounds(Transform transform, Color color = default(Color), bool alsoDrawLocalBounds = true, bool showAlsoBoundsOfChildren = true, float linesWidth = 0.01f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform, "transform")) { return; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + if (alsoDrawLocalBounds) + { + linesWidth = Mathf.Max(linesWidth, 0.01f); + } + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + + Transform[] thisAndAllChildTransforms = transform.GetComponentsInChildren(); + int numberOfDrawnBounds = 0; + + if (thisAndAllChildTransforms == null) + { + UtilitiesDXXL_Log.PrintErrorCode("25"); + return; + } + else + { + bool textHasToBeDrawnYet = true; + DrawGlobalBoundsIfTransformHasAMeshRenderer(ref numberOfDrawnBounds, out textHasToBeDrawnYet, transform, color, linesWidth, text, durationInSec, hiddenByNearerObjects); + + if (showAlsoBoundsOfChildren) + { + for (int i = 0; i < thisAndAllChildTransforms.Length; i++) + { + if (thisAndAllChildTransforms[i] != transform) + { + DrawGlobalBoundsIfTransformHasAMeshRenderer(ref numberOfDrawnBounds, out textHasToBeDrawnYet, thisAndAllChildTransforms[i], color, linesWidth, textHasToBeDrawnYet ? text : null, durationInSec, hiddenByNearerObjects); + } + } + } + + if (numberOfDrawnBounds == 0) + { + UtilitiesDXXL_DrawBasics.PointFallback(transform.position, "[ No bounds found on this GameObject]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + } + + if (alsoDrawLocalBounds) + { + if (numberOfDrawnBounds > 0) + { + Color colorForLocalBounds = UtilitiesDXXL_Colors.GetSimilarColorWithOtherBrightnessValue(color); + LocalBounds(transform, colorForLocalBounds, showAlsoBoundsOfChildren, 0.15f * linesWidth, null, durationInSec, hiddenByNearerObjects); + } + } + + } + + static void DrawGlobalBoundsIfTransformHasAMeshRenderer(ref int numberOfDrawnBounds, out bool textHasToBeDrawnYet, Transform transformToCheck, Color color, float linesWidth, string text, float durationInSec, bool hiddenByNearerObjects) + { + textHasToBeDrawnYet = (text != null); + MeshRenderer meshRenderer = transformToCheck.GetComponent(); + if (meshRenderer != null) + { + if (meshRenderer.bounds != null) + { + Bounds(meshRenderer.bounds, color, linesWidth, text, durationInSec, hiddenByNearerObjects); + numberOfDrawnBounds++; + textHasToBeDrawnYet = false; + } + } + + SkinnedMeshRenderer skinnedMeshRenderer = transformToCheck.gameObject.GetComponent(); + if (skinnedMeshRenderer != null) + { + if (skinnedMeshRenderer.bounds != null) + { + Bounds(skinnedMeshRenderer.bounds, color, linesWidth, text, durationInSec, hiddenByNearerObjects); + numberOfDrawnBounds++; + textHasToBeDrawnYet = false; + } + } + } + + public static void LocalBounds(Transform transform, Color color = default(Color), bool showAlsoBoundsOfChildren = true, float lineWidth_inGlobalUnits = 0.01f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform, "transform")) { return; } + + Transform[] thisAndAllChildTransforms = transform.GetComponentsInChildren(); + int numberOfDrawnBounds = 0; + bool textHasToBeDrawnYet = true; + + DrawLocalBoundsIfTransformHasAMeshFilterOrMeshSkinnedRenderer(ref numberOfDrawnBounds, out textHasToBeDrawnYet, transform, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + + if (showAlsoBoundsOfChildren) + { + for (int i = 0; i < thisAndAllChildTransforms.Length; i++) + { + if (thisAndAllChildTransforms[i] != transform) + { + DrawLocalBoundsIfTransformHasAMeshFilterOrMeshSkinnedRenderer(ref numberOfDrawnBounds, out textHasToBeDrawnYet, thisAndAllChildTransforms[i], color, lineWidth_inGlobalUnits, textHasToBeDrawnYet ? text : null, durationInSec, hiddenByNearerObjects); + } + } + } + + if (numberOfDrawnBounds == 0) + { + UtilitiesDXXL_DrawBasics.PointFallback(transform.position, "[ No bounds found on this GameObject]
" + text, color, lineWidth_inGlobalUnits, durationInSec, hiddenByNearerObjects); + return; + } + } + + static void DrawLocalBoundsIfTransformHasAMeshFilterOrMeshSkinnedRenderer(ref int numberOfDrawnBounds, out bool textHasToBeDrawnYet, Transform transformToCheck, Color color, float lineWidth_inGlobalUnits, string text, float durationInSec, bool hiddenByNearerObjects) + { + textHasToBeDrawnYet = (text != null); + + MeshFilter meshfilter = transformToCheck.gameObject.GetComponent(); + if (meshfilter != null) + { + if (Application.isPlaying) + { + if (meshfilter.mesh != null) + { + if (meshfilter.mesh.bounds != null) + { + LocalBounds(meshfilter.mesh.bounds, transformToCheck, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + numberOfDrawnBounds++; + textHasToBeDrawnYet = false; + } + } + } + else + { + if (meshfilter.sharedMesh != null) + { + if (meshfilter.sharedMesh.bounds != null) + { + LocalBounds(meshfilter.sharedMesh.bounds, transformToCheck, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + numberOfDrawnBounds++; + textHasToBeDrawnYet = false; + } + } + } + } + + SkinnedMeshRenderer skinnedMeshRenderer = transformToCheck.gameObject.GetComponent(); + if (skinnedMeshRenderer != null) + { + if (skinnedMeshRenderer.localBounds != null) + { + if (skinnedMeshRenderer.rootBone == null) + { + text = "[ Local Bounds potentially at the wrong place, because the Skinned Mesh Renderer has no root bone assigned]
" + text; + LocalBounds(skinnedMeshRenderer.localBounds, transformToCheck, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + } + else + { + LocalBounds(skinnedMeshRenderer.localBounds, skinnedMeshRenderer.rootBone, color, lineWidth_inGlobalUnits, text, durationInSec, hiddenByNearerObjects); + } + + numberOfDrawnBounds++; + textHasToBeDrawnYet = false; + } + } + } + + public static void Bounds(Bounds bounds, Color color = default(Color), float linesWidth = 0.01f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + + if (UtilitiesDXXL_Math.ApproximatelyZero(bounds.size)) + { + UtilitiesDXXL_DrawBasics.PointFallback(bounds.center, "[ Bounds with size of 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + + if (UtilitiesDXXL_Math.GetSmallestComponent(bounds.extents) < 0.0f) + { + text = "[ Bounds.extents ( " + bounds.extents.x + " , " + bounds.extents.y + " , " + bounds.extents.z + " ) contains negative values -> 'Bounds.Contains()' will always return 'false']
" + text; + } + + //text ABOVE line (in contrast to "LocalBounds" which may often be superimposed): + UtilitiesDXXL_Shapes.Cube(bounds.center, bounds.size, color, color, Vector3.up, Vector3.forward, linesWidth, text + "

Bounds", DrawBasics.LineStyle.disconnectedAnchors, 1.0f, true, durationInSec, hiddenByNearerObjects, false, null); + } + + public static void LocalBounds(Bounds localBounds, Transform transformDefiningLocalSpace, Color color = default(Color), float lineWidth_inGlobalUnits = 0.01f, string text = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transformDefiningLocalSpace, "transformDefiningLocalSpace")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth_inGlobalUnits, "linesWidth")) { return; } + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + Vector3 boundsCenter_worldSpace = transformDefiningLocalSpace.TransformPoint(localBounds.center); + + if (UtilitiesDXXL_Math.ApproximatelyZero(localBounds.size)) + { + UtilitiesDXXL_DrawBasics.PointFallback(boundsCenter_worldSpace, "[ LocalBounds with size of 0 (in localSpace)]
" + text, color, lineWidth_inGlobalUnits, durationInSec, hiddenByNearerObjects); + return; + } + + Vector3 globalSize = Vector3.Scale(localBounds.size, transformDefiningLocalSpace.lossyScale); + if (UtilitiesDXXL_Math.ApproximatelyZero(globalSize)) + { + UtilitiesDXXL_DrawBasics.PointFallback(boundsCenter_worldSpace, "[ LocalBounds with size of 0 (in worldspace)]
" + text, color, lineWidth_inGlobalUnits, durationInSec, hiddenByNearerObjects); + return; + } + + if (UtilitiesDXXL_Math.GetSmallestComponent(localBounds.extents) < 0.0f) + { + text = "[ LocalBounds.extents ( " + localBounds.extents.x + " , " + localBounds.extents.y + " , " + localBounds.extents.z + " ) contains negative values -> 'Bounds.Contains()' will always return 'false']
" + text; + } + + if (UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(transformDefiningLocalSpace.parent)) + { + text = "[ LocalBounds: The local transform has a parent with non-uniform scale
-> possibly weird results]
" + text; + } + + //text BELOW line (in contrast to "(Global)Bounds" which may often be superimposed): + UtilitiesDXXL_Shapes.Cube(boundsCenter_worldSpace, globalSize, color, color, transformDefiningLocalSpace.up, transformDefiningLocalSpace.forward, lineWidth_inGlobalUnits, "Local Bounds

" + text, DrawBasics.LineStyle.disconnectedAnchors, 1.0f, false, durationInSec, hiddenByNearerObjects, false, null); + } + + public static void DotProduct(Vector3 vector1_lhs, Vector3 vector2_rhs, Vector3 posWhereToDraw = default(Vector3), float linesWidth = 0.0025f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //"lhs" = "left hand side (of equation)". + //"rhs" = "right hand side (of equation)" + + UtilitiesDXXL_EngineBasics.DotProduct(vector1_lhs, vector2_rhs, posWhereToDraw, linesWidth, durationInSec, hiddenByNearerObjects); + } + + public static void CrossProduct(Vector3 vector1_lhs_leftThumb, Vector3 vector2_rhs_leftIndexFinger, Vector3 posWhereToDraw = default(Vector3), float linesWidth = 0.0025f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //"lhs" = "left hand side (of equation)" + //"rhs" = "right hand side (of equation)" + //cross product result is "left middle finger" according to the left hand rule + + UtilitiesDXXL_EngineBasics.CrossProduct(vector1_lhs_leftThumb, vector2_rhs_leftIndexFinger, posWhereToDraw, linesWidth, durationInSec, hiddenByNearerObjects); + } + + public static void TagGameObject(GameObject gameObject, string text = null, Color colorForText = default(Color), Color colorForTagBox = default(Color), float textSize = 0.2f, float linesWidth = 0.0f, bool encapsulateChildren = true, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject, "gameObject")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(textSize, "textSize")) { return; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + + if (UtilitiesDXXL_Colors.IsDefaultColor(colorForText)) + { + colorForText = UtilitiesDXXL_Colors.Get_randomColorSeeded(gameObject.GetInstanceID()); + } + + if (UtilitiesDXXL_Colors.IsDefaultColor(colorForTagBox)) + { + colorForTagBox = UtilitiesDXXL_Colors.Get_randomColorSeeded(gameObject.GetInstanceID()); + } + + UtilitiesDXXL_EngineBasics.FillBounds(gameObject, encapsulateChildren, out Vector3 globalExtents, out Vector3 globalCenter, out bool rotateBoundingBox); + UtilitiesDXXL_EngineBasics.FillTagBoxOrientationVectors(gameObject, rotateBoundingBox, out Vector3 tagBoxUp, out Vector3 tagBoxForward); + + if (UtilitiesDXXL_Math.ApproximatelyZero(globalExtents)) + { + UtilitiesDXXL_DrawBasics.PointFallback(gameObject.transform.position, "[ GameObject with extent of zero]
" + text, colorForTagBox, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + + bool textSize_isZero = UtilitiesDXXL_Math.ApproximatelyZero(textSize); + if (textSize_isZero) + { + UtilitiesDXXL_Shapes.Set_forcedConstantWorldspaceTextSize_forTextAtShapes_reversible(0.0f); //-> text will be relative to gameobject size, or to screenspace + } + else + { + UtilitiesDXXL_Shapes.Set_forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_reversible(0.0f); //-> disable fixed screenspace size, since it would overrule the fixed worldspace size + UtilitiesDXXL_Shapes.Set_forcedConstantWorldspaceTextSize_forTextAtShapes_reversible(textSize); + } + + UtilitiesDXXL_Shapes.Cube(globalCenter, 2.0f * globalExtents, colorForTagBox, colorForText, tagBoxUp, tagBoxForward, linesWidth, text, DrawBasics.LineStyle.disconnectedAnchors, 1.0f, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false, gameObject.name); + + if (textSize_isZero) + { + UtilitiesDXXL_Shapes.Reverse_forcedConstantWorldspaceTextSize_forTextAtShapes(); + } + else + { + UtilitiesDXXL_Shapes.Reverse_forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes(); + UtilitiesDXXL_Shapes.Reverse_forcedConstantWorldspaceTextSize_forTextAtShapes(); + } + + } + + public static void TagGameObjectScreenspace(GameObject gameObject, string text = null, Color colorForText = default(Color), Color colorForTagBox = default(Color), float linesWidth_relToViewportHeight = 0.0f, bool drawPointerIfOffscreen = true, float relTextSizeScaling = 1.0f, bool encapsulateChildren = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawEngineBasics.TagGameObjectScreenspace") == false) { return; } + TagGameObjectScreenspace(automaticallyFoundCamera, gameObject, text, colorForText, colorForTagBox, linesWidth_relToViewportHeight, drawPointerIfOffscreen, relTextSizeScaling, encapsulateChildren, durationInSec); + } + + public static void TagGameObjectScreenspace(Camera screenCamera, GameObject gameObject, string text = null, Color colorForText = default(Color), Color colorForTagBox = default(Color), float linesWidth_relToViewportHeight = 0.0f, bool drawPointerIfOffscreen = true, float relTextSizeScaling = 1.0f, bool encapsulateChildren = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TagGameObjectScreenspace.Add(new TagGameObjectScreenspace(screenCamera, gameObject, text, colorForText, colorForTagBox, linesWidth_relToViewportHeight, drawPointerIfOffscreen, relTextSizeScaling, encapsulateChildren, durationInSec)); + return; + } + + UtilitiesDXXL_EngineBasics.TagGameObjectScreenspace(screenCamera, gameObject, text, colorForText, colorForTagBox, linesWidth_relToViewportHeight, drawPointerIfOffscreen, relTextSizeScaling, encapsulateChildren, durationInSec); + } + + public static void Camera(Vector3 position, Quaternion rotation = default(Quaternion), Color color = default(Color), string text = null, float linesWidth = 0.0f, float nearClipPlaneDistance = 0.3f, float fieldOfViewAngleDeg = 60.0f, float aspectRatioOfScreen = 16.0f / 9.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Camera(position, rotation * Vector3.forward, rotation * Vector3.up, color, text, linesWidth, nearClipPlaneDistance, fieldOfViewAngleDeg, aspectRatioOfScreen, durationInSec, hiddenByNearerObjects); + } + + static InternalDXXL_Plane camPlane = new InternalDXXL_Plane(); + public static void Camera(Vector3 position, Vector3 forward = default(Vector3), Vector3 up = default(Vector3), Color color = default(Color), string text = null, float linesWidth = 0.0f, float nearClipPlaneDistance = 0.3f, float fieldOfViewAngleDeg = 60.0f, float aspectRatioOfScreen = 16.0f / 9.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward, "forward")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up, "up")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(nearClipPlaneDistance, "nearClipPlaneDistance")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(fieldOfViewAngleDeg, "fieldOfViewAngleDeg")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(aspectRatioOfScreen, "aspectRatioOfScreen")) { return; } + + forward = UtilitiesDXXL_Math.OverwriteDefaultVectors(forward, Vector3.forward); + camPlane.Recreate(position, forward); + up = UtilitiesDXXL_Math.OverwriteDefaultVectors(up, Vector3.up); + up = UtilitiesDXXL_Shapes.ForceVectorPerpToOtherVector(up, camPlane); + + aspectRatioOfScreen = UtilitiesDXXL_Math.AbsNonZeroValue(aspectRatioOfScreen); + if (aspectRatioOfScreen < 0.001f) + { + UtilitiesDXXL_DrawBasics.PointFallback(position, "[ Camera with aspectRatioOfScreen near 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + + nearClipPlaneDistance = Mathf.Max(nearClipPlaneDistance, 0.01f); + fieldOfViewAngleDeg = Mathf.Clamp(fieldOfViewAngleDeg, 0.1f, 179.9f); + + UtilitiesDXXL_EngineBasics.Camera(position, forward, up, false, 5.0f, fieldOfViewAngleDeg, nearClipPlaneDistance, aspectRatioOfScreen, color, text, linesWidth, durationInSec, hiddenByNearerObjects); + } + + public static void Camera(Camera camera, Color color = default(Color), string text = null, float linesWidth = 0.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + UtilitiesDXXL_EngineBasics.Camera(camera.transform.position, camera.transform.forward, camera.transform.up, camera.orthographic, camera.orthographicSize, camera.fieldOfView, camera.nearClipPlane, camera.aspect, color, text, linesWidth, durationInSec, hiddenByNearerObjects); + } + + public static void CameraFrustum(Vector3 position_ofCamera, Quaternion rotation_ofCamera = default(Quaternion), Color color = default(Color), float nearClipPlaneDistance = 0.3f, float farClipPlaneDistance = 1000.0f, float fieldOfViewAngleDeg = 60.0f, float aspectRatioOfScreen = 16.0f / 9.0f, float alphaFactor_forBoundarySurfaceLines = 0.18f, float linesWidth_ofEdges = 0.0f, int linesPerBoundarySurface = 60, string text = null, bool forceTextOnNearPlaneUnmirroredTowardsCam = true, Vector3 positionOnHighlightedPlane = default(Vector3), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation_ofCamera = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation_ofCamera); + CameraFrustum(position_ofCamera, rotation_ofCamera * Vector3.forward, rotation_ofCamera * Vector3.up, color, nearClipPlaneDistance, farClipPlaneDistance, fieldOfViewAngleDeg, aspectRatioOfScreen, alphaFactor_forBoundarySurfaceLines, linesWidth_ofEdges, linesPerBoundarySurface, text, forceTextOnNearPlaneUnmirroredTowardsCam, positionOnHighlightedPlane, durationInSec, hiddenByNearerObjects); + } + + public static void CameraFrustum(Vector3 position_ofCamera, Vector3 forward_ofCamera = default(Vector3), Vector3 up_ofCamera = default(Vector3), Color color = default(Color), float nearClipPlaneDistance = 0.3f, float farClipPlaneDistance = 1000.0f, float fieldOfViewAngleDeg = 60.0f, float aspectRatioOfScreen = 16.0f / 9.0f, float alphaFactor_forBoundarySurfaceLines = 0.18f, float linesWidth_ofEdges = 0.0f, int linesPerBoundarySurface = 60, string text = null, bool forceTextOnNearPlaneUnmirroredTowardsCam = true, Vector3 positionOnHighlightedPlane = default(Vector3), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position_ofCamera, "position_ofCamera")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward_ofCamera, "forward_ofCamera")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_ofCamera, "up_ofCamera")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(nearClipPlaneDistance, "nearClipPlaneDistance")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(farClipPlaneDistance, "farClipPlaneDistance")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(fieldOfViewAngleDeg, "fieldOfViewAngleDeg")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(aspectRatioOfScreen, "aspectRatioOfScreen")) { return; } + + forward_ofCamera = UtilitiesDXXL_Math.OverwriteDefaultVectors(forward_ofCamera, Vector3.forward); + camPlane.Recreate(position_ofCamera, forward_ofCamera); + up_ofCamera = UtilitiesDXXL_Math.OverwriteDefaultVectors(up_ofCamera, Vector3.up); + up_ofCamera = UtilitiesDXXL_Shapes.ForceVectorPerpToOtherVector(up_ofCamera, camPlane); + + aspectRatioOfScreen = UtilitiesDXXL_Math.AbsNonZeroValue(aspectRatioOfScreen); + if (aspectRatioOfScreen < 0.001f) + { + UtilitiesDXXL_DrawBasics.PointFallback(position_ofCamera, "[ CameraFrustum with aspectRatioOfScreen near 0]
" + text, color, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + nearClipPlaneDistance = Mathf.Max(nearClipPlaneDistance, 0.01f); + farClipPlaneDistance = Mathf.Max(farClipPlaneDistance, 0.011f); + fieldOfViewAngleDeg = Mathf.Clamp(fieldOfViewAngleDeg, 0.1f, 179.9f); + + UtilitiesDXXL_EngineBasics.CameraFrustum(position_ofCamera, forward_ofCamera, up_ofCamera, false, 5.0f, fieldOfViewAngleDeg, nearClipPlaneDistance, farClipPlaneDistance, aspectRatioOfScreen, color, text, forceTextOnNearPlaneUnmirroredTowardsCam, linesWidth_ofEdges, alphaFactor_forBoundarySurfaceLines, linesPerBoundarySurface, positionOnHighlightedPlane, durationInSec, hiddenByNearerObjects); + } + + public static void CameraFrustum(Camera camera, Color color = default(Color), float alphaFactor_forBoundarySurfaceLines = 0.18f, float linesWidth_ofEdges = 0.0f, int linesPerBoundarySurface = 60, string text = null, bool forceTextOnNearPlaneUnmirroredTowardsCam = true, Vector3 positionOnHighlightedPlane = default(Vector3), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + UtilitiesDXXL_EngineBasics.CameraFrustum(camera.transform.position, camera.transform.forward, camera.transform.up, camera.orthographic, camera.orthographicSize, camera.fieldOfView, camera.nearClipPlane, camera.farClipPlane, camera.aspect, color, text, forceTextOnNearPlaneUnmirroredTowardsCam, linesWidth_ofEdges, alphaFactor_forBoundarySurfaceLines, linesPerBoundarySurface, positionOnHighlightedPlane, durationInSec, hiddenByNearerObjects); + } + + public static void BoolDisplayer2D(bool boolValueToDisplay, Vector2 position = default(Vector2), string boolName = null, float size = 1.0f, float custom_zPos = float.PositiveInfinity, Color color_forTextAndFrame = default(Color), Color overwriteColor_forTrue = default(Color), Color overwriteColor_forFalse = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 positionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(position, zPos); + BoolDisplayer(boolValueToDisplay, positionV3, boolName, size, UnityEngine.Quaternion.identity, color_forTextAndFrame, overwriteColor_forTrue, overwriteColor_forFalse, durationInSec, hiddenByNearerObjects); + } + + public static void BoolDisplayer(bool boolValueToDisplay, Vector3 position = default(Vector3), string boolName = null, float size = 1.0f, Quaternion rotation = default(Quaternion), Color color_forTextAndFrame = default(Color), Color overwriteColor_forTrue = default(Color), Color overwriteColor_forFalse = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + UtilitiesDXXL_EngineBasics.BoolDisplayer(boolValueToDisplay, position, boolName, size, rotation, color_forTextAndFrame, overwriteColor_forTrue, overwriteColor_forFalse, durationInSec, hiddenByNearerObjects); + } + + public static void BoolDisplayerScreenspace(bool boolValueToDisplay, string boolName, Vector3 position_in3DWorldspace, float size_relToViewportHeight = 0.175f, Color color_forTextAndFrame = default(Color), Color overwriteColor_forTrue = default(Color), Color overwriteColor_forFalse = default(Color), float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_BoolDisplayerScreenspace_3Dpos.Add(new BoolDisplayerScreenspace_3Dpos(boolValueToDisplay, boolName, position_in3DWorldspace, size_relToViewportHeight, color_forTextAndFrame, overwriteColor_forTrue, overwriteColor_forFalse, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawEngineBasics.BoolDisplayerScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + BoolDisplayerScreenspace(boolValueToDisplay, boolName, position_in2DViewportSpace, size_relToViewportHeight, color_forTextAndFrame, overwriteColor_forTrue, overwriteColor_forFalse, durationInSec); + } + + public static void BoolDisplayerScreenspace(Camera screenCamera, bool boolValueToDisplay, string boolName, Vector3 position_in3DWorldspace, float size_relToViewportHeight = 0.175f, Color color_forTextAndFrame = default(Color), Color overwriteColor_forTrue = default(Color), Color overwriteColor_forFalse = default(Color), float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam.Add(new BoolDisplayerScreenspace_3Dpos_cam(screenCamera, boolValueToDisplay, boolName, position_in3DWorldspace, size_relToViewportHeight, color_forTextAndFrame, overwriteColor_forTrue, overwriteColor_forFalse, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + BoolDisplayerScreenspace(screenCamera, boolValueToDisplay, boolName, position_in2DViewportSpace, size_relToViewportHeight, color_forTextAndFrame, overwriteColor_forTrue, overwriteColor_forFalse, durationInSec); + } + + public static void BoolDisplayerScreenspace(bool boolValueToDisplay, string boolName = null, Vector2 position_in2DViewportSpace = default(Vector2), float size_relToViewportHeight = 0.175f, Color color_forTextAndFrame = default(Color), Color overwriteColor_forTrue = default(Color), Color overwriteColor_forFalse = default(Color), float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawEngineBasics.BoolDisplayerScreenspace") == false) { return; } + BoolDisplayerScreenspace(automaticallyFoundCamera, boolValueToDisplay, boolName, position_in2DViewportSpace, size_relToViewportHeight, color_forTextAndFrame, overwriteColor_forTrue, overwriteColor_forFalse, durationInSec); + } + + public static void BoolDisplayerScreenspace(Camera screenCamera, bool boolValueToDisplay, string boolName = null, Vector2 position_in2DViewportSpace = default(Vector2), float size_relToViewportHeight = 0.175f, Color color_forTextAndFrame = default(Color), Color overwriteColor_forTrue = default(Color), Color overwriteColor_forFalse = default(Color), float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam.Add(new BoolDisplayerScreenspace_2Dpos_cam(screenCamera, boolValueToDisplay, boolName, position_in2DViewportSpace, size_relToViewportHeight, color_forTextAndFrame, overwriteColor_forTrue, overwriteColor_forFalse, durationInSec)); + return; + } + + UtilitiesDXXL_EngineBasics.BoolDisplayerScreenspace(screenCamera, boolValueToDisplay, boolName, position_in2DViewportSpace, size_relToViewportHeight, color_forTextAndFrame, overwriteColor_forTrue, overwriteColor_forFalse, durationInSec); + } + + public static void RayLineExtended(Ray ray, Color color = default(Color), float width = 0.0f, string text = null, float forceFixedConeLength = 0.0f, bool addNormalizedMarkingText = true, float enlargeSmallTextToThisMinTextSize = 0.005f, float extentionLength = 1000.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + RayLineExtended(ray.origin, ray.direction, color, width, text, forceFixedConeLength, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, extentionLength, durationInSec, hiddenByNearerObjects); + } + + public static void RayLineExtended(Vector3 rayOrigin, Vector3 rayDirection, Color color = default(Color), float width = 0.0f, string text = null, float forceFixedConeLength = 0.0f, bool addNormalizedMarkingText = true, float enlargeSmallTextToThisMinTextSize = 0.005f, float extentionLength = 1000.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_EngineBasics.RayLineExtended(false, rayOrigin, rayDirection, color, width, text, forceFixedConeLength, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, extentionLength, durationInSec, hiddenByNearerObjects); + } + + public static void RayLineExtended2D(Ray2D ray, Color color = default(Color), float width = 0.0f, string text = null, float custom_zPos = float.PositiveInfinity, float forceFixedConeLength = 0.0f, bool addNormalizedMarkingText = true, float enlargeSmallTextToThisMinTextSize = 0.005f, float extentionLength = 1000.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + RayLineExtended2D(ray.origin, ray.direction, color, width, text, custom_zPos, forceFixedConeLength, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, extentionLength, durationInSec, hiddenByNearerObjects); + } + + public static void RayLineExtended2D(Vector2 rayOrigin, Vector2 rayDirection, Color color = default(Color), float width = 0.0f, string text = null, float custom_zPos = float.PositiveInfinity, float forceFixedConeLength = 0.0f, bool addNormalizedMarkingText = true, float enlargeSmallTextToThisMinTextSize = 0.005f, float extentionLength = 1000.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 rayOriginV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(rayOrigin, zPos); + Vector3 rayDirectionV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(rayDirection); + UtilitiesDXXL_EngineBasics.RayLineExtended(true, rayOriginV3, rayDirectionV3, color, width, text, forceFixedConeLength, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, extentionLength, durationInSec, hiddenByNearerObjects); + } + + public static void RayLineExtendedScreenspace(Vector2 rayOrigin, Vector2 rayDirection, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, float coneLength_relToViewportHeight = 0.05f, bool displayDistanceOutsideScreenBorder = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawEngineBasics.RayLineExtendedScreenspace") == false) { return; } + RayLineExtendedScreenspace(automaticallyFoundCamera, rayOrigin, rayDirection, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, coneLength_relToViewportHeight, displayDistanceOutsideScreenBorder, durationInSec); + } + + public static void RayLineExtendedScreenspace(Camera screenCamera, Vector2 rayOrigin, Vector2 rayDirection, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, float coneLength_relToViewportHeight = 0.05f, bool displayDistanceOutsideScreenBorder = true, float durationInSec = 0.0f) + { + UtilitiesDXXL_EngineBasics.RayLineExtendedScreenspace(screenCamera, rayOrigin, rayDirection, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, coneLength_relToViewportHeight, displayDistanceOutsideScreenBorder, durationInSec); + } + + public static void CoordinateAxesGizmo(Vector3 position, float lengthPerAxis = 1.0f, float linesWidth = 0.025f, string text = null, bool drawXYZchars = true, bool skipConeDrawing = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lengthPerAxis, "lengthPerAxis")) { return; } //-> would also be checked in "CoordinateAxesGizmoLocal", but has different name there + CoordinateAxesGizmoLocal(position, UnityEngine.Quaternion.identity, default(Vector3), lengthPerAxis, linesWidth, text, drawXYZchars, skipConeDrawing, durationInSec, hiddenByNearerObjects); + } + + public static void CoordinateAxesGizmoLocal(GameObject gameObject_whoseLocalSpaceIsDisplayed, float forceAllAxesLength = 0.0f, float lineWidth_inGlobalUnits = 0.025f, string text = null, bool drawXYZchars = true, bool skipConeDrawing = false, bool skipWarningForNonUniformParentScale = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject_whoseLocalSpaceIsDisplayed, "gameObject_whoseLocalSpaceIsDisplayed")) { return; } + CoordinateAxesGizmoLocal(gameObject_whoseLocalSpaceIsDisplayed.transform, forceAllAxesLength, lineWidth_inGlobalUnits, text, drawXYZchars, skipConeDrawing, skipWarningForNonUniformParentScale, durationInSec, hiddenByNearerObjects); + } + + public static void CoordinateAxesGizmoLocal(Transform transform_whoseLocalSpaceIsDisplayed, float forceAllAxesLength = 0.0f, float lineWidth_inGlobalUnits = 0.025f, string text = null, bool drawXYZchars = true, bool skipConeDrawing = false, bool skipWarningForNonUniformParentScale = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform_whoseLocalSpaceIsDisplayed, "transform_whoseLocalSpaceIsDisplayed")) { return; } + + bool aParentHasANonUniformScale = UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(transform_whoseLocalSpaceIsDisplayed.parent); + if (skipWarningForNonUniformParentScale) { aParentHasANonUniformScale = false; } + UtilitiesDXXL_EngineBasics.CoordinateAxesGizmoLocal(transform_whoseLocalSpaceIsDisplayed.position, transform_whoseLocalSpaceIsDisplayed.rotation, transform_whoseLocalSpaceIsDisplayed.lossyScale, forceAllAxesLength, lineWidth_inGlobalUnits, text, drawXYZchars, skipConeDrawing, durationInSec, hiddenByNearerObjects, aParentHasANonUniformScale); + } + + public static void CoordinateAxesGizmoLocal(Vector3 position_OfLocalCoordinateSystem, Quaternion rotation_OfLocalCoordinateSystem, Vector3 scale_OfLocalCoordinateSystem = default(Vector3), float forceAllAxesLength = 0.0f, float lineWidth_inGlobalUnits = 0.025f, string text = null, bool drawXYZchars = true, bool skipConeDrawing = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + UtilitiesDXXL_EngineBasics.CoordinateAxesGizmoLocal(position_OfLocalCoordinateSystem, rotation_OfLocalCoordinateSystem, scale_OfLocalCoordinateSystem, forceAllAxesLength, lineWidth_inGlobalUnits, text, drawXYZchars, skipConeDrawing, durationInSec, hiddenByNearerObjects, false); + } + + public static void GridPlanes(Transform transformAroundWhichToDraw, float extentOfEachGridPlane_rel = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transformAroundWhichToDraw, "transformAroundWhichToDraw")) { return; } + GridPlanes(transformAroundWhichToDraw.position, extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + + public static void GridPlanes(Vector3 positionAroundWhichToDraw, float extentOfEachGridPlane_rel = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridPlanes(true, true, true, positionAroundWhichToDraw, extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + + public static void XGridPlanes(Transform transformAroundWhichToDraw, float extentOfEachGridPlane_rel = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transformAroundWhichToDraw, "transformAroundWhichToDraw")) { return; } + XGridPlanes(transformAroundWhichToDraw.position, extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void XGridPlanes(Vector3 positionAroundWhichToDraw, float extentOfEachGridPlane_rel = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridPlanes(true, false, false, positionAroundWhichToDraw, extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void YGridPlanes(Transform transformAroundWhichToDraw, float extentOfEachGridPlane_rel = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transformAroundWhichToDraw, "transformAroundWhichToDraw")) { return; } + YGridPlanes(transformAroundWhichToDraw.position, extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void YGridPlanes(Vector3 positionAroundWhichToDraw, float extentOfEachGridPlane_rel = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridPlanes(false, true, false, positionAroundWhichToDraw, extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void ZGridPlanes(Transform transformAroundWhichToDraw, float extentOfEachGridPlane_rel = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transformAroundWhichToDraw, "transformAroundWhichToDraw")) { return; } + ZGridPlanes(transformAroundWhichToDraw.position, extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void ZGridPlanes(Vector3 positionAroundWhichToDraw, float extentOfEachGridPlane_rel = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridPlanes(false, false, true, positionAroundWhichToDraw, extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void GridPlanesLocal(Transform childTransformAroundWhichToDrawGridOfParent, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDrawGridOfParent, "childTransformAroundWhichToDrawGridOfParent")) { return; } + if (childTransformAroundWhichToDrawGridOfParent.parent == null) + { + GridPlanesLocal(Vector3.zero, Vector3.one, Quaternion.identity, childTransformAroundWhichToDrawGridOfParent.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + else + { + GridPlanesLocal(childTransformAroundWhichToDrawGridOfParent.parent.position, childTransformAroundWhichToDrawGridOfParent.parent.lossyScale, childTransformAroundWhichToDrawGridOfParent.parent.rotation, childTransformAroundWhichToDrawGridOfParent.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + } + + public static void GridPlanesLocal(Transform parentTransformThatDefinesTheLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransformThatDefinesTheLocalSpace == null) + { + UtilitiesDXXL_Grid.GridPlanesLocal(Vector3.zero, Vector3.one, Quaternion.identity, true, true, true, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Grid.GridPlanesLocal(parentTransformThatDefinesTheLocalSpace.position, parentTransformThatDefinesTheLocalSpace.lossyScale, parentTransformThatDefinesTheLocalSpace.rotation, true, true, true, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + } + + public static void XGridPlanesLocal(Transform childTransformAroundWhichToDrawGridOfParent, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDrawGridOfParent, "childTransformAroundWhichToDrawGridOfParent")) { return; } + if (childTransformAroundWhichToDrawGridOfParent.parent == null) + { + XGridPlanesLocal(Vector3.zero, Vector3.one, Quaternion.identity, childTransformAroundWhichToDrawGridOfParent.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + else + { + XGridPlanesLocal(childTransformAroundWhichToDrawGridOfParent.parent.position, childTransformAroundWhichToDrawGridOfParent.parent.lossyScale, childTransformAroundWhichToDrawGridOfParent.parent.rotation, childTransformAroundWhichToDrawGridOfParent.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + } + + public static void XGridPlanesLocal(Transform parentTransformThatDefinesTheLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransformThatDefinesTheLocalSpace == null) + { + UtilitiesDXXL_Grid.GridPlanesLocal(Vector3.zero, Vector3.one, Quaternion.identity, true, false, false, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Grid.GridPlanesLocal(parentTransformThatDefinesTheLocalSpace.position, parentTransformThatDefinesTheLocalSpace.lossyScale, parentTransformThatDefinesTheLocalSpace.rotation, true, false, false, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + } + + public static void YGridPlanesLocal(Transform childTransformAroundWhichToDrawGridOfParent, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDrawGridOfParent, "childTransformAroundWhichToDrawGridOfParent")) { return; } + if (childTransformAroundWhichToDrawGridOfParent.parent == null) + { + YGridPlanesLocal(Vector3.zero, Vector3.one, Quaternion.identity, childTransformAroundWhichToDrawGridOfParent.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + else + { + YGridPlanesLocal(childTransformAroundWhichToDrawGridOfParent.parent.position, childTransformAroundWhichToDrawGridOfParent.parent.lossyScale, childTransformAroundWhichToDrawGridOfParent.parent.rotation, childTransformAroundWhichToDrawGridOfParent.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + } + + public static void YGridPlanesLocal(Transform parentTransformThatDefinesTheLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransformThatDefinesTheLocalSpace == null) + { + UtilitiesDXXL_Grid.GridPlanesLocal(Vector3.zero, Vector3.one, Quaternion.identity, false, true, false, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Grid.GridPlanesLocal(parentTransformThatDefinesTheLocalSpace.position, parentTransformThatDefinesTheLocalSpace.lossyScale, parentTransformThatDefinesTheLocalSpace.rotation, false, true, false, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + } + + public static void ZGridPlanesLocal(Transform childTransformAroundWhichToDrawGridOfParent, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDrawGridOfParent, "childTransformAroundWhichToDrawGridOfParent")) { return; } + if (childTransformAroundWhichToDrawGridOfParent.parent == null) + { + ZGridPlanesLocal(Vector3.zero, Vector3.one, Quaternion.identity, childTransformAroundWhichToDrawGridOfParent.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + else + { + ZGridPlanesLocal(childTransformAroundWhichToDrawGridOfParent.parent.position, childTransformAroundWhichToDrawGridOfParent.parent.lossyScale, childTransformAroundWhichToDrawGridOfParent.parent.rotation, childTransformAroundWhichToDrawGridOfParent.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + } + + public static void ZGridPlanesLocal(Transform parentTransformThatDefinesTheLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransformThatDefinesTheLocalSpace == null) + { + UtilitiesDXXL_Grid.GridPlanesLocal(Vector3.zero, Vector3.one, Quaternion.identity, false, false, true, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Grid.GridPlanesLocal(parentTransformThatDefinesTheLocalSpace.position, parentTransformThatDefinesTheLocalSpace.lossyScale, parentTransformThatDefinesTheLocalSpace.rotation, false, false, true, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + } + + public static void GridPlanesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Transform childTransformAroundWhichToDraw, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDraw, "childTransformAroundWhichToDraw")) { return; } + GridPlanesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, childTransformAroundWhichToDraw.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + + public static void GridPlanesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 localPositionAroundWhichToDraw = default(Vector3), float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridPlanesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, true, true, true, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + + public static void XGridPlanesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Transform childTransformAroundWhichToDraw, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDraw, "childTransformAroundWhichToDraw")) { return; } + XGridPlanesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, childTransformAroundWhichToDraw.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void XGridPlanesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 localPositionAroundWhichToDraw = default(Vector3), float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridPlanesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, true, false, false, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void YGridPlanesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Transform childTransformAroundWhichToDraw, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDraw, "childTransformAroundWhichToDraw")) { return; } + YGridPlanesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, childTransformAroundWhichToDraw.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void YGridPlanesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 localPositionAroundWhichToDraw = default(Vector3), float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridPlanesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, false, true, false, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + public static void ZGridPlanesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Transform childTransformAroundWhichToDraw, float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDraw, "childTransformAroundWhichToDraw")) { return; } + ZGridPlanesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, childTransformAroundWhichToDraw.localPosition, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void ZGridPlanesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 localPositionAroundWhichToDraw = default(Vector3), float extentOfEachGridPlane_rel_inLocalSpaceUnits = 10.0f, float drawDensity = 1.0f, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = false, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridPlanesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, false, false, true, localPositionAroundWhichToDraw, extentOfEachGridPlane_rel_inLocalSpaceUnits, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public enum XGridLinesOrientation { alongY, alongZ }; + public enum YGridLinesOrientation { alongX, alongZ }; + public enum ZGridLinesOrientation { alongX, alongY }; + public static void GridLines(Transform transformAroundWhichToDraw, float coveredGridUnits_rel = 10.0f, float lengthOfEachGridLine_rel = 10.0f, float linesWidth_signFlipsPerp = 0.0f, XGridLinesOrientation orientation_ofXLines = XGridLinesOrientation.alongY, YGridLinesOrientation orientation_ofYLines = YGridLinesOrientation.alongX, ZGridLinesOrientation orientation_ofZLines = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transformAroundWhichToDraw, "transformAroundWhichToDraw")) { return; } + GridLines(transformAroundWhichToDraw.position, coveredGridUnits_rel, lengthOfEachGridLine_rel, linesWidth_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + + public static void GridLines(Vector3 positionAroundWhichToDraw, float coveredGridUnits_rel = 10.0f, float lengthOfEachGridLine_rel = 10.0f, float linesWidth_signFlipsPerp = 0.0f, XGridLinesOrientation orientation_ofXLines = XGridLinesOrientation.alongY, YGridLinesOrientation orientation_ofYLines = YGridLinesOrientation.alongX, ZGridLinesOrientation orientation_ofZLines = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridLines(positionAroundWhichToDraw, coveredGridUnits_rel, lengthOfEachGridLine_rel, linesWidth_signFlipsPerp, true, true, true, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + + public static void XGridLines(Transform transformAroundWhichToDraw, float coveredGridUnits_rel = 10.0f, float lengthOfEachGridLine_rel = 10.0f, float linesWidth_signFlipsPerp = 0.0f, XGridLinesOrientation orientation = XGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transformAroundWhichToDraw, "transformAroundWhichToDraw")) { return; } + XGridLines(transformAroundWhichToDraw.position, coveredGridUnits_rel, lengthOfEachGridLine_rel, linesWidth_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void XGridLines(Vector3 positionAroundWhichToDraw, float coveredGridUnits_rel = 10.0f, float lengthOfEachGridLine_rel = 10.0f, float linesWidth_signFlipsPerp = 0.0f, XGridLinesOrientation orientation = XGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridLines(positionAroundWhichToDraw, coveredGridUnits_rel, lengthOfEachGridLine_rel, linesWidth_signFlipsPerp, true, false, false, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, orientation, YGridLinesOrientation.alongX, ZGridLinesOrientation.alongX); + } + + public static void YGridLines(Transform transformAroundWhichToDraw, float coveredGridUnits_rel = 10.0f, float lengthOfEachGridLine_rel = 10.0f, float linesWidth_signFlipsPerp = 0.0f, YGridLinesOrientation orientation = YGridLinesOrientation.alongX, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transformAroundWhichToDraw, "transformAroundWhichToDraw")) { return; } + YGridLines(transformAroundWhichToDraw.position, coveredGridUnits_rel, lengthOfEachGridLine_rel, linesWidth_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void YGridLines(Vector3 positionAroundWhichToDraw, float coveredGridUnits_rel = 10.0f, float lengthOfEachGridLine_rel = 10.0f, float linesWidth_signFlipsPerp = 0.0f, YGridLinesOrientation orientation = YGridLinesOrientation.alongX, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridLines(positionAroundWhichToDraw, coveredGridUnits_rel, lengthOfEachGridLine_rel, linesWidth_signFlipsPerp, false, true, false, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, XGridLinesOrientation.alongZ, orientation, ZGridLinesOrientation.alongX); + } + public static void ZGridLines(Transform transformAroundWhichToDraw, float coveredGridUnits_rel = 10.0f, float lengthOfEachGridLine_rel = 10.0f, float linesWidth_signFlipsPerp = 0.0f, ZGridLinesOrientation orientation = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transformAroundWhichToDraw, "transformAroundWhichToDraw")) { return; } + ZGridLines(transformAroundWhichToDraw.position, coveredGridUnits_rel, lengthOfEachGridLine_rel, linesWidth_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void ZGridLines(Vector3 positionAroundWhichToDraw, float coveredGridUnits_rel = 10.0f, float lengthOfEachGridLine_rel = 10.0f, float linesWidth_signFlipsPerp = 0.0f, ZGridLinesOrientation orientation = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridLines(positionAroundWhichToDraw, coveredGridUnits_rel, lengthOfEachGridLine_rel, linesWidth_signFlipsPerp, false, false, true, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, XGridLinesOrientation.alongZ, YGridLinesOrientation.alongZ, orientation); + } + + public static void GridLinesLocal(Transform childTransformAroundWhichToDrawGridOfParent, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, XGridLinesOrientation orientation_ofXLines = XGridLinesOrientation.alongY, YGridLinesOrientation orientation_ofYLines = YGridLinesOrientation.alongX, ZGridLinesOrientation orientation_ofZLines = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDrawGridOfParent, "childTransformAroundWhichToDrawGridOfParent")) { return; } + if (childTransformAroundWhichToDrawGridOfParent.parent == null) + { + GridLinesLocal(Vector3.zero, Vector3.one, Quaternion.identity, childTransformAroundWhichToDrawGridOfParent.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + else + { + GridLinesLocal(childTransformAroundWhichToDrawGridOfParent.parent.position, childTransformAroundWhichToDrawGridOfParent.parent.lossyScale, childTransformAroundWhichToDrawGridOfParent.parent.rotation, childTransformAroundWhichToDrawGridOfParent.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + } + + public static void GridLinesLocal(Transform parentTransformThatDefinesTheLocalSpace, Vector3 localPositionAroundWhichToDraw, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, XGridLinesOrientation orientation_ofXLines = XGridLinesOrientation.alongY, YGridLinesOrientation orientation_ofYLines = YGridLinesOrientation.alongX, ZGridLinesOrientation orientation_ofZLines = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransformThatDefinesTheLocalSpace == null) + { + UtilitiesDXXL_Grid.GridLinesLocal(Vector3.zero, Vector3.one, Quaternion.identity, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, true, true, true, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + else + { + UtilitiesDXXL_Grid.GridLinesLocal(parentTransformThatDefinesTheLocalSpace.position, parentTransformThatDefinesTheLocalSpace.lossyScale, parentTransformThatDefinesTheLocalSpace.rotation, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, true, true, true, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + + public static void XGridLinesLocal(Transform childTransformAroundWhichToDrawGridOfParent, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, XGridLinesOrientation orientation = XGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDrawGridOfParent, "childTransformAroundWhichToDrawGridOfParent")) { return; } + if (childTransformAroundWhichToDrawGridOfParent.parent == null) + { + XGridLinesLocal(Vector3.zero, Vector3.one, Quaternion.identity, childTransformAroundWhichToDrawGridOfParent.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + else + { + XGridLinesLocal(childTransformAroundWhichToDrawGridOfParent.parent.position, childTransformAroundWhichToDrawGridOfParent.parent.lossyScale, childTransformAroundWhichToDrawGridOfParent.parent.rotation, childTransformAroundWhichToDrawGridOfParent.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + } + + public static void XGridLinesLocal(Transform parentTransformThatDefinesTheLocalSpace, Vector3 localPositionAroundWhichToDraw, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, XGridLinesOrientation orientation = XGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransformThatDefinesTheLocalSpace == null) + { + UtilitiesDXXL_Grid.GridLinesLocal(Vector3.zero, Vector3.one, Quaternion.identity, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, true, false, false, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, orientation, YGridLinesOrientation.alongX, ZGridLinesOrientation.alongX); + } + else + { + UtilitiesDXXL_Grid.GridLinesLocal(parentTransformThatDefinesTheLocalSpace.position, parentTransformThatDefinesTheLocalSpace.lossyScale, parentTransformThatDefinesTheLocalSpace.rotation, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, true, false, false, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, orientation, YGridLinesOrientation.alongX, ZGridLinesOrientation.alongX); + } + } + + public static void YGridLinesLocal(Transform childTransformAroundWhichToDrawGridOfParent, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, YGridLinesOrientation orientation = YGridLinesOrientation.alongX, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDrawGridOfParent, "childTransformAroundWhichToDrawGridOfParent")) { return; } + if (childTransformAroundWhichToDrawGridOfParent.parent == null) + { + YGridLinesLocal(Vector3.zero, Vector3.one, Quaternion.identity, childTransformAroundWhichToDrawGridOfParent.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + else + { + YGridLinesLocal(childTransformAroundWhichToDrawGridOfParent.parent.position, childTransformAroundWhichToDrawGridOfParent.parent.lossyScale, childTransformAroundWhichToDrawGridOfParent.parent.rotation, childTransformAroundWhichToDrawGridOfParent.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + } + + public static void YGridLinesLocal(Transform parentTransformThatDefinesTheLocalSpace, Vector3 localPositionAroundWhichToDraw, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, YGridLinesOrientation orientation = YGridLinesOrientation.alongX, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransformThatDefinesTheLocalSpace == null) + { + UtilitiesDXXL_Grid.GridLinesLocal(Vector3.zero, Vector3.one, Quaternion.identity, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, true, false, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, XGridLinesOrientation.alongZ, orientation, ZGridLinesOrientation.alongX); + } + else + { + UtilitiesDXXL_Grid.GridLinesLocal(parentTransformThatDefinesTheLocalSpace.position, parentTransformThatDefinesTheLocalSpace.lossyScale, parentTransformThatDefinesTheLocalSpace.rotation, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, true, false, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, XGridLinesOrientation.alongZ, orientation, ZGridLinesOrientation.alongX); + } + } + + public static void ZGridLinesLocal(Transform childTransformAroundWhichToDrawGridOfParent, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, ZGridLinesOrientation orientation = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDrawGridOfParent, "childTransformAroundWhichToDrawGridOfParent")) { return; } + if (childTransformAroundWhichToDrawGridOfParent.parent == null) + { + ZGridLinesLocal(Vector3.zero, Vector3.one, Quaternion.identity, childTransformAroundWhichToDrawGridOfParent.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + else + { + ZGridLinesLocal(childTransformAroundWhichToDrawGridOfParent.parent.position, childTransformAroundWhichToDrawGridOfParent.parent.lossyScale, childTransformAroundWhichToDrawGridOfParent.parent.rotation, childTransformAroundWhichToDrawGridOfParent.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + } + + public static void ZGridLinesLocal(Transform parentTransformThatDefinesTheLocalSpace, Vector3 localPositionAroundWhichToDraw, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, ZGridLinesOrientation orientation = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (parentTransformThatDefinesTheLocalSpace == null) + { + UtilitiesDXXL_Grid.GridLinesLocal(Vector3.zero, Vector3.one, Quaternion.identity, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, false, true, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, XGridLinesOrientation.alongZ, YGridLinesOrientation.alongZ, orientation); + } + else + { + UtilitiesDXXL_Grid.GridLinesLocal(parentTransformThatDefinesTheLocalSpace.position, parentTransformThatDefinesTheLocalSpace.lossyScale, parentTransformThatDefinesTheLocalSpace.rotation, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, false, true, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, XGridLinesOrientation.alongZ, YGridLinesOrientation.alongZ, orientation); + } + } + + public static void GridLinesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Transform childTransformAroundWhichToDraw, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, XGridLinesOrientation orientation_ofXLines = XGridLinesOrientation.alongY, YGridLinesOrientation orientation_ofYLines = YGridLinesOrientation.alongX, ZGridLinesOrientation orientation_ofZLines = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDraw, "childTransformAroundWhichToDraw")) { return; } + GridLinesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, childTransformAroundWhichToDraw.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects); + } + + public static void GridLinesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 localPositionAroundWhichToDraw = default(Vector3), float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, XGridLinesOrientation orientation_ofXLines = XGridLinesOrientation.alongY, YGridLinesOrientation orientation_ofYLines = YGridLinesOrientation.alongX, ZGridLinesOrientation orientation_ofZLines = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColorForX = default(Color), Color overwriteColorForY = default(Color), Color overwriteColorForZ = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridLinesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, true, true, true, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColorForX, overwriteColorForY, overwriteColorForZ, durationInSec, hiddenByNearerObjects, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + + public static void XGridLinesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Transform childTransformAroundWhichToDraw, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, XGridLinesOrientation orientation = XGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDraw, "childTransformAroundWhichToDraw")) { return; } + XGridLinesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, childTransformAroundWhichToDraw.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + + public static void XGridLinesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 localPositionAroundWhichToDraw = default(Vector3), float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, XGridLinesOrientation orientation = XGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridLinesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, true, false, false, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, orientation, YGridLinesOrientation.alongX, ZGridLinesOrientation.alongX); + } + + public static void YGridLinesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Transform childTransformAroundWhichToDraw, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, YGridLinesOrientation orientation = YGridLinesOrientation.alongX, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDraw, "childTransformAroundWhichToDraw")) { return; } + YGridLinesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, childTransformAroundWhichToDraw.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void YGridLinesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 localPositionAroundWhichToDraw = default(Vector3), float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, YGridLinesOrientation orientation = YGridLinesOrientation.alongX, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridLinesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, true, false, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, XGridLinesOrientation.alongZ, orientation, ZGridLinesOrientation.alongX); + } + + public static void ZGridLinesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Transform childTransformAroundWhichToDraw, float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, ZGridLinesOrientation orientation = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(childTransformAroundWhichToDraw, "childTransformAroundWhichToDraw")) { return; } + ZGridLinesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, childTransformAroundWhichToDraw.localPosition, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, orientation, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, durationInSec, hiddenByNearerObjects); + } + + public static void ZGridLinesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 localPositionAroundWhichToDraw = default(Vector3), float coveredGridUnits_rel_inLocalSpaceUnits = 10.0f, float lengthOfEachGridLine_rel_inLocalSpaceUnits = 10.0f, float linesWidth_inLocalSpaceUnits_signFlipsPerp = 0.0f, ZGridLinesOrientation orientation = ZGridLinesOrientation.alongY, bool draw1000grid = false, bool draw100grid = false, bool draw10grid = false, bool draw1grid = true, bool draw0p1grid = true, bool draw0p01grid = false, bool draw0p001grid = false, float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f, Color overwriteColor = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Grid.GridLinesLocal(originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, localPositionAroundWhichToDraw, coveredGridUnits_rel_inLocalSpaceUnits, lengthOfEachGridLine_rel_inLocalSpaceUnits, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, false, true, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, distanceBetweenRepeatingCoordsTexts_relToGridDistance, overwriteColor, overwriteColor, overwriteColor, durationInSec, hiddenByNearerObjects, XGridLinesOrientation.alongZ, YGridLinesOrientation.alongZ, orientation); + } + + public enum GridScreenspaceMode + { + warpWidthAndHeightIndividuallyToFitScreenInBothAxes, + screenHeightDefinesSquareBoxes_alignLeft, + screenHeightDefinesSquareBoxes_alignRight, + screenWidthDefinesSquareBoxes_alignAtBottom, + screenWidthDefinesSquareBoxes_alignAtTop, + } + + public static void GridScreenspace(Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, bool drawTenthLines = true, bool drawHundredthLines = true, GridScreenspaceMode gridScreenspaceMode = GridScreenspaceMode.warpWidthAndHeightIndividuallyToFitScreenInBothAxes, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawEngineBasics.GridScreenspace") == false) { return; } + GridScreenspace(automaticallyFoundCamera, color, linesWidth_relToViewportHeight, drawTenthLines, drawHundredthLines, gridScreenspaceMode, durationInSec); + } + + public static void GridScreenspace(Camera camera, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, bool drawTenthLines = true, bool drawHundredthLines = true, GridScreenspaceMode gridScreenspaceMode = GridScreenspaceMode.warpWidthAndHeightIndividuallyToFitScreenInBothAxes, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(camera)) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_GridScreenspace.Add(new GridScreenspace(camera, color, linesWidth_relToViewportHeight, drawTenthLines, drawHundredthLines, gridScreenspaceMode, durationInSec)); + return; + } + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + Color colorFor01 = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.5f); + Color colorFor001 = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.15f); + float usedAspectCorrectionFactor_toMakeBoxesSquare; + + switch (gridScreenspaceMode) + { + case GridScreenspaceMode.warpWidthAndHeightIndividuallyToFitScreenInBothAxes: + DrawMainScreenspaceGridLines(camera, 1.0f, 1.0f, false, false, color, linesWidth_relToViewportHeight, durationInSec); + DrawConfigurableScreenspaceGrid(camera, drawTenthLines, 10, 1.0f, 1.0f, false, false, colorFor01, durationInSec); + DrawConfigurableScreenspaceGrid(camera, drawHundredthLines, 100, 1.0f, 1.0f, false, false, colorFor001, durationInSec); + break; + case GridScreenspaceMode.screenHeightDefinesSquareBoxes_alignLeft: + usedAspectCorrectionFactor_toMakeBoxesSquare = 1.0f / camera.aspect; + DrawMainScreenspaceGridLines(camera, 1.0f, usedAspectCorrectionFactor_toMakeBoxesSquare, false, false, color, linesWidth_relToViewportHeight, durationInSec); + DrawConfigurableScreenspaceGrid(camera, drawTenthLines, 10, 1.0f, usedAspectCorrectionFactor_toMakeBoxesSquare, false, false, colorFor01, durationInSec); + DrawConfigurableScreenspaceGrid(camera, drawHundredthLines, 100, 1.0f, usedAspectCorrectionFactor_toMakeBoxesSquare, false, false, colorFor001, durationInSec); + break; + case GridScreenspaceMode.screenHeightDefinesSquareBoxes_alignRight: + usedAspectCorrectionFactor_toMakeBoxesSquare = 1.0f / camera.aspect; + DrawMainScreenspaceGridLines(camera, 1.0f, usedAspectCorrectionFactor_toMakeBoxesSquare, true, false, color, linesWidth_relToViewportHeight, durationInSec); + DrawConfigurableScreenspaceGrid(camera, drawTenthLines, 10, 1.0f, usedAspectCorrectionFactor_toMakeBoxesSquare, true, false, colorFor01, durationInSec); + DrawConfigurableScreenspaceGrid(camera, drawHundredthLines, 100, 1.0f, usedAspectCorrectionFactor_toMakeBoxesSquare, true, false, colorFor001, durationInSec); + break; + case GridScreenspaceMode.screenWidthDefinesSquareBoxes_alignAtBottom: + usedAspectCorrectionFactor_toMakeBoxesSquare = camera.aspect; + DrawMainScreenspaceGridLines(camera, usedAspectCorrectionFactor_toMakeBoxesSquare, 1.0f, false, false, color, linesWidth_relToViewportHeight, durationInSec); + DrawConfigurableScreenspaceGrid(camera, drawTenthLines, 10, usedAspectCorrectionFactor_toMakeBoxesSquare, 1.0f, false, false, colorFor01, durationInSec); + DrawConfigurableScreenspaceGrid(camera, drawHundredthLines, 100, usedAspectCorrectionFactor_toMakeBoxesSquare, 1.0f, false, false, colorFor001, durationInSec); + break; + case GridScreenspaceMode.screenWidthDefinesSquareBoxes_alignAtTop: + usedAspectCorrectionFactor_toMakeBoxesSquare = camera.aspect; + DrawMainScreenspaceGridLines(camera, usedAspectCorrectionFactor_toMakeBoxesSquare, 1.0f, false, true, color, linesWidth_relToViewportHeight, durationInSec); + DrawConfigurableScreenspaceGrid(camera, drawTenthLines, 10, usedAspectCorrectionFactor_toMakeBoxesSquare, 1.0f, false, true, colorFor01, durationInSec); + DrawConfigurableScreenspaceGrid(camera, drawHundredthLines, 100, usedAspectCorrectionFactor_toMakeBoxesSquare, 1.0f, false, true, colorFor001, durationInSec); + break; + default: + break; + } + + } + + static void DrawMainScreenspaceGridLines(Camera camera, float scaleFactor_forHorizLines, float scaleFactor_forVertLines, bool startAtRightBorder_insteadOfLeft, bool startAtTopBorder_insteadOfBottom, Color color, float linesWidth_relToViewportHeight, float durationInSec) + { + //horiz lines: + if (startAtTopBorder_insteadOfBottom) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.0f, 1.0f), new Vector2(1.0f, 1.0f), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.0f, 1.0f - (0.5f * scaleFactor_forHorizLines)), new Vector2(1.0f, 1.0f - (0.5f * scaleFactor_forHorizLines)), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.0f, 1.0f - (1.0f * scaleFactor_forHorizLines)), new Vector2(1.0f, 1.0f - (1.0f * scaleFactor_forHorizLines)), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + } + else + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.0f, 0.5f * scaleFactor_forHorizLines), new Vector2(1.0f, 0.5f * scaleFactor_forHorizLines), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.0f, 1.0f * scaleFactor_forHorizLines), new Vector2(1.0f, 1.0f * scaleFactor_forHorizLines), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + } + + //vert lines: + if (startAtRightBorder_insteadOfLeft) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(1.0f, 0.0f), new Vector2(1.0f, 1.0f), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(1.0f - (0.5f * scaleFactor_forVertLines), 0.0f), new Vector2(1.0f - (0.5f * scaleFactor_forVertLines), 1.0f), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(1.0f - (1.0f * scaleFactor_forVertLines), 0.0f), new Vector2(1.0f - (1.0f * scaleFactor_forVertLines), 1.0f), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + } + else + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.0f, 0.0f), new Vector2(0.0f, 1.0f), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.5f * scaleFactor_forVertLines, 0.0f), new Vector2(0.5f * scaleFactor_forVertLines, 1.0f), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(1.0f * scaleFactor_forVertLines, 0.0f), new Vector2(1.0f * scaleFactor_forVertLines, 1.0f), color, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + } + } + + static void DrawConfigurableScreenspaceGrid(Camera camera, bool drawThis, int numberOfLines, float scaleFactor_forHorizLines, float scaleFactor_forVertLines, bool startAtRightBorder_insteadOfLeft, bool startAtTopBorder_insteadOfBottom, Color color, float durationInSec) + { + if (drawThis) + { + float progress0to1_perLine = 1.0f / (float)numberOfLines; + + //horiz lines: + float progress0to1_perLine_forHorizLines = progress0to1_perLine * scaleFactor_forHorizLines; + + int numberOfHorizLines_minus1_overshootingToFillWholeScreen; + if (UtilitiesDXXL_Math.ApproximatelyZero(scaleFactor_forHorizLines)) + { + numberOfHorizLines_minus1_overshootingToFillWholeScreen = numberOfLines - 1; //-> "minus 1" is for not overdrawing the mainLine once more to not alter mainLines alpha value + } + else + { + numberOfHorizLines_minus1_overshootingToFillWholeScreen = Mathf.RoundToInt((float)numberOfLines / scaleFactor_forHorizLines); + } + + for (int i = 1; i <= numberOfHorizLines_minus1_overshootingToFillWholeScreen; i++) + { + float progress0to1_forHorizLines = progress0to1_perLine_forHorizLines * i; + if (startAtTopBorder_insteadOfBottom) { progress0to1_forHorizLines = 1.0f - progress0to1_forHorizLines; } + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.0f, progress0to1_forHorizLines), new Vector2(1.0f, progress0to1_forHorizLines), color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + } + + //vert lines: + float progress0to1_perLine_forVertLines = progress0to1_perLine * scaleFactor_forVertLines; + + int numberOfVertLines_minus1_overshootingToFillWholeScreen; + if (UtilitiesDXXL_Math.ApproximatelyZero(scaleFactor_forVertLines)) + { + numberOfVertLines_minus1_overshootingToFillWholeScreen = numberOfLines - 1; //-> "minus 1" is for not overdrawing the mainLine once more to not alter mainLines alpha value + } + else + { + numberOfVertLines_minus1_overshootingToFillWholeScreen = Mathf.RoundToInt((float)numberOfLines / scaleFactor_forVertLines); + } + + for (int i = 1; i <= numberOfVertLines_minus1_overshootingToFillWholeScreen; i++) + { + float progress0to1_forVertLines = progress0to1_perLine_forVertLines * i; + if (startAtRightBorder_insteadOfLeft) { progress0to1_forVertLines = 1.0f - progress0to1_forVertLines; } + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(progress0to1_forVertLines, 0.0f), new Vector2(progress0to1_forVertLines, 1.0f), color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + } + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/DrawEngineBasics.cs.meta b/Runtime/DrawDebugLibrary/DrawEngineBasics.cs.meta new file mode 100644 index 0000000..e897ab1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawEngineBasics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec28ea9811a12d945a4060291021fbe6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawLogs.cs b/Runtime/DrawDebugLibrary/DrawLogs.cs new file mode 100644 index 0000000..6d52880 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawLogs.cs @@ -0,0 +1,959 @@ +namespace DrawXXL +{ + using System; + using System.Diagnostics; + using UnityEngine; + using System.Collections.Generic; + + public class DrawLogs + { + public static bool autoMarkupLogTextWithGameobjectColor_forConsole = false; + public static bool autoMarkupLogTextWithGameobjectColor_forDrawingInScene = false; + public static bool autoMarkupLogTextWithGameobjectColor_forDrawingInScrenspace = false; + public static float forceLuminance_ofAutoMarkupColors = 0.0f; + + [Conditional("UNITY_ASSERTIONS")] + public static void Assert(bool condition, string message, GameObject context) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(message, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.Assert(condition, message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.Assert(condition, message, context); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + if (condition == false) + { + NoteLogMessageForDrawingAtGameObjects(LogType.Assert, context, message); + } + } + + [Conditional("UNITY_ASSERTIONS")] + public static void Assert(bool condition) + { + UnityEngine.Debug.Assert(condition); + } + + [Conditional("UNITY_ASSERTIONS")] + public static void Assert(bool condition, object message, GameObject context) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string message_asString = GetStringFromObject(message); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(message_asString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.Assert(condition, message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.Assert(condition, message, context); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + if (condition == false) + { + NoteLogMessageForDrawingAtGameObjects(LogType.Assert, context, message); + } + } + + [Conditional("UNITY_ASSERTIONS")] + public static void Assert(bool condition, string message) + { + UnityEngine.Debug.Assert(condition, message); + } + + [Conditional("UNITY_ASSERTIONS")] + public static void Assert(bool condition, object message) + { + UnityEngine.Debug.Assert(condition, message); + } + + [Conditional("UNITY_ASSERTIONS")] + public static void Assert(bool condition, GameObject context) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(assertionFailedString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.Assert(condition, message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.Assert(condition, context); + } + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + if (condition == false) + { + NoteLogMessageForDrawingAtGameObjects(LogType.Assert, context); + } + } + + [Conditional("UNITY_ASSERTIONS")] + public static void AssertFormat(bool condition, GameObject context, string format, params object[] args) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string messageAsString = GetStringFromFormatAndArgs(format, args); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(messageAsString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.Assert(condition, message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.AssertFormat(condition, context, format, args); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + if (condition == false) + { + NoteLogMessageForDrawingAtGameObjects(LogType.Assert, context, format, args); + } + } + + [Conditional("UNITY_ASSERTIONS")] + public static void AssertFormat(bool condition, string format, params object[] args) + { + UnityEngine.Debug.AssertFormat(condition, format, args); + } + + public static void Log(object message) + { + UnityEngine.Debug.Log(message); + } + + public static void Log(object message, GameObject context) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string message_asString = GetStringFromObject(message); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(message_asString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.Log(message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.Log(message, context); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + NoteLogMessageForDrawingAtGameObjects(LogType.Log, context, message); + } + + [Conditional("UNITY_ASSERTIONS")] + public static void LogAssertion(object message, GameObject context) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string message_asString = GetStringFromObject(message); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(message_asString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.LogAssertion(message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.LogAssertion(message, context); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + NoteLogMessageForDrawingAtGameObjects(LogType.Assert, context, message); + } + + [Conditional("UNITY_ASSERTIONS")] + public static void LogAssertion(object message) + { + UnityEngine.Debug.LogAssertion(message); + } + + [Conditional("UNITY_ASSERTIONS")] + public static void LogAssertionFormat(GameObject context, string format, params object[] args) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string messageAsString = GetStringFromFormatAndArgs(format, args); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(messageAsString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.LogAssertion(message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.LogAssertionFormat(context, format, args); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + NoteLogMessageForDrawingAtGameObjects(LogType.Assert, context, format, args); + } + + [Conditional("UNITY_ASSERTIONS")] + public static void LogAssertionFormat(string format, params object[] args) + { + UnityEngine.Debug.LogAssertionFormat(format, args); + } + + public static void LogError(object message, GameObject context) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string message_asString = GetStringFromObject(message); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(message_asString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.LogError(message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.LogError(message, context); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + NoteLogMessageForDrawingAtGameObjects(LogType.Error, context, message); + } + + public static void LogError(object message) + { + UnityEngine.Debug.LogError(message); + } + + public static void LogErrorFormat(GameObject context, string format, params object[] args) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string messageAsString = GetStringFromFormatAndArgs(format, args); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(messageAsString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.LogError(message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.LogErrorFormat(context, format, args); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + NoteLogMessageForDrawingAtGameObjects(LogType.Error, context, format, args); + } + + public static void LogErrorFormat(string format, params object[] args) + { + UnityEngine.Debug.LogErrorFormat(format, args); + } + + public static void LogException(System.Exception exception) + { + UnityEngine.Debug.LogException(exception); + } + + public static void LogException(System.Exception exception, GameObject context) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string messageAsString = GetStringFromException(exception); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(messageAsString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.LogError(message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.LogException(exception, context); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + NoteLogMessageForDrawingAtGameObjects(LogType.Exception, context, exception); + } + + public static void LogFormat(string format, params object[] args) + { + UnityEngine.Debug.LogFormat(format, args); + } + + public static void LogFormat(GameObject context, string format, params object[] args) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string messageAsString = GetStringFromFormatAndArgs(format, args); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(messageAsString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.Log(message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.LogFormat(context, format, args); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + NoteLogMessageForDrawingAtGameObjects(LogType.Log, context, format, args); + } + + public static void LogFormat(LogType logType, LogOption logOptions, GameObject context, string format, params object[] args) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string format_withColorMarkup = DrawText.MarkupColorFromGameobjectID(format, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.LogFormat(logType, logOptions, context, format_withColorMarkup, args); + } + else + { + UnityEngine.Debug.LogFormat(logType, logOptions, context, format, args); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + NoteLogMessageForDrawingAtGameObjects(logType, context, format, args); + } + + public static void LogWarning(object message, GameObject context) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string message_asString = GetStringFromObject(message); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(message_asString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.LogWarning(message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.LogWarning(message, context); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + NoteLogMessageForDrawingAtGameObjects(LogType.Warning, context, message); + } + + public static void LogWarning(object message) + { + UnityEngine.Debug.LogWarning(message); + } + + public static void LogWarningFormat(GameObject context, string format, params object[] args) + { + if (autoMarkupLogTextWithGameobjectColor_forConsole) + { + string messageAsString = GetStringFromFormatAndArgs(format, args); + string message_asString_withColorMarkup = DrawText.MarkupColorFromGameobjectID(messageAsString, context, forceLuminance_ofAutoMarkupColors); + UnityEngine.Debug.LogWarning(message_asString_withColorMarkup, context); + } + else + { + UnityEngine.Debug.LogWarningFormat(context, format, args); + } + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + NoteLogMessageForDrawingAtGameObjects(LogType.Warning, context, format, args); + } + + public static void LogWarningFormat(string format, params object[] args) + { + UnityEngine.Debug.LogWarningFormat(format, args); + } + + static void NoteLogMessageForDrawingAtGameObjects(LogType logType, GameObject gameObject_toWhichLogMessageBelongs, object message) + { + string messageString = GetStringFromObject(message, ref logType); + NoteLogMessageForDrawingAtGameObjects(logType, gameObject_toWhichLogMessageBelongs, messageString); + } + + static string GetStringFromObject(object message) + { + LogType dummyLogType = default; + return GetStringFromObject(message, ref dummyLogType); + } + + static string GetStringFromObject(object message, ref LogType logType) + { + if (message == null) + { + return "null"; + } + else + { + string messageString; + try + { + messageString = message.ToString(); + } + catch (Exception exception) + { + try + { + messageString = "[" + DrawText.MarkupLogSymbol(logType) + " -> " + DrawText.MarkupLogSymbol(LogType.Exception) + "] Converting message object to string threw an exception: " + exception.GetType() + ": " + exception.Message; + } + catch + { + messageString = "Converting message object to string threw an exception, and parsing this exception to string again threw another exception."; + } + logType = LogType.Exception; + } + return messageString; + } + } + + static string assertionFailedString = "Assertion failed"; + static void NoteLogMessageForDrawingAtGameObjects(LogType logType, GameObject gameObject_toWhichLogMessageBelongs) + { + NoteLogMessageForDrawingAtGameObjects(logType, gameObject_toWhichLogMessageBelongs, assertionFailedString); + } + + static void NoteLogMessageForDrawingAtGameObjects(LogType logType, GameObject gameObject_toWhichLogMessageBelongs, string format, params object[] args) + { + string messageString = GetStringFromFormatAndArgs(ref logType, format, args); + NoteLogMessageForDrawingAtGameObjects(logType, gameObject_toWhichLogMessageBelongs, messageString); + } + + static string GetStringFromFormatAndArgs(string format, params object[] args) + { + LogType dummyLogType = default; + return GetStringFromFormatAndArgs(ref dummyLogType, format, args); + } + + static string GetStringFromFormatAndArgs(ref LogType logType, string format, params object[] args) + { + if (format == null) + { + return "null"; + } + else + { + string messageString; + try + { + messageString = String.Format(format, args); + } + catch (Exception exception) + { + try + { + messageString = "[" + DrawText.MarkupLogSymbol(logType) + " -> " + DrawText.MarkupLogSymbol(LogType.Exception) + "] Formatting the logString threw an exception: " + exception.GetType() + ": " + exception.Message; + } + catch + { + messageString = "Formatting the logString threw an exception, and parsing this exception to string again threw another exception."; + } + logType = LogType.Exception; + } + return messageString; + } + } + + static void NoteLogMessageForDrawingAtGameObjects(LogType logType, GameObject gameObject_toWhichLogMessageBelongs, System.Exception exception) + { + string message = GetStringFromException(exception); + NoteLogMessageForDrawingAtGameObjects(logType, gameObject_toWhichLogMessageBelongs, message, exception.StackTrace); + } + + static string GetStringFromException(System.Exception exception) + { + string message; + try + { + message = "" + exception.GetType() + ": " + exception.Message; + } + catch (Exception) + { + message = "LogException, that failed to parse to string."; + } + return message; + } + + static void NoteLogMessageForDrawingAtGameObjects(LogType logType, GameObject gameObject_toWhichLogMessageBelongs, string message, string stackTrace = null) + { + if (gameObject_toWhichLogMessageBelongs != null) + { + if (message != null) + { + InternalDXXL_LogMessageForDrawing receivedLogMessage = new InternalDXXL_LogMessageForDrawing(); + receivedLogMessage.logString = message; + receivedLogMessage.stackTrace = stackTrace; + receivedLogMessage.logType = logType; + receivedLogMessage.gameObjectsInstanceID = gameObject_toWhichLogMessageBelongs.GetInstanceID(); + logMessagesForDrawAtGameObjects.Add(receivedLogMessage); + } + } + } + + public static void LogsAtGameObject(GameObject gameObject, bool drawNormalPrio = true, bool drawWarningPrio = true, bool drawErrorPrio = true, int maxNumberOfDisplayedLogMessages = 10, float textSize = 0.2f, Color textColor = default(Color), Color boxColor = default(Color), float width_ofBoxLines = 0.0f, bool drawnBoxEncapsulatesChildren = true, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //if you supply a different "maxNumberOfDisplayedLogMessages" or "draw*Prio" during runtime: Then this comes into effect not immediately, but after a delay, namely when a new log message gets noted. Reason: optimization of GC allocations. + //the same goes if you change during runtime between "LogsAtGameObject" and "LogsAtGameObjectScreenSpace" + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject, "gameObject")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(textSize, "textSize")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_ofBoxLines, "width_ofBoxLines")) { return; } + + if (maxNumberOfDisplayedLogMessages > maxMaxNumberOfNumberOfLogDisplayerLogMessages) + { + UnityEngine.Debug.Log("The maximum allowed value for 'maxNumberOfDisplayedLogMessages' is " + maxMaxNumberOfNumberOfLogDisplayerLogMessages + " -> Auto-force from " + maxNumberOfDisplayedLogMessages + " to " + maxMaxNumberOfNumberOfLogDisplayerLogMessages + ""); + maxNumberOfDisplayedLogMessages = maxMaxNumberOfNumberOfLogDisplayerLogMessages; + } + + textColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(textColor); + if (autoMarkupLogTextWithGameobjectColor_forDrawingInScene) { textColor = SeededColorGenerator.ColorOfGameobjectID(gameObject, forceLuminance_ofAutoMarkupColors); } + string logsAsTextWall = GetStringWithXNewestLogsForGameObject(gameObject, maxNumberOfDisplayedLogMessages, drawNormalPrio, drawWarningPrio, drawErrorPrio); + DrawEngineBasics.TagGameObject(gameObject, logsAsTextWall, textColor, boxColor, textSize, width_ofBoxLines, drawnBoxEncapsulatesChildren, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + public static void LogsAtGameObjectScreenspace(GameObject gameObject, bool drawNormalPrio = true, bool drawWarningPrio = true, bool drawErrorPrio = true, bool clampIntoScreen = true, int maxNumberOfDisplayedLogMessages = 10, float relTextSizeScaling = 1.0f, Color textColor = default(Color), Color boxColor = default(Color), float widthOfBoxLines_relToViewportHeight = 0.0f, bool drawnBoxEncapsulatesChildren = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawLogs.LogsAtGameObjectScreenspace") == false) { return; } + LogsAtGameObjectScreenspace(automaticallyFoundCamera, gameObject, drawNormalPrio, drawWarningPrio, drawErrorPrio, clampIntoScreen, maxNumberOfDisplayedLogMessages, relTextSizeScaling, textColor, boxColor, widthOfBoxLines_relToViewportHeight, drawnBoxEncapsulatesChildren, durationInSec); + } + + public static void LogsAtGameObjectScreenspace(Camera cameraWhereToDraw, GameObject gameObject, bool drawNormalPrio = true, bool drawWarningPrio = true, bool drawErrorPrio = true, bool clampIntoScreen = true, int maxNumberOfDisplayedLogMessages = 10, float relTextSizeScaling = 1.0f, Color textColor = default(Color), Color boxColor = default(Color), float widthOfBoxLines_relToViewportHeight = 0.0f, bool drawnBoxEncapsulatesChildren = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(cameraWhereToDraw, "cameraWhereToDraw")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject, "gameObject")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(widthOfBoxLines_relToViewportHeight, "widthOfBoxLines_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(relTextSizeScaling, "relTextSizeScaling")) { return; } + + if (maxNumberOfDisplayedLogMessages > maxMaxNumberOfNumberOfLogDisplayerLogMessages) + { + UnityEngine.Debug.Log("The maximum allowed value for 'maxNumberOfDisplayedLogMessages' is " + maxMaxNumberOfNumberOfLogDisplayerLogMessages + " -> Auto-force from " + maxNumberOfDisplayedLogMessages + " to " + maxMaxNumberOfNumberOfLogDisplayerLogMessages + ""); + maxNumberOfDisplayedLogMessages = maxMaxNumberOfNumberOfLogDisplayerLogMessages; + } + + textColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(textColor); + if (autoMarkupLogTextWithGameobjectColor_forDrawingInScrenspace) { textColor = SeededColorGenerator.ColorOfGameobjectID(gameObject, forceLuminance_ofAutoMarkupColors); } + string logsAsTextWall = GetStringWithXNewestLogsForGameObject(gameObject, maxNumberOfDisplayedLogMessages, drawNormalPrio, drawWarningPrio, drawErrorPrio); + DrawEngineBasics.TagGameObjectScreenspace(cameraWhereToDraw, gameObject, logsAsTextWall, textColor, boxColor, widthOfBoxLines_relToViewportHeight, clampIntoScreen, 0.6f * relTextSizeScaling, drawnBoxEncapsulatesChildren, durationInSec); + } + + public static void LogsOnScreen(bool drawNormalPrio = true, bool drawWarningPrio = true, bool drawErrorPrio = true, int maxNumberOfDisplayedLogMessages = 10, float textSize_relToViewportHeight = 0.014f, Color textColor = default(Color), bool stackTraceForNormalPrio = false, bool stackTraceForWarningPrio = false, bool stackTraceForErrorPrio = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawLogs.LogsOnScreen") == false) { return; } + LogsOnScreen(automaticallyFoundCamera, drawNormalPrio, drawWarningPrio, drawErrorPrio, maxNumberOfDisplayedLogMessages, textSize_relToViewportHeight, textColor, stackTraceForNormalPrio, stackTraceForWarningPrio, stackTraceForErrorPrio, durationInSec); + } + + public static void LogsOnScreen(Camera cameraWhereToDraw, bool drawNormalPrio = true, bool drawWarningPrio = true, bool drawErrorPrio = true, int maxNumberOfDisplayedLogMessages = 10, float textSize_relToViewportHeight = 0.014f, Color textColor = default(Color), bool stackTraceForNormalPrio = false, bool stackTraceForWarningPrio = false, bool stackTraceForErrorPrio = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(cameraWhereToDraw, "cameraWhereToDraw")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(textSize_relToViewportHeight, "textSize_relToViewportHeight")) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_LogsOnScreen.Add(new LogsOnScreen(cameraWhereToDraw, drawNormalPrio, drawWarningPrio, drawErrorPrio, maxNumberOfDisplayedLogMessages, textSize_relToViewportHeight, textColor, stackTraceForNormalPrio, stackTraceForWarningPrio, stackTraceForErrorPrio, durationInSec, logMessageListenerForLogsOnScreen_isActivated)); + return; + } + + if (maxNumberOfDisplayedLogMessages > maxMaxNumberOfNumberOfLogDisplayerLogMessages) + { + UnityEngine.Debug.Log("The maximum allowed value for 'maxNumberOfDisplayedLogMessages' is " + maxMaxNumberOfNumberOfLogDisplayerLogMessages + " -> Auto-force from " + maxNumberOfDisplayedLogMessages + " to " + maxMaxNumberOfNumberOfLogDisplayerLogMessages + ""); + maxNumberOfDisplayedLogMessages = maxMaxNumberOfNumberOfLogDisplayerLogMessages; + } + + textColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(textColor); + string logsAsTextWall = GetStringWithXNewestLogsForDrawOnScreen(maxNumberOfDisplayedLogMessages, drawNormalPrio, drawWarningPrio, drawErrorPrio, stackTraceForNormalPrio, stackTraceForWarningPrio, stackTraceForErrorPrio); + UtilitiesDXXL_Text.WriteScreenspace(cameraWhereToDraw, logsAsTextWall, new Vector2(textSize_relToViewportHeight, 0.0f), textColor, textSize_relToViewportHeight, 0.0f, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, false, durationInSec, false); + } + + static List logMessagesForDrawAtGameObjects = new List(); + static int maxMaxNumberOfNumberOfLogDisplayerLogMessages = 40; //has to be dividable by "4" //if value is raised: danger of performance issues/freezing + static int maxNumberOfBlocksOf4ConcattedStrings = Mathf.RoundToInt(0.25f * maxMaxNumberOfNumberOfLogDisplayerLogMessages); + static string[] blocksOf4ConcattedStrings_startingWithNewest = new string[maxNumberOfBlocksOf4ConcattedStrings]; + static int[] indexes_ofCurrLog_insideAllLogsList_startingWithNewest = new int[maxMaxNumberOfNumberOfLogDisplayerLogMessages]; + static string GetStringWithXNewestLogsForGameObject(GameObject gameObject, int maxNumberOfDisplayedLogMessages, bool getNormalPrio, bool getWarningPrio, bool getErrorPrio) + { + if (getNormalPrio == false && getWarningPrio == false && getErrorPrio == false) + { + return "(all logTypes are disabled)"; + } + + maxNumberOfDisplayedLogMessages = Mathf.Abs(maxNumberOfDisplayedLogMessages); + maxNumberOfDisplayedLogMessages = Mathf.Max(maxNumberOfDisplayedLogMessages, 1); + maxNumberOfDisplayedLogMessages = Mathf.Min(maxNumberOfDisplayedLogMessages, maxMaxNumberOfNumberOfLogDisplayerLogMessages); + + int gameObjectsInstanceId = gameObject.GetInstanceID(); + + int numberOfSavedRequestedTypesMessagesThatAreAttachedToGameObject = 0; + int numberOf_savedNormalLogMessagesThatAreAttachedToGameObject = 0; + int numberOf_savedWarningLogMessagesThatAreAttachedToGameObject = 0; + int numberOf_savedErrorLogMessagesThatAreAttachedToGameObject = 0; + for (int i = 0; i < logMessagesForDrawAtGameObjects.Count; i++) + { + if (gameObjectsInstanceId == logMessagesForDrawAtGameObjects[i].gameObjectsInstanceID) + { + if (logMessagesForDrawAtGameObjects[i].logType == LogType.Log) + { + numberOf_savedNormalLogMessagesThatAreAttachedToGameObject++; + if (getNormalPrio) + { + numberOfSavedRequestedTypesMessagesThatAreAttachedToGameObject++; + } + } + else + { + if (logMessagesForDrawAtGameObjects[i].logType == LogType.Warning) + { + numberOf_savedWarningLogMessagesThatAreAttachedToGameObject++; + if (getWarningPrio) + { + numberOfSavedRequestedTypesMessagesThatAreAttachedToGameObject++; + } + } + else + { + //"exception" and "assertion" count as "error": + numberOf_savedErrorLogMessagesThatAreAttachedToGameObject++; + if (getErrorPrio) + { + numberOfSavedRequestedTypesMessagesThatAreAttachedToGameObject++; + } + } + } + } + } + + if (numberOfSavedRequestedTypesMessagesThatAreAttachedToGameObject == 0) + { + return "(no log messages yet for the requested log types)"; + } + else + { + int numberOfMessagesInTextWall = FillGameObjectsConcerned_stringsWithLogSymbolStackTraceAndLineBreak(gameObjectsInstanceId, maxNumberOfDisplayedLogMessages, getNormalPrio, getWarningPrio, getErrorPrio); + return GetWholeLogTextWall(ref logMessagesForDrawAtGameObjects, numberOfSavedRequestedTypesMessagesThatAreAttachedToGameObject, numberOfMessagesInTextWall, numberOf_savedNormalLogMessagesThatAreAttachedToGameObject, numberOf_savedWarningLogMessagesThatAreAttachedToGameObject, numberOf_savedErrorLogMessagesThatAreAttachedToGameObject, getNormalPrio, getWarningPrio, getErrorPrio); + } + } + + static int FillGameObjectsConcerned_stringsWithLogSymbolStackTraceAndLineBreak(int gameObjectsInstanceId, int maxNumberOfDisplayedLogMessages, bool getNormalPrio, bool getWarningPrio, bool getErrorPrio) + { + int numberOfAlreadyRetrievedMessages = 0; + for (int i_logsOfAllGameObjects = logMessagesForDrawAtGameObjects.Count - 1; i_logsOfAllGameObjects >= 0; i_logsOfAllGameObjects--) + { + if (gameObjectsInstanceId == logMessagesForDrawAtGameObjects[i_logsOfAllGameObjects].gameObjectsInstanceID) + { + if (IsARequestedLogType(logMessagesForDrawAtGameObjects[i_logsOfAllGameObjects].logType, getNormalPrio, getWarningPrio, getErrorPrio)) + { + if (logMessagesForDrawAtGameObjects[i_logsOfAllGameObjects].stringWithLogSymbolStackTraceAndLineBreak == null) + { + logMessagesForDrawAtGameObjects[i_logsOfAllGameObjects].stringWithLogSymbolStackTraceAndLineBreak = DrawText.MarkupLogSymbol(logMessagesForDrawAtGameObjects[i_logsOfAllGameObjects].logType) + " " + logMessagesForDrawAtGameObjects[i_logsOfAllGameObjects].logString + "
"; + if (logMessagesForDrawAtGameObjects[i_logsOfAllGameObjects].stackTrace != null) + { + logMessagesForDrawAtGameObjects[i_logsOfAllGameObjects].stringWithLogSymbolStackTraceAndLineBreak = logMessagesForDrawAtGameObjects[i_logsOfAllGameObjects].stringWithLogSymbolStackTraceAndLineBreak + logMessagesForDrawAtGameObjects[i_logsOfAllGameObjects].stackTrace + "
"; + } + } + + indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyRetrievedMessages] = i_logsOfAllGameObjects; + numberOfAlreadyRetrievedMessages++; + } + } + if (numberOfAlreadyRetrievedMessages >= maxNumberOfDisplayedLogMessages) { break; } + } + return numberOfAlreadyRetrievedMessages; + } + + static bool IsARequestedLogType(LogType logTypeToCheckIfRequested, bool getNormalPrio, bool getWarningPrio, bool getErrorPrio) + { + if (logTypeToCheckIfRequested == LogType.Log) + { + if (getNormalPrio) + { + return true; + } + } + else + { + if (logTypeToCheckIfRequested == LogType.Warning) + { + if (getWarningPrio) + { + return true; + } + } + else + { + //"exception" and "assertion" count as "error": + if (getErrorPrio) + { + return true; + } + } + } + return false; + } + + static string GetWholeLogTextWall(ref List listOfSavedLogMessages, int numberOfSavedRequestedTypesMessagesThatAreAttachedToGameObject, int numberOfMessagesInTextWall, int numberOf_savedNormalLogMessagesThatAreAttachedToGameObject, int numberOf_savedWarningLogMessagesThatAreAttachedToGameObject, int numberOf_savedErrorLogMessagesThatAreAttachedToGameObject, bool getNormalPrio, bool getWarningPrio, bool getErrorPrio) + { + if (listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[0]].wholeTextWallForLogDisplayOfLastXLogs == null) + { + string headerLine = GetHeaderLineString(numberOfSavedRequestedTypesMessagesThatAreAttachedToGameObject, numberOfMessagesInTextWall, numberOf_savedNormalLogMessagesThatAreAttachedToGameObject, numberOf_savedWarningLogMessagesThatAreAttachedToGameObject, numberOf_savedErrorLogMessagesThatAreAttachedToGameObject, getNormalPrio, getWarningPrio, getErrorPrio); + + int numberOfAlreadyConcattedMessages = 0; + int numberOfUsedSlots_inConcatted4StringsArray = 0; + bool allSlotsInStringOf4ArrayFilled = false; + + //trading code readability for GC.Alloc()-prevention: + for (int i_concatted4Strings = 0; i_concatted4Strings < maxNumberOfBlocksOf4ConcattedStrings; i_concatted4Strings++) + { + int numberOfLogsForNext_blockOf4ConcattedStrings = (numberOfAlreadyConcattedMessages + 4) <= numberOfMessagesInTextWall ? 4 : (numberOfMessagesInTextWall - numberOfAlreadyConcattedMessages); + switch (numberOfLogsForNext_blockOf4ConcattedStrings) + { + case 0: + blocksOf4ConcattedStrings_startingWithNewest[i_concatted4Strings] = headerLine; + allSlotsInStringOf4ArrayFilled = true; + break; + + case 1: + blocksOf4ConcattedStrings_startingWithNewest[i_concatted4Strings] = headerLine + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyConcattedMessages]].stringWithLogSymbolStackTraceAndLineBreak; + allSlotsInStringOf4ArrayFilled = true; + break; + + case 2: + blocksOf4ConcattedStrings_startingWithNewest[i_concatted4Strings] = headerLine + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyConcattedMessages + 1]].stringWithLogSymbolStackTraceAndLineBreak + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyConcattedMessages]].stringWithLogSymbolStackTraceAndLineBreak; + allSlotsInStringOf4ArrayFilled = true; + break; + + case 3: + blocksOf4ConcattedStrings_startingWithNewest[i_concatted4Strings] = headerLine + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyConcattedMessages + 2]].stringWithLogSymbolStackTraceAndLineBreak + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyConcattedMessages + 1]].stringWithLogSymbolStackTraceAndLineBreak + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyConcattedMessages]].stringWithLogSymbolStackTraceAndLineBreak; + allSlotsInStringOf4ArrayFilled = true; + break; + + case 4: + blocksOf4ConcattedStrings_startingWithNewest[i_concatted4Strings] = listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyConcattedMessages + 3]].stringWithLogSymbolStackTraceAndLineBreak + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyConcattedMessages + 2]].stringWithLogSymbolStackTraceAndLineBreak + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyConcattedMessages + 1]].stringWithLogSymbolStackTraceAndLineBreak + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyConcattedMessages]].stringWithLogSymbolStackTraceAndLineBreak; + numberOfAlreadyConcattedMessages = numberOfAlreadyConcattedMessages + 4; + break; + + default: + UtilitiesDXXL_Log.PrintErrorCode("1-" + numberOfLogsForNext_blockOf4ConcattedStrings); + break; + } + + if (allSlotsInStringOf4ArrayFilled) + { + numberOfUsedSlots_inConcatted4StringsArray = i_concatted4Strings + 1; + break; + } + + if (i_concatted4Strings >= (maxNumberOfBlocksOf4ConcattedStrings - 1)) + { + //->all slots are filled + blocksOf4ConcattedStrings_startingWithNewest[i_concatted4Strings] = headerLine + blocksOf4ConcattedStrings_startingWithNewest[i_concatted4Strings]; + numberOfUsedSlots_inConcatted4StringsArray = i_concatted4Strings + 1; + break; + } + + } + + switch (numberOfUsedSlots_inConcatted4StringsArray) + { + case 0: + UtilitiesDXXL_Log.PrintErrorCode("2"); + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[0]].wholeTextWallForLogDisplayOfLastXLogs = null; + break; + + case 1: + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[0]].wholeTextWallForLogDisplayOfLastXLogs = blocksOf4ConcattedStrings_startingWithNewest[0]; + break; + + case 2: + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[0]].wholeTextWallForLogDisplayOfLastXLogs = blocksOf4ConcattedStrings_startingWithNewest[1] + blocksOf4ConcattedStrings_startingWithNewest[0]; + break; + + case 3: + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[0]].wholeTextWallForLogDisplayOfLastXLogs = blocksOf4ConcattedStrings_startingWithNewest[2] + blocksOf4ConcattedStrings_startingWithNewest[1] + blocksOf4ConcattedStrings_startingWithNewest[0]; + break; + + case 4: + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[0]].wholeTextWallForLogDisplayOfLastXLogs = blocksOf4ConcattedStrings_startingWithNewest[3] + blocksOf4ConcattedStrings_startingWithNewest[2] + blocksOf4ConcattedStrings_startingWithNewest[1] + blocksOf4ConcattedStrings_startingWithNewest[0]; + break; + + default: + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[0]].wholeTextWallForLogDisplayOfLastXLogs = blocksOf4ConcattedStrings_startingWithNewest[3] + blocksOf4ConcattedStrings_startingWithNewest[2] + blocksOf4ConcattedStrings_startingWithNewest[1] + blocksOf4ConcattedStrings_startingWithNewest[0]; + //no GC.Alloc()-optimization for more than 14 maxNumberOfDisplayedLogMessages: + for (int i = 4; i < numberOfUsedSlots_inConcatted4StringsArray; i++) + { + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[0]].wholeTextWallForLogDisplayOfLastXLogs = blocksOf4ConcattedStrings_startingWithNewest[i] + listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[0]].wholeTextWallForLogDisplayOfLastXLogs; + } + break; + } + } + return listOfSavedLogMessages[indexes_ofCurrLog_insideAllLogsList_startingWithNewest[0]].wholeTextWallForLogDisplayOfLastXLogs; + } + + static string GetHeaderLineString(int overallNumberOfSavedRequestedTypesMessages, int numberOfMessagesInTextWall, int numberOf_normalLogMessages, int numberOf_warningLogMessages, int numberOf_errorLogMessages, bool getNormalPrio, bool getWarningPrio, bool getErrorPrio) + { + //trading code readability for GC.Alloc()-prevention: + if (getNormalPrio) + { + if (getWarningPrio) + { + if (getErrorPrio) + { + return (" ..." + (overallNumberOfSavedRequestedTypesMessages - numberOfMessagesInTextWall) + " more message(s) (overall: " + numberOf_normalLogMessages + " , " + numberOf_warningLogMessages + " , " + numberOf_errorLogMessages + " )
"); + } + else + { + return (" ..." + (overallNumberOfSavedRequestedTypesMessages - numberOfMessagesInTextWall) + " more message(s) (overall: " + numberOf_normalLogMessages + " , " + numberOf_warningLogMessages + " , " + numberOf_errorLogMessages + " )
"); + } + } + else + { + if (getErrorPrio) + { + return (" ..." + (overallNumberOfSavedRequestedTypesMessages - numberOfMessagesInTextWall) + " more message(s) (overall: " + numberOf_normalLogMessages + " , " + numberOf_warningLogMessages + " , " + numberOf_errorLogMessages + " )
"); + } + else + { + return (" ..." + (overallNumberOfSavedRequestedTypesMessages - numberOfMessagesInTextWall) + " more message(s) (overall: " + numberOf_normalLogMessages + " , " + numberOf_warningLogMessages + " , " + numberOf_errorLogMessages + " )
"); + } + } + } + else + { + if (getWarningPrio) + { + if (getErrorPrio) + { + return (" ..." + (overallNumberOfSavedRequestedTypesMessages - numberOfMessagesInTextWall) + " more message(s) (overall: " + numberOf_normalLogMessages + " , " + numberOf_warningLogMessages + " , " + numberOf_errorLogMessages + " )
"); + } + else + { + return (" ..." + (overallNumberOfSavedRequestedTypesMessages - numberOfMessagesInTextWall) + " more message(s) (overall: " + numberOf_normalLogMessages + " , " + numberOf_warningLogMessages + " , " + numberOf_errorLogMessages + " )
"); + } + } + else + { + if (getErrorPrio) + { + return (" ..." + (overallNumberOfSavedRequestedTypesMessages - numberOfMessagesInTextWall) + " more message(s) (overall: " + numberOf_normalLogMessages + " , " + numberOf_warningLogMessages + " , " + numberOf_errorLogMessages + " )
"); + } + else + { + return "(all logTypes are disabled)"; + } + } + } + } + + public static void ClearLogs(bool clearLogsForDrawingAtGameobjects = true, bool clearLogsForDrawingToScreenspace = true) + { + if (clearLogsForDrawingAtGameobjects) + { + logMessagesForDrawAtGameObjects = new List(); + } + + if (clearLogsForDrawingToScreenspace) + { + logMessagesForDrawnOnScreen = new List(); + } + } + + private static bool logMessageListenerForLogsOnScreen_isActivated = false; + public static bool LogMessageListenerForLogsOnScreen_isActivated + { + get { return logMessageListenerForLogsOnScreen_isActivated; } + set { UnityEngine.Debug.LogError("Don't set 'LogMessageListenerForLogsOnScreen_isActivated' manually. Use 'ActivateLogMessageListenerForLogsOnScreen()' or 'DecactivateLogMessageListenerForLogsOnScreen()' instead."); } + } + + public static void ActivateLogMessageListenerForLogsOnScreen() + { + Application.logMessageReceived -= SaveLogForDrawingOnScreen; + Application.logMessageReceived += SaveLogForDrawingOnScreen; + logMessageListenerForLogsOnScreen_isActivated = true; + } + + public static void DeactivateLogMessageListenerForLogsOnScreen() + { + Application.logMessageReceived -= SaveLogForDrawingOnScreen; + logMessageListenerForLogsOnScreen_isActivated = false; + } + + static void SaveLogForDrawingOnScreen(string logString, string stackTrace, LogType type) + { + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) { return; } + + InternalDXXL_LogMessageForDrawing receivedLogMessage = new InternalDXXL_LogMessageForDrawing(); + receivedLogMessage.logString = logString; + receivedLogMessage.stackTrace = stackTrace; + receivedLogMessage.logType = type; + logMessagesForDrawnOnScreen.Add(receivedLogMessage); + } + + static List logMessagesForDrawnOnScreen = new List(); + static string GetStringWithXNewestLogsForDrawOnScreen(int maxNumberOfDisplayedLogMessages, bool getNormalPrio, bool getWarningPrio, bool getErrorPrio, bool stackTraceForNormalPrio, bool stackTraceForWarningPrio, bool stackTraceForErrorPrio) + { + if (logMessageListenerForLogsOnScreen_isActivated == false) + { + return "In order to use 'DrawLogs.LogsOnScreen()' you have activate it by calling
'DrawLogs.ActivateLogMessageListenerForLogsOnScreen()' once beforehand."; + } + + if (getNormalPrio == false && getWarningPrio == false && getErrorPrio == false) + { + return "(all logTypes are disabled)"; + } + + maxNumberOfDisplayedLogMessages = Mathf.Abs(maxNumberOfDisplayedLogMessages); + maxNumberOfDisplayedLogMessages = Mathf.Max(maxNumberOfDisplayedLogMessages, 1); + maxNumberOfDisplayedLogMessages = Mathf.Min(maxNumberOfDisplayedLogMessages, maxMaxNumberOfNumberOfLogDisplayerLogMessages); + + int numberOfSavedRequestedTypesMessages = 0; + int numberOf_savedNormalLogMessages = 0; + int numberOf_savedWarningLogMessages = 0; + int numberOf_savedErrorLogMessages = 0; + for (int i = 0; i < logMessagesForDrawnOnScreen.Count; i++) + { + if (logMessagesForDrawnOnScreen[i].logType == LogType.Log) + { + numberOf_savedNormalLogMessages++; + if (getNormalPrio) + { + numberOfSavedRequestedTypesMessages++; + } + } + else + { + if (logMessagesForDrawnOnScreen[i].logType == LogType.Warning) + { + numberOf_savedWarningLogMessages++; + if (getWarningPrio) + { + numberOfSavedRequestedTypesMessages++; + } + } + else + { + //"exception" and "assertion" count as "error": + numberOf_savedErrorLogMessages++; + if (getErrorPrio) + { + numberOfSavedRequestedTypesMessages++; + } + } + } + } + + if (numberOfSavedRequestedTypesMessages == 0) + { + return "(no log messages yet for the requested log types)"; + } + else + { + int numberOfMessagesInTextWall = FillConcerned_stringsWithLogSymbolStackTraceAndLineBreak(maxNumberOfDisplayedLogMessages, getNormalPrio, getWarningPrio, getErrorPrio, stackTraceForNormalPrio, stackTraceForWarningPrio, stackTraceForErrorPrio); + return GetWholeLogTextWall(ref logMessagesForDrawnOnScreen, numberOfSavedRequestedTypesMessages, numberOfMessagesInTextWall, numberOf_savedNormalLogMessages, numberOf_savedWarningLogMessages, numberOf_savedErrorLogMessages, getNormalPrio, getWarningPrio, getErrorPrio); + } + } + + static int FillConcerned_stringsWithLogSymbolStackTraceAndLineBreak(int maxNumberOfDisplayedLogMessages, bool getNormalPrio, bool getWarningPrio, bool getErrorPrio, bool stackTraceForNormalPrio, bool stackTraceForWarningPrio, bool stackTraceForErrorPrio) + { + int numberOfAlreadyRetrievedMessages = 0; + for (int i_ofAllSavedLogs = logMessagesForDrawnOnScreen.Count - 1; i_ofAllSavedLogs >= 0; i_ofAllSavedLogs--) + { + if (IsARequestedLogType(logMessagesForDrawnOnScreen[i_ofAllSavedLogs].logType, getNormalPrio, getWarningPrio, getErrorPrio)) + { + if (logMessagesForDrawnOnScreen[i_ofAllSavedLogs].stringWithLogSymbolStackTraceAndLineBreak == null) + { + logMessagesForDrawnOnScreen[i_ofAllSavedLogs].stringWithLogSymbolStackTraceAndLineBreak = DrawText.MarkupLogSymbol(logMessagesForDrawnOnScreen[i_ofAllSavedLogs].logType) + " " + logMessagesForDrawnOnScreen[i_ofAllSavedLogs].logString + "
"; + if (logMessagesForDrawnOnScreen[i_ofAllSavedLogs].stackTrace != null) + { + if (IsARequestedLogType(logMessagesForDrawnOnScreen[i_ofAllSavedLogs].logType, stackTraceForNormalPrio, stackTraceForWarningPrio, stackTraceForErrorPrio)) + { + //-> it is not trivial here to simply indent the stack trace, because the ".stackTrace" field comes already with inserted line breaks, so the line start positions are not directly available here + logMessagesForDrawnOnScreen[i_ofAllSavedLogs].stringWithLogSymbolStackTraceAndLineBreak = logMessagesForDrawnOnScreen[i_ofAllSavedLogs].stringWithLogSymbolStackTraceAndLineBreak + "
-----------------------------[STACK TRACE]-----------------------------
" + logMessagesForDrawnOnScreen[i_ofAllSavedLogs].stackTrace + "
-----------------------------[/STACK TRACE]----------------------------

"; + } + } + } + + indexes_ofCurrLog_insideAllLogsList_startingWithNewest[numberOfAlreadyRetrievedMessages] = i_ofAllSavedLogs; + numberOfAlreadyRetrievedMessages++; + } + if (numberOfAlreadyRetrievedMessages >= maxNumberOfDisplayedLogMessages) { break; } + } + return numberOfAlreadyRetrievedMessages; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/DrawLogs.cs.meta b/Runtime/DrawDebugLibrary/DrawLogs.cs.meta new file mode 100644 index 0000000..b79b891 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawLogs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b0620c964834a94ca9b951c9b4504c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawMeasurements.cs b/Runtime/DrawDebugLibrary/DrawMeasurements.cs new file mode 100644 index 0000000..75b4438 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawMeasurements.cs @@ -0,0 +1,933 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class DrawMeasurements + { + static InternalDXXL_Line line = new InternalDXXL_Line(); + static InternalDXXL_Line line1 = new InternalDXXL_Line(); + static InternalDXXL_Line line2 = new InternalDXXL_Line(); + + public static Color defaultColor1 = new Color(0.26f, 1.0f, 1.0f, 1.0f); + public static Color defaultColor2 = new Color(1.0f, 0.938f, 0.23f, 1.0f); + + public static Vector3 preferredPlanePatternOrientation_forDistancePointToPlane = Vector3.forward; + public static float minimumLineLength_forDistancePointToLine = 1000.0f; + public static float minimumLineLength_forDistanceLineToLine = 1000.0f; + public static float minimumLineLength_forAngleLineToPlane = 1000.0f; + + public static float Distance(Vector3 from, Vector3 to, Color color = default(Color), float lineWidth = 0.0f, string text = null, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return UtilitiesDXXL_Measurements.Distance(false, UtilitiesDXXL_Measurements.DistanceSpecifyingStringType.point_point, from, to, color, lineWidth, text, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, false); + } + + public static float Angle(Vector3 from, Vector3 to, Vector3 turnCenter, Color color = default(Color), float forceRadius = 0.0f, float lineWidth = 0.0f, string text = null, bool useReflexAngleOver180deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool drawBoundaryLines = true, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return UtilitiesDXXL_Measurements.Angle(false, false, false, from, to, turnCenter, color, forceRadius, lineWidth, text, useReflexAngleOver180deg, displayAndReturn_radInsteadOfDeg, coneLength, drawBoundaryLines, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + public static float AngleSpan(Vector3 from, Vector3 to, Vector3 turnCenter, Color color = default(Color), float forceRadius = 0.0f, float lineWidth = 0.0f, string text = null, bool useReflexAngleOver180deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool drawBoundaryLines = true, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return UtilitiesDXXL_Measurements.Angle(false, false, true, from, to, turnCenter, color, forceRadius, lineWidth, text, useReflexAngleOver180deg, displayAndReturn_radInsteadOfDeg, coneLength, drawBoundaryLines, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + public static float DistancePointToLine(Vector3 point, Ray line, Color color = default(Color), float linesWidth = 0.0f, string text = null, string lineName = null, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return DistancePointToLine(point, line.origin, line.direction, color, linesWidth, text, lineName, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + public static float DistancePointToLine(Vector3 point, Vector3 lineOrigin, Vector3 lineDirection, Color color = default(Color), float linesWidth = 0.0f, string text = null, string lineName = null, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0.0f; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(point, "point")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(lineOrigin, "lineOrigin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(lineDirection, "lineDirection")) { return 0.0f; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + if (UtilitiesDXXL_Math.ApproximatelyZero(lineDirection)) + { + UtilitiesDXXL_DrawBasics.PointFallback(point, "[ 'lineDirection' is zero. DistancePointToLine measure operation not executed.]
[point]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(lineOrigin, "[ 'lineDirection' is zero. DistancePointToLine measure operation not executed.]
[lineOrigin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + line.Recreate(lineOrigin, lineDirection, false); + Vector3 pointsProjectionOntoLine = line.Get_perpProjectionOfPoint_ontoThisLine(point); + + //Draw distance: + bool skipDrawing = DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped(); + float distance = UtilitiesDXXL_Measurements.Distance(false, UtilitiesDXXL_Measurements.DistanceSpecifyingStringType.point_line, point, pointsProjectionOntoLine, color, linesWidth, text, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipDrawing); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return distance; } + + //Draw line: + string lineIdentifyingText = ((lineName == null) || (lineName == "")) ? "line direction" : lineName; + float widthOfDirVector = UtilitiesDXXL_Math.ApproximatelyZero(linesWidth) ? 0.01f : (0.6f * linesWidth); + Color colorOfProlongedLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor2, 0.55f); + Color colorOfProlongedLine_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor2, 0.35f); + DrawBasics.VectorFrom(lineOrigin, lineDirection, defaultColor2, widthOfDirVector, DrawText.MarkupColor(lineIdentifyingText, colorOfProlongedLine_lowerAlpha), coneLength * 1.7f, false, false, default(Vector3), true, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + + Vector3 projectionToLineOrigin = line.origin - pointsProjectionOntoLine; + float distance_projectionToLineOrigin = projectionToLineOrigin.magnitude; + float lineExtentionPerSide = Mathf.Max(minimumLineLength_forDistancePointToLine, 1.1f * distance_projectionToLineOrigin); + Line_fadeableAnimSpeed.InternalDraw(lineOrigin - line.direction_normalized * lineExtentionPerSide, lineOrigin + line.direction_normalized * lineExtentionPerSide, colorOfProlongedLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + UtilitiesDXXL_Measurements.WriteLineNameAtProjectionPlumbPos(false, lineName, "line", "", projectionToLineOrigin, distance_projectionToLineOrigin, point, line, pointsProjectionOntoLine, 0.02f * distance, colorOfProlongedLine, true, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_Measurements.Draw90degSymbol(distance, pointsProjectionOntoLine, point, line.direction_normalized, colorOfProlongedLine_lowerAlpha, durationInSec, hiddenByNearerObjects); + + return distance; + } + + public static float DistanceLineToLine(Ray line1, Ray line2, Color color = default(Color), float linesWidth = 0.0f, string text = null, string line1Name = null, string line2Name = null, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return DistanceLineToLine(line1.origin, line1.direction, line2.origin, line2.direction, color, linesWidth, text, line1Name, line2Name, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + public static float DistanceLineToLine(Vector3 line1Origin, Vector3 line1Direction, Vector3 line2Origin, Vector3 line2Direction, Color color = default(Color), float linesWidth = 0.0f, string text = null, string line1Name = null, string line2Name = null, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0.0f; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(line1Origin, "line1Origin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(line1Direction, "line1Direction")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(line2Origin, "line2Origin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(line2Direction, "line2Direction")) { return 0.0f; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + if (UtilitiesDXXL_Math.ApproximatelyZero(line1Direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(line1Origin, "[ 'line1Direction' is zero. DistanceLineToLine measure operation not executed.]
[line1Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(line2Origin, "[ 'line1Direction' is zero. DistanceLineToLine measure operation not executed.]
[line2Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(line2Direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(line1Origin, "[ 'line2Direction' is zero. DistanceLineToLine measure operation not executed.]
[line1Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(line2Origin, "[ 'line2Direction' is zero. DistanceLineToLine measure operation not executed.]
[line2Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + line1.Recreate(line1Origin, line1Direction, false); + line2.Recreate(line2Origin, line2Direction, false); + Vector3 posOnLine2_thatIsNearestToLine1 = line2.Get_posOnLine_thatIsNearestTo_passingOtherLine(line1); + if (float.IsNaN(posOnLine2_thatIsNearestToLine1.x)) + { + posOnLine2_thatIsNearestToLine1 = line2.origin; + } + Vector3 pointsProjectionOntoLine1 = line1.Get_perpProjectionOfPoint_ontoThisLine(posOnLine2_thatIsNearestToLine1); + + //Draw distance: + bool skipDrawing = DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped(); + float distance = UtilitiesDXXL_Measurements.Distance(false, UtilitiesDXXL_Measurements.DistanceSpecifyingStringType.line_line, pointsProjectionOntoLine1, posOnLine2_thatIsNearestToLine1, color, linesWidth, text, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipDrawing); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return distance; } + + //Draw lines: + float widthOfDirVector = UtilitiesDXXL_Math.ApproximatelyZero(linesWidth) ? 0.01f : (0.6f * linesWidth); + float alphaFactor_ofProlongedLines = 0.55f; + float alphaFactor_ofLineAttachments = 0.35f; + Color colorOfProlongedLine1 = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor1, alphaFactor_ofProlongedLines); + Color colorOfProlongedLine2 = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor2, alphaFactor_ofProlongedLines); + Color colorOfLine1Attachments = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor1, alphaFactor_ofLineAttachments); + Color colorOfLine2Attachments = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor2, alphaFactor_ofLineAttachments); + + Vector3 projectionOnLine1ToLine1Origin = line1.origin - pointsProjectionOntoLine1; + float distance_projectionToLine1Origin = projectionOnLine1ToLine1Origin.magnitude; + float line1ExtentionPerSide = Mathf.Max(minimumLineLength_forDistanceLineToLine, 1.1f * distance_projectionToLine1Origin); + string line1IdentifyingText = ((line1Name == null) || (line1Name == "")) ? "line1 direction" : line1Name; + DrawBasics.VectorFrom(line1Origin, line1Direction, defaultColor1, widthOfDirVector, DrawText.MarkupColor(line1IdentifyingText, colorOfLine1Attachments), coneLength * 1.7f, false, false, default(Vector3), true, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + Line_fadeableAnimSpeed.InternalDraw(line1Origin - line1.direction_normalized * line1ExtentionPerSide, line1Origin + line1.direction_normalized * line1ExtentionPerSide, colorOfProlongedLine1, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + Vector3 projectionOnLine2ToLine2Origin = line2.origin - posOnLine2_thatIsNearestToLine1; + float distance_projectionToLine2Origin = projectionOnLine2ToLine2Origin.magnitude; + float line2ExtentionPerSide = Mathf.Max(minimumLineLength_forDistanceLineToLine, 1.1f * distance_projectionToLine2Origin); + string line2IdentifyingText = ((line2Name == null) || (line2Name == "")) ? "line2 direction" : line2Name; + DrawBasics.VectorFrom(line2Origin, line2Direction, defaultColor2, widthOfDirVector, DrawText.MarkupColor(line2IdentifyingText, colorOfLine2Attachments), coneLength * 1.7f, false, false, default(Vector3), true, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + Line_fadeableAnimSpeed.InternalDraw(line2Origin - line2.direction_normalized * line2ExtentionPerSide, line2Origin + line2.direction_normalized * line2ExtentionPerSide, colorOfProlongedLine2, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + UtilitiesDXXL_Measurements.WriteLineNameAtProjectionPlumbPos(false, line1Name, "line1", "", projectionOnLine1ToLine1Origin, distance_projectionToLine1Origin, posOnLine2_thatIsNearestToLine1, line1, pointsProjectionOntoLine1, 0.02f * distance, colorOfProlongedLine1, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Measurements.WriteLineNameAtProjectionPlumbPos(false, line2Name, "line2", "", projectionOnLine2ToLine2Origin, distance_projectionToLine2Origin, pointsProjectionOntoLine1, line2, posOnLine2_thatIsNearestToLine1, 0.02f * distance, colorOfProlongedLine2, true, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_Measurements.Draw90degSymbol(distance, pointsProjectionOntoLine1, posOnLine2_thatIsNearestToLine1, line1.direction_normalized, colorOfLine1Attachments, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Measurements.Draw90degSymbol(distance, posOnLine2_thatIsNearestToLine1, pointsProjectionOntoLine1, line2.direction_normalized, colorOfLine2Attachments, durationInSec, hiddenByNearerObjects); + + return distance; + } + + public static float DistancePerpToOrthoViewDir(Vector3 from, Vector3 to, Vector3 orthoViewDir, Color color = default(Color), float linesWidth = 0.0f, string text = null, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0.0f; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(from, "from")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(to, "to")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(orthoViewDir, "orthoViewDir")) { return 0.0f; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + if (UtilitiesDXXL_Math.ApproximatelyZero(orthoViewDir)) + { + UtilitiesDXXL_DrawBasics.PointFallback(from, "[ 'orthoViewDir' is zero. DistancePerpToOrthoViewDir measure operation not executed.]
[from]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(to, "[ 'orthoViewDir' is zero. DistancePerpToOrthoViewDir measure operation not executed.]
[to]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + orthoViewDir = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(orthoViewDir); + line1.Recreate(from, orthoViewDir, false); + line2.Recreate(to, orthoViewDir, false); + Vector3 fromPoint_projectedOntoLine2 = line2.Get_perpProjectionOfPoint_ontoThisLine(from); + if (float.IsNaN(fromPoint_projectedOntoLine2.x)) + { + fromPoint_projectedOntoLine2 = line2.origin; + } + + //Draw distance: + bool skipDrawing = DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped(); + float distance = UtilitiesDXXL_Measurements.Distance(false, UtilitiesDXXL_Measurements.DistanceSpecifyingStringType.point_ll_point, from, fromPoint_projectedOntoLine2, color, linesWidth, text, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipDrawing); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return distance; } + + //Draw lines: + Vector3 point1_to_point2_alongViewDir = to - fromPoint_projectedOntoLine2; + float distanceAlongViewDir = point1_to_point2_alongViewDir.magnitude; + Vector3 point1_to_point2_alongViewDir_normalized; + if (UtilitiesDXXL_Math.ApproximatelyZero(distanceAlongViewDir)) + { + point1_to_point2_alongViewDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(orthoViewDir); + distanceAlongViewDir = 1.0f; + } + else + { + point1_to_point2_alongViewDir_normalized = point1_to_point2_alongViewDir / distanceAlongViewDir; + } + + Color colorOfAttachments = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(Color.white, 0.2f); + float patternScaleFactor = distanceAlongViewDir; + patternScaleFactor = Mathf.Max(patternScaleFactor, 0.02f); + + Vector3 line1_start = from - point1_to_point2_alongViewDir_normalized * (0.1f * distanceAlongViewDir); + Line_fadeableAnimSpeed.InternalDraw(line1_start, line1_start + point1_to_point2_alongViewDir_normalized * (1.2f * distanceAlongViewDir), colorOfAttachments, 0.0f, null, DrawBasics.LineStyle.dashedLong, patternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + Vector3 line2_start = to + point1_to_point2_alongViewDir_normalized * (0.1f * distanceAlongViewDir); + Line_fadeableAnimSpeed.InternalDraw(line2_start, line2_start - point1_to_point2_alongViewDir_normalized * (1.2f * distanceAlongViewDir), colorOfAttachments, 0.0f, null, DrawBasics.LineStyle.dashedLong, patternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + UtilitiesDXXL_Measurements.WriteOrthoViewDirNameAtProjectionPlumbPos(" ortho view dir throught 'from'", fromPoint_projectedOntoLine2, from, orthoViewDir, 0.02f * distance, colorOfAttachments, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Measurements.WriteOrthoViewDirNameAtProjectionPlumbPos(" ortho view dir throught 'to'", from, fromPoint_projectedOntoLine2, -orthoViewDir, 0.02f * distance, colorOfAttachments, durationInSec, hiddenByNearerObjects); + + //Draw 'to'-Point: + Vector3 upVector_forLookRotationOf_toPoint = (orthoViewDir.y >= 0.0f) ? orthoViewDir : (-orthoViewDir); + Vector3 forwardVector_forLookRotationOf_toPoint = Vector3.Cross(orthoViewDir, from - fromPoint_projectedOntoLine2); + forwardVector_forLookRotationOf_toPoint = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(forwardVector_forLookRotationOf_toPoint); + if (UtilitiesDXXL_Math.ApproximatelyZero(forwardVector_forLookRotationOf_toPoint)) + { + forwardVector_forLookRotationOf_toPoint = Vector3.forward; + } + Quaternion rotation_ofToPoint = Quaternion.LookRotation(forwardVector_forLookRotationOf_toPoint, upVector_forLookRotationOf_toPoint); + + UtilitiesDXXL_DrawBasics.Set_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_reversible(0); + DrawBasics.Point(to, "to(distance perp to ortho)", color, distance * 0.1f, linesWidth, color, rotation_ofToPoint, false, true, false, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM(); + + UtilitiesDXXL_Measurements.Draw90degSymbol(distance, from, fromPoint_projectedOntoLine2, line1.direction_normalized, colorOfAttachments, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Measurements.Draw90degSymbol(distance, fromPoint_projectedOntoLine2, from, line2.direction_normalized, colorOfAttachments, durationInSec, hiddenByNearerObjects); + + return distance; + } + + public static float DistanceAlongOrthoViewDir(Vector3 from, Vector3 to, Vector3 orthoViewDir, Color color = default(Color), float linesWidth = 0.0f, string text = null, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0.0f; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(from, "from")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(to, "to")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(orthoViewDir, "orthoViewDir")) { return 0.0f; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + if (UtilitiesDXXL_Math.ApproximatelyZero(orthoViewDir)) + { + UtilitiesDXXL_DrawBasics.PointFallback(from, "[ 'orthoViewDir' is zero. DistanceAlongOrthoViewDir measure operation not executed.]
[from]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(to, "[ 'orthoViewDir' is zero. DistanceAlongOrthoViewDir measure operation not executed.]
[to]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + orthoViewDir = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(orthoViewDir); + line1.Recreate(from, orthoViewDir, false); + line2.Recreate(to, orthoViewDir, false); + Vector3 fromPoint_projectedOntoLine2 = line2.Get_perpProjectionOfPoint_ontoThisLine(from); + if (float.IsNaN(fromPoint_projectedOntoLine2.x)) + { + fromPoint_projectedOntoLine2 = line2.origin; + } + Vector3 toPoint_projectedOntoLine1 = line1.Get_perpProjectionOfPoint_ontoThisLine(to); + + //Draw distance: + bool skipDrawing = DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped(); + float distanceAlongViewDir = UtilitiesDXXL_Measurements.Distance(false, UtilitiesDXXL_Measurements.DistanceSpecifyingStringType.point_l_I_l_point, from, toPoint_projectedOntoLine1, color, linesWidth, text, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipDrawing); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return distanceAlongViewDir; } + + //Draw viewDirLines: + float perpDistance_betweenLines = (fromPoint_projectedOntoLine2 - from).magnitude; + Vector3 point1_to_point2_alongViewDir = to - fromPoint_projectedOntoLine2; + Vector3 point1_to_point2_alongViewDir_normalized; + float extentionBase_forLinesAlongViewDir; + if (UtilitiesDXXL_Math.ApproximatelyZero(distanceAlongViewDir)) + { + point1_to_point2_alongViewDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(orthoViewDir); + extentionBase_forLinesAlongViewDir = 1.0f; + } + else + { + point1_to_point2_alongViewDir_normalized = point1_to_point2_alongViewDir / distanceAlongViewDir; + extentionBase_forLinesAlongViewDir = distanceAlongViewDir; + } + + Color colorOfAttachments = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(Color.white, 0.2f); + + float patternScaleFactor = distanceAlongViewDir; + patternScaleFactor = Mathf.Max(patternScaleFactor, 0.02f); + Vector3 line1_start = from - point1_to_point2_alongViewDir_normalized * (0.6f * extentionBase_forLinesAlongViewDir); + Line_fadeableAnimSpeed.InternalDraw(line1_start, line1_start + point1_to_point2_alongViewDir_normalized * (2.2f * extentionBase_forLinesAlongViewDir), colorOfAttachments, 0.0f, null, DrawBasics.LineStyle.dashedLong, patternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Vector3 line2_start = to + point1_to_point2_alongViewDir_normalized * (0.6f * extentionBase_forLinesAlongViewDir); + Line_fadeableAnimSpeed.InternalDraw(line2_start, line2_start - point1_to_point2_alongViewDir_normalized * (2.2f * extentionBase_forLinesAlongViewDir), colorOfAttachments, 0.0f, null, DrawBasics.LineStyle.dashedLong, patternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + UtilitiesDXXL_Measurements.WriteOrthoViewDirNameAtProjectionPlumbPos(" ortho view dir throught 'from'", fromPoint_projectedOntoLine2, from, orthoViewDir, 0.02f * perpDistance_betweenLines, colorOfAttachments, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Measurements.WriteOrthoViewDirNameAtProjectionPlumbPos(" ortho view dir throught 'to'", from, fromPoint_projectedOntoLine2, -orthoViewDir, 0.02f * perpDistance_betweenLines, colorOfAttachments, durationInSec, hiddenByNearerObjects); + + //Draw 'to'-Point: + Vector3 upVector_forLookRotationOf_toPoint = (orthoViewDir.y >= 0.0f) ? orthoViewDir : (-orthoViewDir); + Vector3 forwardVector_forLookRotationOf_toPoint = Vector3.Cross(orthoViewDir, from - fromPoint_projectedOntoLine2); + forwardVector_forLookRotationOf_toPoint = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(forwardVector_forLookRotationOf_toPoint); + if (UtilitiesDXXL_Math.ApproximatelyZero(forwardVector_forLookRotationOf_toPoint)) + { + forwardVector_forLookRotationOf_toPoint = Vector3.forward; + } + Quaternion rotation_ofToPoint = Quaternion.LookRotation(forwardVector_forLookRotationOf_toPoint, upVector_forLookRotationOf_toPoint); + + UtilitiesDXXL_DrawBasics.Set_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_reversible(0); + DrawBasics.Point(to, "to(distance along ortho)", color, perpDistance_betweenLines * 0.1f, linesWidth, color, rotation_ofToPoint, false, true, false, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM(); + + if (perpDistance_betweenLines > 0.0001f) + { + //Draw perp connection lines: + Line_fadeableAnimSpeed.InternalDraw(from, fromPoint_projectedOntoLine2, colorOfAttachments, 0.0f, null, DrawBasics.LineStyle.disconnectedAnchors, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed.InternalDraw(to, toPoint_projectedOntoLine1, colorOfAttachments, 0.0f, null, DrawBasics.LineStyle.disconnectedAnchors, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + UtilitiesDXXL_Measurements.Draw90degSymbol(perpDistance_betweenLines, from, fromPoint_projectedOntoLine2, line1.direction_normalized, colorOfAttachments, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Measurements.Draw90degSymbol(perpDistance_betweenLines, fromPoint_projectedOntoLine2, from, line2.direction_normalized, colorOfAttachments, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_Measurements.Draw90degSymbol(perpDistance_betweenLines, to, toPoint_projectedOntoLine1, line1.direction_normalized, colorOfAttachments, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Measurements.Draw90degSymbol(perpDistance_betweenLines, toPoint_projectedOntoLine1, to, line2.direction_normalized, colorOfAttachments, durationInSec, hiddenByNearerObjects); + } + + return distanceAlongViewDir; + } + + public static float DistancePointToPlane(Vector3 point, Transform planeTransform, Color color = default(Color), float linesWidth = 0.0f, string text = null, string planeName = null, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(planeTransform, "planeTransform")) { return 0.0f; } + return DistancePointToPlane(point, planeTransform.position, planeTransform.up, color, linesWidth, text, planeName, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + public static float DistancePointToPlane(Vector3 point, Plane plane, Color color = default(Color), float linesWidth = 0.0f, string text = null, string planeName = null, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return DistancePointToPlane(point, plane.ClosestPointOnPlane(Vector3.zero), plane.normal, color, linesWidth, text, planeName, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + static InternalDXXL_Plane plane = new InternalDXXL_Plane(); + public static float DistancePointToPlane(Vector3 point, Vector3 planeOrigin, Vector3 planeNormal, Color color = default(Color), float linesWidth = 0.0f, string text = null, string planeName = null, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0.0f; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(point, "point")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(planeOrigin, "planeOrigin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(planeNormal, "planeNormal")) { return 0.0f; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + if (UtilitiesDXXL_Math.ApproximatelyZero(planeNormal)) + { + UtilitiesDXXL_DrawBasics.PointFallback(point, "[ 'planeNormal' is zero. DistancePointToPlane measure operation not executed.]
[point]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(planeOrigin, "[ 'planeNormal' is zero. DistancePointToPlane measure operation not executed.]
[planeOrigin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + plane.Recreate(planeOrigin, planeNormal); + Vector3 projectionOfPointOnPlane = plane.Get_perpProjectionOfPointOnPlane(point); + if (float.IsNaN(projectionOfPointOnPlane.x)) + { + projectionOfPointOnPlane = point; + } + + bool skipDrawing = DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped(); + float distance = UtilitiesDXXL_Measurements.Distance(false, UtilitiesDXXL_Measurements.DistanceSpecifyingStringType.point_plane, point, projectionOfPointOnPlane, color, linesWidth, text, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipDrawing); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return distance; } + + Color planeColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor2, 0.5f); + float planeSize_nonExtended = distance; + planeSize_nonExtended = Mathf.Max(planeSize_nonExtended, 1.0f); + float anchorVisualizationSize = 0.2f * planeSize_nonExtended; + float subSegments_signFlipsInterpretation; + Vector3 forward_insidePlane = preferredPlanePatternOrientation_forDistancePointToPlane; //-> The plane grid pattern orientation stance can rotate fast and unnaturally when "planeNormal" becomes similar to "preferredPlanePatternOrientation_forDistancePointToPlane". Though since there is no preferred plane stance expected to be used more often than others I don't see an easy fix for that. + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref planeNormal, ref forward_insidePlane, true); + forward_insidePlane = plane.Get_projectionOfVectorOntoPlane(forward_insidePlane); + + //Main Plane: + subSegments_signFlipsInterpretation = (-0.1f) * planeSize_nonExtended; //-> "negative sign" means "fixed world space size of segments" + DrawShapes.Plane(planeOrigin, planeNormal, projectionOfPointOnPlane, planeColor, planeSize_nonExtended, planeSize_nonExtended, forward_insidePlane, 0.0f, null, subSegments_signFlipsInterpretation, false, anchorVisualizationSize, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + //Emphasizing plane at points projection on plane: + subSegments_signFlipsInterpretation = 20; //-> "positive sign" means "fixed number of segments" + DrawShapes.Plane(projectionOfPointOnPlane, planeNormal, default, planeColor, 0.2f * planeSize_nonExtended, 0.2f * planeSize_nonExtended, forward_insidePlane, 0.0f, null, subSegments_signFlipsInterpretation, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_Measurements.Draw90degSymbol(distance, projectionOfPointOnPlane, point, forward_insidePlane, planeColor, durationInSec, hiddenByNearerObjects); + + if ((planeName == null) || (planeName == "")) { planeName = "plane"; } + UtilitiesDXXL_Text.WriteFramed(planeName, projectionOfPointOnPlane + 0.11f * planeSize_nonExtended * forward_insidePlane, planeColor, 0.05f * planeSize_nonExtended, forward_insidePlane, Vector3.Cross(planeNormal, forward_insidePlane), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + return distance; + } + + public static float AngleLineToPlane(Ray line, Transform planeTransform, Color color = default(Color), float linesWidth = 0.0f, string text = null, string lineName = null, string planeName = null, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(planeTransform, "planeTransform")) { return 0.0f; } + return AngleLineToPlane(line.origin, line.direction, planeTransform.position, planeTransform.up, color, linesWidth, text, lineName, planeName, returnObtuseAngleOver90deg, displayAndReturn_radInsteadOfDeg, coneLength, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + public static float AngleLineToPlane(Ray line, Plane plane, Color color = default(Color), float linesWidth = 0.0f, string text = null, string lineName = null, string planeName = null, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return AngleLineToPlane(line.origin, line.direction, plane.ClosestPointOnPlane(Vector3.zero), plane.normal, color, linesWidth, text, lineName, planeName, returnObtuseAngleOver90deg, displayAndReturn_radInsteadOfDeg, coneLength, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + public static float AngleLineToPlane(Ray line, Vector3 planeOrigin, Vector3 planeNormal, Color color = default(Color), float linesWidth = 0.0f, string text = null, string lineName = null, string planeName = null, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return AngleLineToPlane(line.origin, line.direction, planeOrigin, planeNormal, color, linesWidth, text, lineName, planeName, returnObtuseAngleOver90deg, displayAndReturn_radInsteadOfDeg, coneLength, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + public static float AngleLineToPlane(Vector3 lineOrigin, Vector3 lineDirection, Transform planeTransform, Color color = default(Color), float linesWidth = 0.0f, string text = null, string lineName = null, string planeName = null, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(planeTransform, "planeTransform")) { return 0.0f; } + return AngleLineToPlane(lineOrigin, lineDirection, planeTransform.position, planeTransform.up, color, linesWidth, text, lineName, planeName, returnObtuseAngleOver90deg, displayAndReturn_radInsteadOfDeg, coneLength, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + public static float AngleLineToPlane(Vector3 lineOrigin, Vector3 lineDirection, Plane plane, Color color = default(Color), float linesWidth = 0.0f, string text = null, string lineName = null, string planeName = null, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return AngleLineToPlane(lineOrigin, lineDirection, plane.ClosestPointOnPlane(Vector3.zero), plane.normal, color, linesWidth, text, lineName, planeName, returnObtuseAngleOver90deg, displayAndReturn_radInsteadOfDeg, coneLength, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + public static float AngleLineToPlane(Vector3 lineOrigin, Vector3 lineDirection, Vector3 planeOrigin, Vector3 planeNormal, Color color = default(Color), float linesWidth = 0.0f, string text = null, string lineName = null, string planeName = null, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0.0f; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(lineOrigin, "lineOrigin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(lineDirection, "lineDirection")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(planeOrigin, "planeOrigin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(planeNormal, "planeNormal")) { return 0.0f; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + if (UtilitiesDXXL_Math.ApproximatelyZero(planeNormal)) + { + UtilitiesDXXL_DrawBasics.PointFallback(lineOrigin, "[ 'planeNormal' is zero. AngleLineToPlane measure operation not executed.]
[lineOrigin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(planeOrigin, "[ 'planeNormal' is zero. AngleLineToPlane measure operation not executed.]
[planeOrigin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(lineDirection)) + { + UtilitiesDXXL_DrawBasics.PointFallback(lineOrigin, "[ 'lineDirection' is zero. AngleLineToPlane measure operation not executed.]
[lineOrigin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(planeOrigin, "[ 'lineDirection' is zero. AngleLineToPlane measure operation not executed.]
[planeOrigin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + planeNormal = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(planeNormal); + Vector3 planeNormal_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(planeNormal); + line.Recreate(lineOrigin, lineDirection, false); + plane.Recreate(planeOrigin, planeNormal_normalized); + + Color planeColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor2, 0.5f); + Color colorOfProlongedLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor1, 0.55f); + Color color_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.45f); + Color colorOfAttachments = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor1, 0.35f); + + string lineIdentifyingText = ((lineName == null) || (lineName == "")) ? "line direction" : lineName; + float widthOfDirVector = UtilitiesDXXL_Math.ApproximatelyZero(linesWidth) ? 0.01f : (0.6f * linesWidth); + Vector3 lineOrigins_projectionOnPlane = plane.Get_perpProjectionOfPointOnPlane(line.origin); + + if (Mathf.Abs(Vector3.Dot(plane.normalDir, line.direction_normalized)) < 0.0001f) + { + //line is parallel to plane: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorFrom(lineOrigin, lineDirection, defaultColor1, widthOfDirVector, DrawText.MarkupColor(lineIdentifyingText, colorOfAttachments), 0.17f, false, false, default(Vector3), true, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + + Vector3 intersectionToLineOrigin_fallback = Vector3.zero; + float distance_intersectionToLineOrigin_fallback = 0.0f; + Line_fadeableAnimSpeed.InternalDraw(lineOrigin - line.direction_normalized * minimumLineLength_forAngleLineToPlane, lineOrigin + line.direction_normalized * minimumLineLength_forAngleLineToPlane, colorOfProlongedLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + UtilitiesDXXL_Measurements.WriteLineNameAtProjectionPlumbPos(false, lineName, "line", "", intersectionToLineOrigin_fallback, distance_intersectionToLineOrigin_fallback, lineOrigins_projectionOnPlane, line, line.origin, 0.1f, colorOfProlongedLine, false, durationInSec, hiddenByNearerObjects); + DistancePointToPlane(lineOrigin, planeOrigin, planeNormal_normalized, color, linesWidth, "[ Line is approximately parallel to plane -> fallback from 'Angle()' to 'Distance()']
" + text, planeName, coneLength, 0.0f, durationInSec, hiddenByNearerObjects); + return returnObtuseAngleOver90deg ? (displayAndReturn_radInsteadOfDeg ? (Mathf.Deg2Rad * 180.0f) : 180.0f) : 0.0f; + } + + Vector3 intersectionPoint = line.Get_intersectionPoint_withPlane_withoutParallelCheck(plane); + Vector3 intersection_to_lineOrigin = line.origin - intersectionPoint; + float distance_intersection_to_lineOrigin = intersection_to_lineOrigin.magnitude; + Vector3 intersection_towardsLine_normalized; + if (distance_intersection_to_lineOrigin < 0.0001f) + { + intersection_towardsLine_normalized = planeNormal_normalized; + } + else + { + intersection_towardsLine_normalized = intersection_to_lineOrigin / distance_intersection_to_lineOrigin; + } + + float radius = 0.5f * distance_intersection_to_lineOrigin; + radius = Mathf.Max(radius, 0.2f); + + Vector3 lineOriginProjectionOnPlane_to_intersectionPos = intersectionPoint - lineOrigins_projectionOnPlane; + float distance_from_lineOriginProjectionOnPlane_to_intersectionPos = lineOriginProjectionOnPlane_to_intersectionPos.magnitude; + + Vector3 forward_insidePlane_normalized = default; + if (distance_from_lineOriginProjectionOnPlane_to_intersectionPos < 0.0001f) + { + //angle is approximately 90deg: + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref planeNormal_normalized, ref forward_insidePlane_normalized, true); + forward_insidePlane_normalized = plane.Get_projectionOfVectorOntoPlane(forward_insidePlane_normalized); + forward_insidePlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(forward_insidePlane_normalized); + } + else + { + forward_insidePlane_normalized = lineOriginProjectionOnPlane_to_intersectionPos / distance_from_lineOriginProjectionOnPlane_to_intersectionPos; + } + + float planeSize_nonExtended; + if (distance_from_lineOriginProjectionOnPlane_to_intersectionPos < 0.1f) + { + planeSize_nonExtended = 1.0f; + } + else + { + planeSize_nonExtended = 1.2f * distance_from_lineOriginProjectionOnPlane_to_intersectionPos; + } + planeSize_nonExtended = Mathf.Max(planeSize_nonExtended, 1.0f); + + float acuteAngle; + float obtuseAngle; + if (returnObtuseAngleOver90deg) + { + acuteAngle = UtilitiesDXXL_Measurements.Angle(false, false, false, intersection_towardsLine_normalized, -forward_insidePlane_normalized, intersectionPoint, color_lowerAlpha, radius, 0.0f, null, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + obtuseAngle = UtilitiesDXXL_Measurements.Angle(true, false, false, intersection_towardsLine_normalized, forward_insidePlane_normalized, intersectionPoint, color, radius, linesWidth, text, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + else + { + acuteAngle = UtilitiesDXXL_Measurements.Angle(true, false, false, intersection_towardsLine_normalized, -forward_insidePlane_normalized, intersectionPoint, color, radius, linesWidth, text, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + obtuseAngle = UtilitiesDXXL_Measurements.Angle(false, false, false, intersection_towardsLine_normalized, forward_insidePlane_normalized, intersectionPoint, color_lowerAlpha, radius, 0.0f, null, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) + { + return ReturnAngleOfCorrectAcuteObtuseType(obtuseAngle, acuteAngle, returnObtuseAngleOver90deg); + } + + //Draw plane: + float subSegments_signFlipsInterpretation = (-0.1f) * planeSize_nonExtended; //-> "negative sign" means "fixed world space size of segments" + float anchorVisualizationSize = 0.5f * planeSize_nonExtended; + DrawShapes.Plane(planeOrigin, planeNormal_normalized, intersectionPoint, planeColor, planeSize_nonExtended, planeSize_nonExtended, forward_insidePlane_normalized, 0.0f, null, subSegments_signFlipsInterpretation, false, anchorVisualizationSize, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + Vector3 textUp_normalized = Vector3.Cross(planeNormal_normalized, forward_insidePlane_normalized); + if ((planeName == null) || (planeName == "")) { planeName = "plane"; } + UtilitiesDXXL_Text.Write(planeName, intersectionPoint - 0.05f * planeSize_nonExtended * forward_insidePlane_normalized, planeColor, 0.05f * planeSize_nonExtended, -forward_insidePlane_normalized, textUp_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + + //Draw line: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorFrom(lineOrigin, lineDirection, defaultColor1, widthOfDirVector, DrawText.MarkupColor(lineIdentifyingText, colorOfAttachments), 0.17f, false, false, default(Vector3), true, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + + float lineExtentionPerSide = Mathf.Max(minimumLineLength_forAngleLineToPlane, 1.1f * distance_intersection_to_lineOrigin); + Line_fadeableAnimSpeed.InternalDraw(lineOrigin - line.direction_normalized * lineExtentionPerSide, lineOrigin + line.direction_normalized * lineExtentionPerSide, colorOfProlongedLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + UtilitiesDXXL_Measurements.WriteLineNameAtProjectionPlumbPos(false, lineName, "line", " ", intersection_to_lineOrigin, distance_intersection_to_lineOrigin, lineOrigins_projectionOnPlane, line, intersectionPoint, 0.08f * radius, colorOfProlongedLine, false, durationInSec, hiddenByNearerObjects); + + //Enforce line at radius of angleCone: + Vector3 posOnLine_whereAngleConeTouches = intersectionPoint + intersection_towardsLine_normalized * radius; + float halfLengthOfEnforcementLine = radius * 0.055f + 0.5f * linesWidth; + float widthOfEnforcementLine = radius * 0.003f; + Line_fadeableAnimSpeed.InternalDraw(posOnLine_whereAngleConeTouches - intersection_towardsLine_normalized * halfLengthOfEnforcementLine, posOnLine_whereAngleConeTouches + intersection_towardsLine_normalized * halfLengthOfEnforcementLine, color, widthOfEnforcementLine, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //Draw intersection pos coordinate: + UtilitiesDXXL_DrawBasics.Set_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_reversible(0); + DrawBasics.Point(intersectionPoint, "intersection
position", color, 0.025f * planeSize_nonExtended, 0.0f, color, default, false, true, false, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM(); + + //Draw circles at intersection pos: + DrawShapes.Decagon(intersectionPoint, radius * 0.02f, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 1.0f), planeNormal, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Decagon(intersectionPoint, radius * 0.04f, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.65f), planeNormal, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Circle(intersectionPoint, radius * 0.06f, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.35f), planeNormal, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Circle(intersectionPoint, radius * 0.08f, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.15f), planeNormal, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + return ReturnAngleOfCorrectAcuteObtuseType(obtuseAngle, acuteAngle, returnObtuseAngleOver90deg); + } + + static float ReturnAngleOfCorrectAcuteObtuseType(float obtuseAngle, float acuteAngle, bool returnObtuseAngleOver90deg) + { + if (returnObtuseAngleOver90deg) + { + return obtuseAngle; + } + else + { + return acuteAngle; + } + } + + public static float AnglePlaneToPlane(Transform plane1Transform, Transform plane2Transform, Color color = default(Color), float linesWidth = 0.0f, string text = null, string plane1Name = null, string plane2Name = null, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(plane1Transform, "plane1Transform")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(plane2Transform, "plane2Transform")) { return 0.0f; } + return AnglePlaneToPlane(plane1Transform.position, plane1Transform.up, plane2Transform.position, plane2Transform.up, color, linesWidth, text, plane1Name, plane2Name, returnObtuseAngleOver90deg, displayAndReturn_radInsteadOfDeg, coneLength, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + public static float AnglePlaneToPlane(Plane plane1, Plane plane2, Vector3 drawPositioinAsPlumb = default(Vector3), Color color = default(Color), float linesWidth = 0.0f, string text = null, string plane1Name = null, string plane2Name = null, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(drawPositioinAsPlumb, "drawPositioinAsPlumb")) { return 0.0f; } + drawPositioinAsPlumb = UtilitiesDXXL_Math.OverwriteDefaultVectors(drawPositioinAsPlumb, Vector3.zero); + + Vector3 closestPointOnPlane1 = plane1.ClosestPointOnPlane(drawPositioinAsPlumb); + Vector3 closestPointOnPlane2 = plane2.ClosestPointOnPlane(drawPositioinAsPlumb); + return AnglePlaneToPlane(closestPointOnPlane1, plane1.normal, closestPointOnPlane2, plane2.normal, color, linesWidth, text, plane1Name, plane2Name, returnObtuseAngleOver90deg, displayAndReturn_radInsteadOfDeg, coneLength, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + static InternalDXXL_Plane plane1 = new InternalDXXL_Plane(); + static InternalDXXL_Plane plane2 = new InternalDXXL_Plane(); + static InternalDXXL_Line intersectionLine = new InternalDXXL_Line(); + public static float AnglePlaneToPlane(Vector3 plane1Origin, Vector3 plane1Normal, Vector3 plane2Origin, Vector3 plane2Normal, Color color = default(Color), float linesWidth = 0.0f, string text = null, string plane1Name = null, string plane2Name = null, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0.0f; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(plane1Origin, "plane1Origin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(plane1Normal, "plane1Normal")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(plane2Origin, "plane2Origin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(plane2Normal, "plane2Normal")) { return 0.0f; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + if (UtilitiesDXXL_Math.ApproximatelyZero(plane1Normal)) + { + UtilitiesDXXL_DrawBasics.PointFallback(plane1Origin, "[ 'plane1Normal' is zero. AnglePlaneToPlane measure operation not executed.]
[plane1Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(plane2Origin, "[ 'plane1Normal' is zero. AnglePlaneToPlane measure operation not executed.]
[plane2Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(plane2Normal)) + { + UtilitiesDXXL_DrawBasics.PointFallback(plane1Origin, "[ 'plane2Normal' is zero. AnglePlaneToPlane measure operation not executed.]
[plane1Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(plane2Origin, "[ 'plane2Normal' is zero. AnglePlaneToPlane measure operation not executed.]
[plane2Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + Vector3 plane1Normal_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(plane1Normal); + Vector3 plane2Normal_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(plane2Normal); + + plane1.Recreate(plane1Origin, plane1Normal_normalized); + plane2.Recreate(plane2Origin, plane2Normal_normalized); + + Color plane1Color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor1, 0.5f); + Color plane2Color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(defaultColor2, 0.5f); + Color colorOfAdditionalAngle = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.55f); + + if ((plane1Name == null) || (plane1Name == "")) + { + plane1Name = "plane1"; + } + if ((plane2Name == null) || (plane2Name == "")) + { + plane2Name = "plane2"; + } + + if (Mathf.Abs(Vector3.Dot(plane1Normal_normalized, plane2Normal_normalized)) > 0.999999f) + { + //-> planes are approximately parallel + + //thresholds: + //"0.9999f" -> minDetectableAngle: 0.8deg + //"0.99999f" -> minDetectableAngle: 0.26deg + //"0.999999f" -> minDetectableAngle: 0.09deg + + Vector3 plane1Origins_projectionOnPlane2 = plane2.Get_perpProjectionOfPointOnPlane(plane1Origin); + float distance = UtilitiesDXXL_Measurements.Distance(false, UtilitiesDXXL_Measurements.DistanceSpecifyingStringType.plane_plane, plane1Origin, plane1Origins_projectionOnPlane2, color, linesWidth, "[ Planes are approximately parallel -> fallback from 'angle' to 'distance']
" + text, coneLength, 0.0f, durationInSec, hiddenByNearerObjects, false); + float bigPlaneSize = Mathf.Max(distance, 1.0f); + float smallPlaneSize = 0.2f * bigPlaneSize; + float textSize = 0.2f * smallPlaneSize; + + Vector3 forwardInsidePlane_normalized = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(plane1Normal_normalized); + Vector3 textDir_normalized = forwardInsidePlane_normalized; + Vector3 textUp_normalized = Vector3.Cross(forwardInsidePlane_normalized, plane1Normal_normalized); + + DrawShapes.Plane(plane1Origin, plane1Normal_normalized, plane2Origin, plane1Color, bigPlaneSize, bigPlaneSize, forwardInsidePlane_normalized, 0.0f, null, 10, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Plane(plane1Origin, plane1Normal_normalized, default, plane1Color, smallPlaneSize, smallPlaneSize, forwardInsidePlane_normalized, 0.0f, null, 10, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Text.Write(plane1Name, plane1Origin + textDir_normalized * (0.6f * smallPlaneSize), plane1Color, textSize, textDir_normalized, textUp_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + + DrawShapes.Plane(plane2Origin, plane2Normal_normalized, plane1Origins_projectionOnPlane2, plane2Color, bigPlaneSize, bigPlaneSize, forwardInsidePlane_normalized, 0.0f, null, 10, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Plane(plane1Origins_projectionOnPlane2, plane2Normal_normalized, default, plane2Color, smallPlaneSize, smallPlaneSize, forwardInsidePlane_normalized, 0.0f, null, 10, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Text.Write(plane2Name, plane1Origins_projectionOnPlane2 + textDir_normalized * (0.6f * smallPlaneSize), plane2Color, textSize, textDir_normalized, textUp_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + + return returnObtuseAngleOver90deg ? (displayAndReturn_radInsteadOfDeg ? (Mathf.Deg2Rad * 180.0f) : 180.0f) : 0.0f; + } + + InternalDXXL_Plane.Calc_intersectionLine_ofTwoPlanes(ref intersectionLine, plane1, plane2); + if (intersectionLine.ErrorLogForInvalidLineParameters() == false) + { + UtilitiesDXXL_DrawBasics.PointFallback(plane1Origin, "[ Couldn't calculate intersectionLine of the the planes. AnglePlaneToPlane measure operation not executed.]
[plane1Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.PointFallback(plane2Origin, "[ Couldn't calculate intersectionLine of the the planes. AnglePlaneToPlane measure operation not executed.]
[plane2Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + bool angleIsApproximately90Deg = (Mathf.Abs(Vector3.Dot(plane1Normal_normalized, plane2Normal_normalized)) < 0.0001f); + + Vector3 plane1origin_projectedOnLine = intersectionLine.Get_perpProjectionOfPoint_ontoThisLine(plane1Origin); + Vector3 intersectionPos1_to_plane1Origin = plane1Origin - plane1origin_projectedOnLine; + float distance_intersection1_to_plane1Origin = intersectionPos1_to_plane1Origin.magnitude; + + Vector3 plane2origin_projectedOnLine = intersectionLine.Get_perpProjectionOfPoint_ontoThisLine(plane2Origin); + Vector3 intersectionPos2_to_plane2Origin = plane2Origin - plane2origin_projectedOnLine; + float distance_intersection2_to_plane2Origin = intersectionPos2_to_plane2Origin.magnitude; + + Vector3 angleCenterPos; + Vector3 intersection_towardsPlane1_normalized; + Vector3 intersection_towardsPlane2_normalized; + float radius = 0.2f; + + if (distance_intersection1_to_plane1Origin < 0.0001f) + { + if (distance_intersection2_to_plane2Origin < 0.0001f) + { + //both planeOrigins lie on intersectionLine: + angleCenterPos = plane1Origin; + Vector3 aNormalizedVector_perpToLine = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(intersectionLine.direction_normalized); + Quaternion seldomRotation_aroundLine = Quaternion.AngleAxis(UtilitiesDXXL_Math.arbitrarySeldomDir_precalced.x, intersectionLine.direction_normalized); + Vector3 aSeldomNormalizedVector_perpToLine = seldomRotation_aroundLine * aNormalizedVector_perpToLine; + intersection_towardsPlane1_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(plane1.Get_projectionOfVectorOntoPlane(aSeldomNormalizedVector_perpToLine)); + if (angleIsApproximately90Deg) + { + Quaternion rotation90deg = Quaternion.AngleAxis(90.0f, intersectionLine.direction_normalized); + intersection_towardsPlane2_normalized = rotation90deg * intersection_towardsPlane1_normalized; + } + else + { + intersection_towardsPlane2_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(plane2.Get_projectionOfVectorOntoPlane(intersection_towardsPlane1_normalized)); + } + } + else + { + //plane1Origin lies on intersectionLine, but plane2Origin NOT: + radius = 0.5f * distance_intersection2_to_plane2Origin; + angleCenterPos = plane2origin_projectedOnLine; + intersection_towardsPlane2_normalized = intersectionPos2_to_plane2Origin / distance_intersection2_to_plane2Origin; + if (angleIsApproximately90Deg) + { + Quaternion rotation90deg = Quaternion.AngleAxis(90.0f, intersectionLine.direction_normalized); + intersection_towardsPlane1_normalized = rotation90deg * intersection_towardsPlane2_normalized; + } + else + { + intersection_towardsPlane1_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(plane1.Get_projectionOfVectorOntoPlane(intersection_towardsPlane2_normalized)); + } + } + } + else + { + //plane1Origin does NOT lie on intersectionLine: + if (distance_intersection2_to_plane2Origin < 0.0001f) + { + //plane2Origin lies on intersectionLine, but plane1Origin NOT: + radius = 0.5f * distance_intersection1_to_plane1Origin; + } + else + { + //both planeOrigins do NOT lie on intersectionLine: + float averageDistance_intersections_to_planeOrigins = 0.5f * (distance_intersection1_to_plane1Origin + distance_intersection2_to_plane2Origin); + radius = 0.5f * averageDistance_intersections_to_planeOrigins; + } + + angleCenterPos = plane1origin_projectedOnLine; + intersection_towardsPlane1_normalized = intersectionPos1_to_plane1Origin / distance_intersection1_to_plane1Origin; + if (angleIsApproximately90Deg) + { + Quaternion rotation90deg = Quaternion.AngleAxis(90.0f, intersectionLine.direction_normalized); + intersection_towardsPlane2_normalized = rotation90deg * intersection_towardsPlane1_normalized; + } + else + { + intersection_towardsPlane2_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(plane2.Get_projectionOfVectorOntoPlane(intersection_towardsPlane1_normalized)); + } + } + + radius = Mathf.Max(radius, 0.2f); + float approxPlane1Length; + if (distance_intersection1_to_plane1Origin < 0.1f) + { + approxPlane1Length = 1.0f + (2.0f * radius); + } + else + { + approxPlane1Length = 1.2f * distance_intersection1_to_plane1Origin + (2.0f * radius); + } + + float approxPlane2Length; + if (distance_intersection2_to_plane2Origin < 0.1f) + { + approxPlane2Length = 1.0f + (2.0f * radius); + } + else + { + approxPlane2Length = 1.2f * distance_intersection2_to_plane2Origin + (2.0f * radius); + } + + float approxPlaneLength = Mathf.Max(approxPlane1Length, approxPlane2Length); + approxPlaneLength = Mathf.Max(approxPlaneLength, 2.5f * radius); + approxPlaneLength = Mathf.Max(approxPlaneLength, 1.0f); + + float distance_betweenTheTwoProjectionsOntoTheIntersectionLine = (plane1origin_projectedOnLine - plane2origin_projectedOnLine).magnitude; + float planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine = 0.25f * distance_betweenTheTwoProjectionsOntoTheIntersectionLine; + planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine = Mathf.Max(planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine, 1.0f); + + float angleDeg_towards1_to_towards2 = Vector3.Angle(intersection_towardsPlane1_normalized, intersection_towardsPlane2_normalized); + + float acuteAngle; + float obtuseAngle; + if (angleIsApproximately90Deg || angleDeg_towards1_to_towards2 < 90.0f) + { + //towards1-to-towards2 is acute: + if (returnObtuseAngleOver90deg) + { + acuteAngle = UtilitiesDXXL_Measurements.Angle(false, false, false, intersection_towardsPlane1_normalized, intersection_towardsPlane2_normalized, angleCenterPos, colorOfAdditionalAngle, radius, 0.0f, null, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + obtuseAngle = UtilitiesDXXL_Measurements.Angle(true, false, false, intersection_towardsPlane1_normalized, -intersection_towardsPlane2_normalized, angleCenterPos, color, radius, linesWidth, text, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + else + { + acuteAngle = UtilitiesDXXL_Measurements.Angle(true, false, false, intersection_towardsPlane1_normalized, intersection_towardsPlane2_normalized, angleCenterPos, color, radius, linesWidth, text, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + obtuseAngle = UtilitiesDXXL_Measurements.Angle(false, false, false, intersection_towardsPlane1_normalized, -intersection_towardsPlane2_normalized, angleCenterPos, colorOfAdditionalAngle, radius, 0.0f, null, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + } + else + { + //towards1-to-towards2 is obtuse: + if (returnObtuseAngleOver90deg) + { + acuteAngle = UtilitiesDXXL_Measurements.Angle(false, false, false, intersection_towardsPlane1_normalized, -intersection_towardsPlane2_normalized, angleCenterPos, colorOfAdditionalAngle, radius, 0.0f, null, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + obtuseAngle = UtilitiesDXXL_Measurements.Angle(true, false, false, intersection_towardsPlane1_normalized, intersection_towardsPlane2_normalized, angleCenterPos, color, radius, linesWidth, text, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + else + { + acuteAngle = UtilitiesDXXL_Measurements.Angle(true, false, false, intersection_towardsPlane1_normalized, -intersection_towardsPlane2_normalized, angleCenterPos, color, radius, linesWidth, text, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + obtuseAngle = UtilitiesDXXL_Measurements.Angle(false, false, false, intersection_towardsPlane1_normalized, intersection_towardsPlane2_normalized, angleCenterPos, colorOfAdditionalAngle, radius, 0.0f, null, false, displayAndReturn_radInsteadOfDeg, coneLength, true, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + } + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) + { + return ReturnAngleOfCorrectAcuteObtuseType(obtuseAngle, acuteAngle, returnObtuseAngleOver90deg); + } + + //Draw circles as angle display mounting point: + Vector3 position_ofMountingPointDisplayCircle = angleCenterPos + intersection_towardsPlane1_normalized * radius; + Vector3 normal_ofMountingPointDisplayCircle = plane1Normal_normalized; + DrawShapes.Decagon(position_ofMountingPointDisplayCircle, radius * 0.02f, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 1.0f), normal_ofMountingPointDisplayCircle, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Decagon(position_ofMountingPointDisplayCircle, radius * 0.04f, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.65f), normal_ofMountingPointDisplayCircle, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Circle(position_ofMountingPointDisplayCircle, radius * 0.06f, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.35f), normal_ofMountingPointDisplayCircle, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Circle(position_ofMountingPointDisplayCircle, radius * 0.08f, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.15f), normal_ofMountingPointDisplayCircle, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + //Draw planes: + Vector3 pos_between_theTwoLineProjectedPlaneOrigins = 0.5f * (plane1origin_projectedOnLine + plane2origin_projectedOnLine); + float anchorVisualizationSize = 0.5f * planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine; + float subSegments_signFlipsInterpretation = (-0.1f) * planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine; //-> "negative sign" means "fixed world space size of segments" + + DrawShapes.Plane(plane1Origin, plane1Normal_normalized, plane2origin_projectedOnLine, plane1Color, planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine, planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine, intersection_towardsPlane1_normalized, 0.0f, null, subSegments_signFlipsInterpretation, false, anchorVisualizationSize, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Text.Write(plane1Name, angleCenterPos - 0.05f * approxPlaneLength * intersection_towardsPlane1_normalized, plane1Color, 0.05f * approxPlaneLength, -intersection_towardsPlane1_normalized, intersectionLine.direction_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + + DrawShapes.Plane(plane2Origin, plane2Normal_normalized, plane1origin_projectedOnLine, plane2Color, planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine, planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine, intersection_towardsPlane2_normalized, 0.0f, null, subSegments_signFlipsInterpretation, false, anchorVisualizationSize, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Text.Write(plane2Name, angleCenterPos - 0.05f * approxPlaneLength * intersection_towardsPlane2_normalized, plane2Color, 0.05f * approxPlaneLength, -intersection_towardsPlane2_normalized, intersectionLine.direction_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + + //Draw additional emphasizing planes around intersectionline: + float length_ofAdditialPlanes = 0.3f * radius; + DrawShapes.Plane(plane1origin_projectedOnLine, plane1Normal_normalized, plane2origin_projectedOnLine, plane1Color, planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine, length_ofAdditialPlanes, intersection_towardsPlane1_normalized, 0.0f, null, 10, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Plane(plane2origin_projectedOnLine, plane2Normal_normalized, plane1origin_projectedOnLine, plane2Color, planeWidth_thatProtrudesTheTwoProjectionsOnIntersectionLine, length_ofAdditialPlanes, intersection_towardsPlane2_normalized, 0.0f, null, 10, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + //Draw the emphasized intersection line: + float lineWidth_ofIntersectionLineVisualization = 0.01f * radius; + Vector3 intersectionLineVector_withLengthOfHalfWidthOfDisplayedPlanes = intersectionLine.direction_normalized * 0.5f * UtilitiesDXXL_Shapes.finalWidth_ofLastDrawnPlane; + DrawBasics.Line(pos_between_theTwoLineProjectedPlaneOrigins - intersectionLineVector_withLengthOfHalfWidthOfDisplayedPlanes, pos_between_theTwoLineProjectedPlaneOrigins + intersectionLineVector_withLengthOfHalfWidthOfDisplayedPlanes, color, lineWidth_ofIntersectionLineVisualization, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + return ReturnAngleOfCorrectAcuteObtuseType(obtuseAngle, acuteAngle, returnObtuseAngleOver90deg); + } + + public static void DistanceThreshold(Vector3 startPos, Vector3 endPos, float thresholdDistance, string text = null, bool displayDistanceAlsoAsText = false, float lineWidth = 0.0f, bool exactlyThresholdLength_countsAsShorter = true, float endPlates_size = 0.0f, DrawBasics.LineStyle overwriteStyle_forNear = DrawBasics.LineStyle.electricNoise, DrawBasics.LineStyle overwriteStyle_forFar = DrawBasics.LineStyle.solid, Color overwriteColor_forNear = default(Color), Color overwriteColor_forFar = default(Color), Vector3 customAmplitudeAndTextDir = default(Vector3), float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(thresholdDistance, "thresholdDistance")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPos, "startPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(endPos, "endPos")) { return; } + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(startPos, endPos)) + { + UtilitiesDXXL_DrawBasics.PointFallback(startPos, "[ DistanceThreshold with distance of 0]
" + text, UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forNear, UtilitiesDXXL_Colors.red_boolFalse), lineWidth, durationInSec, hiddenByNearerObjects); + return; + } + + Color usedColor = new Color(); + DrawBasics.LineStyle usedLineStyle = DrawBasics.LineStyle.solid; + float distance = (endPos - startPos).magnitude; + float stylePatternScaleFactor = distance; + + if (displayDistanceAlsoAsText) + { + text = string.IsNullOrEmpty(text) ? ("distance =
" + distance) : ("distance =
" + distance + "
" + text); + } + + UtilitiesDXXL_Measurements.ChooseColorAndStyleForDistanceThresholdLine(ref usedColor, ref usedLineStyle, distance, thresholdDistance, exactlyThresholdLength_countsAsShorter, overwriteStyle_forNear, overwriteStyle_forFar, overwriteColor_forNear, overwriteColor_forFar); + + UtilitiesDXXL_DrawBasics.Set_relSizeOfTextOnLines_reversible(0.65f); + UtilitiesDXXL_DrawBasics.Set_shiftTextPosOnLines_toNonIntersecting_reversible(true); + UtilitiesDXXL_DrawBasics.Line(startPos, endPos, usedColor, lineWidth, text, usedLineStyle, stylePatternScaleFactor, 0.0f, null, customAmplitudeAndTextDir, false, 0.0f, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, true, true, null, false, endPlates_size); + UtilitiesDXXL_DrawBasics.Reverse_relSizeOfTextOnLines(); + UtilitiesDXXL_DrawBasics.Reverse_shiftTextPosOnLines_toNonIntersecting(); + } + + public static void DistanceThresholds(Vector3 startPos, Vector3 endPos, float smallerThresholdDistance, float biggerThresholdDistance, string text = null, bool displayDistanceAlsoAsText = false, float lineWidth = 0.0f, bool exactlyThresholdLength_countsAsShorter = true, float endPlates_size = 0.0f, DrawBasics.LineStyle overwriteStyle_forNear = DrawBasics.LineStyle.electricNoise, DrawBasics.LineStyle overwriteStyle_forMiddle = DrawBasics.LineStyle.electricImpulses, DrawBasics.LineStyle overwriteStyle_forFar = DrawBasics.LineStyle.solid, Color overwriteColor_forNear = default(Color), Color overwriteColor_forMiddle = default(Color), Color overwriteColor_forFar = default(Color), Vector3 customAmplitudeAndTextDir = default(Vector3), float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(smallerThresholdDistance, "smallerThresholdDistance")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(biggerThresholdDistance, "biggerThresholdDistance")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPos, "startPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(endPos, "endPos")) { return; } + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(startPos, endPos)) + { + UtilitiesDXXL_DrawBasics.PointFallback(startPos, "[ DistanceThresholds with distance of 0]
" + text, UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forNear, UtilitiesDXXL_Colors.red_boolFalse), lineWidth, durationInSec, hiddenByNearerObjects); + return; + } + + if (smallerThresholdDistance > biggerThresholdDistance) + { + text = "[ threshold distances are automatically flipped: smaller (" + smallerThresholdDistance + " -> " + biggerThresholdDistance + ") / bigger (" + biggerThresholdDistance + " -> " + smallerThresholdDistance + ")]
" + text; + float smallerClipboard = smallerThresholdDistance; + smallerThresholdDistance = biggerThresholdDistance; + biggerThresholdDistance = smallerClipboard; + } + + Color usedColor = new Color(); + DrawBasics.LineStyle usedLineStyle = DrawBasics.LineStyle.solid; + float distance = (endPos - startPos).magnitude; + float stylePatternScaleFactor = distance; + + if (displayDistanceAlsoAsText) + { + text = string.IsNullOrEmpty(text) ? ("distance =
" + distance) : ("distance =
" + distance + "
" + text); + } + + UtilitiesDXXL_Measurements.ChooseColorAndStyleForDistanceThresholdsLine(ref usedColor, ref usedLineStyle, distance, smallerThresholdDistance, biggerThresholdDistance, exactlyThresholdLength_countsAsShorter, overwriteStyle_forNear, overwriteStyle_forMiddle, overwriteStyle_forFar, overwriteColor_forNear, overwriteColor_forMiddle, overwriteColor_forFar); + + UtilitiesDXXL_DrawBasics.Set_relSizeOfTextOnLines_reversible(0.65f); + UtilitiesDXXL_DrawBasics.Set_shiftTextPosOnLines_toNonIntersecting_reversible(true); + UtilitiesDXXL_DrawBasics.Line(startPos, endPos, usedColor, lineWidth, text, usedLineStyle, stylePatternScaleFactor, 0.0f, null, customAmplitudeAndTextDir, false, 0.0f, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, true, true, null, false, endPlates_size); + UtilitiesDXXL_DrawBasics.Reverse_relSizeOfTextOnLines(); + UtilitiesDXXL_DrawBasics.Reverse_shiftTextPosOnLines_toNonIntersecting(); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/DrawMeasurements.cs.meta b/Runtime/DrawDebugLibrary/DrawMeasurements.cs.meta new file mode 100644 index 0000000..7a97ca5 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawMeasurements.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4ea9a952ec8d7154c9419ddd7735548e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawMeasurements2D.cs b/Runtime/DrawDebugLibrary/DrawMeasurements2D.cs new file mode 100644 index 0000000..efce944 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawMeasurements2D.cs @@ -0,0 +1,404 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class DrawMeasurements2D + { + public static float minimumLineLength_forDistancePointToLine = 1000.0f; + public static float minimumLineLength_forAngleLineToLine = 1000.0f; + + public static float Distance(Vector2 from, Vector2 to, Color color = default(Color), float lineWidth = 0.0f, string text = null, float custom_zPos = float.PositiveInfinity, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 fromV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(from, zPos); + Vector3 toV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(to, zPos); + return UtilitiesDXXL_Measurements.Distance(true, UtilitiesDXXL_Measurements.DistanceSpecifyingStringType.point_point, fromV3, toV3, color, lineWidth, text, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, false); + } + + public static float Angle(Vector2 from, Vector2 to, Vector2 turnCenter, Color color = default(Color), float forceRadius = 0.0f, float lineWidth = 0.0f, string text = null, float custom_zPos = float.PositiveInfinity, bool useReflexAngleOver180deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool drawBoundaryLines = true, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 turnCenterV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(turnCenter, zPos); + Vector3 fromV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(from); + Vector3 toV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(to); + return UtilitiesDXXL_Measurements.Angle(false, true, false, fromV3, toV3, turnCenterV3, color, forceRadius, lineWidth, text, useReflexAngleOver180deg, displayAndReturn_radInsteadOfDeg, coneLength, drawBoundaryLines, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + public static float AngleSpan(Vector2 from, Vector2 to, Vector2 turnCenter, Color color = default(Color), float forceRadius = 0.0f, float lineWidth = 0.0f, string text = null, float custom_zPos = float.PositiveInfinity, bool useReflexAngleOver180deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool drawBoundaryLines = true, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 turnCenterV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(turnCenter, zPos); + Vector3 fromV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(from); + Vector3 toV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(to); + return UtilitiesDXXL_Measurements.Angle(false, true, true, fromV3, toV3, turnCenterV3, color, forceRadius, lineWidth, text, useReflexAngleOver180deg, displayAndReturn_radInsteadOfDeg, coneLength, drawBoundaryLines, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + public static float DistancePointToLine(Vector2 point, Ray2D line, Color color = default(Color), float linesWidth = 0.0f, string text = null, string lineName = null, float custom_zPos = float.PositiveInfinity, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return DistancePointToLine(point, line.origin, line.direction, color, linesWidth, text, lineName, custom_zPos, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + static InternalDXXL_Line line_3D = new InternalDXXL_Line(); + public static float DistancePointToLine(Vector2 point, Vector2 lineOrigin, Vector2 lineDirection, Color color = default(Color), float linesWidth = 0.0f, string text = null, string lineName = null, float custom_zPos = float.PositiveInfinity, float coneLength = 0.10f, float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0.0f; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(point, "point")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(lineOrigin, "lineOrigin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(lineDirection, "lineDirection")) { return 0.0f; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + if (UtilitiesDXXL_Math.ApproximatelyZero(lineDirection)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(point, zPos, "[ 'lineDirection' is zero. DistancePointToLine2D measure operation not executed.]
[point]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics2D.PointFallback(lineOrigin, zPos, "[ 'lineDirection' is zero. DistancePointToLine2D measure operation not executed.]
[lineOrigin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + Vector3 pointV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(point, zPos); + Vector3 lineOriginV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(lineOrigin, zPos); + Vector3 lineDirectionV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(lineDirection); + + line_3D.Recreate(lineOriginV3, lineDirectionV3, false); + Vector3 pointsProjectionOntoLine = line_3D.Get_perpProjectionOfPoint_ontoThisLine(pointV3); + + //Draw distance: + bool skipDrawing = DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped(); + float distance = UtilitiesDXXL_Measurements.Distance(true, UtilitiesDXXL_Measurements.DistanceSpecifyingStringType.point_line, pointV3, pointsProjectionOntoLine, color, linesWidth, text, coneLength, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipDrawing); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return distance; } + + //Draw line: + string lineIdentifyingText = ((lineName == null) || (lineName == "")) ? "line direction" : lineName; + float widthOfDirVector = UtilitiesDXXL_Math.ApproximatelyZero(linesWidth) ? 0.01f : (0.6f * linesWidth); + Color colorOfProlongedLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawMeasurements.defaultColor2, 0.55f); + Color colorOfAttachments = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawMeasurements.defaultColor2, 0.35f); + DrawBasics2D.VectorFrom(lineOriginV3, lineDirectionV3, DrawMeasurements.defaultColor2, widthOfDirVector, DrawText.MarkupColor(lineIdentifyingText, colorOfAttachments), coneLength * 1.7f, false, zPos, true, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + + Vector3 projectionToLineOrigin = line_3D.origin - pointsProjectionOntoLine; + float distance_projectionToLineOrigin = projectionToLineOrigin.magnitude; + float lineExtentionPerSide = Mathf.Max(minimumLineLength_forDistancePointToLine, 1.1f * distance_projectionToLineOrigin); + Line_fadeableAnimSpeed.InternalDraw(lineOriginV3 - line_3D.direction_normalized * lineExtentionPerSide, lineOriginV3 + line_3D.direction_normalized * lineExtentionPerSide, colorOfProlongedLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + UtilitiesDXXL_Measurements.WriteLineNameAtProjectionPlumbPos(true, lineName, "line", "", projectionToLineOrigin, distance_projectionToLineOrigin, pointV3, line_3D, pointsProjectionOntoLine, 0.02f * distance, colorOfProlongedLine, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Measurements.Draw90degSymbol(distance, pointsProjectionOntoLine, pointV3, line_3D.direction_normalized, colorOfAttachments, durationInSec, hiddenByNearerObjects); + + return distance; + } + + public static float AngleLineToLine(Ray2D line1, Ray2D line2, Color color = default(Color), float linesWidth = 0.0f, string text = null, string line1Name = null, string line2Name = null, float custom_zPos = float.PositiveInfinity, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + return AngleLineToLine(line1.origin, line1.direction, line2.origin, line2.direction, color, linesWidth, text, line1Name, line2Name, custom_zPos, returnObtuseAngleOver90deg, displayAndReturn_radInsteadOfDeg, coneLength, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + + static InternalDXXL_Line line1_3D = new InternalDXXL_Line(); + static InternalDXXL_Line line2_3D = new InternalDXXL_Line(); + static InternalDXXL_Line2D line1_2D = new InternalDXXL_Line2D(); + static InternalDXXL_Line2D line2_2D = new InternalDXXL_Line2D(); + public static float AngleLineToLine(Vector2 line1Origin, Vector2 line1Direction, Vector2 line2Origin, Vector2 line2Direction, Color color = default(Color), float linesWidth = 0.0f, string text = null, string line1Name = null, string line2Name = null, float custom_zPos = float.PositiveInfinity, bool returnObtuseAngleOver90deg = false, bool displayAndReturn_radInsteadOfDeg = false, float coneLength = 0.13f, bool addTextForAlternativeAngleUnit = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0.0f; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(line1Origin, "line1Origin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(line1Direction, "line1Direction")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(line2Origin, "line2Origin")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(line2Direction, "line2Direction")) { return 0.0f; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + if (UtilitiesDXXL_Math.ApproximatelyZero(line1Direction)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(line1Origin, zPos, "[ 'line1Direction' is zero. AngleLineToLine measure operation not executed.]
[line1Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics2D.PointFallback(line2Origin, zPos, "[ 'line1Direction' is zero. AngleLineToLine measure operation not executed.]
[line2Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(line2Direction)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(line1Origin, zPos, "[ 'line2Direction' is zero. AngleLineToLine measure operation not executed.]
[line1Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics2D.PointFallback(line2Origin, zPos, "[ 'line2Direction' is zero. AngleLineToLine measure operation not executed.]
[line2Origin]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + float length_ofLine1Direction; + float length_ofLine2Direction; + Vector2 line1_direction_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(line1Direction, out length_ofLine1Direction); + Vector2 line2_direction_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(line2Direction, out length_ofLine2Direction); + + float alphaFactor_ofProlongedLines = 0.55f; + float alphaFactor_ofLineAttachments = 0.35f; + Color colorOfProlongedLine1 = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawMeasurements.defaultColor1, alphaFactor_ofProlongedLines); + Color colorOfProlongedLine2 = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawMeasurements.defaultColor2, alphaFactor_ofProlongedLines); + Color colorOfLine1Attachments = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawMeasurements.defaultColor1, alphaFactor_ofLineAttachments); + Color colorOfLine2Attachments = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawMeasurements.defaultColor2, alphaFactor_ofLineAttachments); + + string line1IdentifyingText = ((line1Name == null) || (line1Name == "")) ? "line1 direction" : line1Name; + string line2IdentifyingText = ((line2Name == null) || (line2Name == "")) ? "line2 direction" : line2Name; + + float widthOfDirVector = UtilitiesDXXL_Math.ApproximatelyZero(linesWidth) ? 0.01f : (0.6f * linesWidth); + + //->calculation falls back to line-3D, because it is more precise + Vector3 line1OriginV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(line1Origin, zPos); + Vector3 line2OriginV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(line2Origin, zPos); + Vector3 line1DirectionV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(line1Direction); + Vector3 line2DirectionV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(line2Direction); + line1_3D.Recreate(line1OriginV3, line1DirectionV3, false); + line2_3D.Recreate(line2OriginV3, line2DirectionV3, false); + + bool linesAreApproxParallel = CheckIfLinesAreApproxParallel(out float displayedAndReturnedAngle_forParallelLines, returnObtuseAngleOver90deg, displayAndReturn_radInsteadOfDeg, line1Direction, line2Direction); + if (linesAreApproxParallel) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return displayedAndReturnedAngle_forParallelLines; } + float distanceBetweenLines = line1_3D.Get_perpDistance_ofGivenPoint_toThisLine(line2OriginV3); + if (distanceBetweenLines < 0.001f) + { + //parallel and coinciding lines: + line1IdentifyingText = line1IdentifyingText + "

[ AngleLineToLine:
The two lines
lie approximately
parallel on top
of each other]"; + float distanceBetweenLineOrigins = (line1Origin - line2Origin).magnitude; + if (distanceBetweenLineOrigins > Mathf.Max(length_ofLine1Direction, length_ofLine2Direction)) + { + line2IdentifyingText = line2IdentifyingText + "

[ AngleLineToLine:
The two lines
lie approximately
parallel on top
of each other]"; + } + } + else + { + //parallel lines with distance (not coinciding): + Vector3 line2origin_projectedOntoLine1 = line1_3D.Get_perpProjectionOfPoint_ontoThisLine(line2OriginV3); + Vector3 line1Origin_to_line2OriginOnLine1 = line2origin_projectedOntoLine1 - line1OriginV3; + float distanceBetweenLineOrigins_alongLineDir = line1Origin_to_line2OriginOnLine1.magnitude; + + string textForDistanceFallback = "[ AngleLineToLine:
The two lines are
approximately parallel
-> Fallback to 'Distance()']

" + text; + if (distanceBetweenLineOrigins_alongLineDir < 5.0f) + { + Vector3 centerBetweenLineOrigins_onLine1 = line1OriginV3 + 0.5f * line1Origin_to_line2OriginOnLine1; + Distance(centerBetweenLineOrigins_onLine1, line2_3D.Get_perpProjectionOfPoint_ontoThisLine(centerBetweenLineOrigins_onLine1), color, linesWidth, textForDistanceFallback, zPos, coneLength, 0.005f, durationInSec, hiddenByNearerObjects); + } + else + { + Distance(line1OriginV3, line2_3D.Get_perpProjectionOfPoint_ontoThisLine(line1OriginV3), color, linesWidth, textForDistanceFallback, zPos, coneLength, 0.005f, durationInSec, hiddenByNearerObjects); + Distance(line1_3D.Get_perpProjectionOfPoint_ontoThisLine(line2OriginV3), line2OriginV3, color, linesWidth, textForDistanceFallback, zPos, coneLength, 0.005f, durationInSec, hiddenByNearerObjects); + } + } + + //Draw lineVectors: + DrawBasics2D.VectorFrom(line1Origin, line1Direction, colorOfProlongedLine1, widthOfDirVector, line1IdentifyingText, coneLength, false, zPos, true, 0.005f, false, 0.0f, durationInSec, hiddenByNearerObjects); + DrawBasics2D.VectorFrom(line2Origin, line2Direction, colorOfProlongedLine2, widthOfDirVector, line2IdentifyingText, coneLength, false, zPos, true, 0.005f, false, 0.0f, durationInSec, hiddenByNearerObjects); + + //Draw lineExtentions: + float lineExtentionPerSide = UtilitiesDXXL_Math.Max(minimumLineLength_forAngleLineToLine, line1Origin.magnitude, line2Origin.magnitude); + Line_fadeableAnimSpeed_2D.InternalDraw(line1Origin, line1Origin - line1_direction_normalized * lineExtentionPerSide, colorOfProlongedLine1, 0.0f, null, DrawBasics.LineStyle.solid, zPos, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed_2D.InternalDraw(line1Origin, line1Origin + line1_direction_normalized * lineExtentionPerSide, colorOfProlongedLine1, 0.0f, null, DrawBasics.LineStyle.solid, zPos, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed_2D.InternalDraw(line2Origin, line2Origin - line2_direction_normalized * lineExtentionPerSide, colorOfProlongedLine2, 0.0f, null, DrawBasics.LineStyle.solid, zPos, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed_2D.InternalDraw(line2Origin, line2Origin + line2_direction_normalized * lineExtentionPerSide, colorOfProlongedLine2, 0.0f, null, DrawBasics.LineStyle.solid, zPos, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + return displayedAndReturnedAngle_forParallelLines; + } + else + { + //-> lines are not parallel + + Vector2 intersectionPos = line1_3D.Get_posOnLine_thatIsNearestTo_passingOtherLine(line2_3D); + Vector2 intersectionToLine1Origin = line1Origin - intersectionPos; + Vector2 intersectionToLine2Origin = line2Origin - intersectionPos; + float distance_intersection_to_line1origin = intersectionToLine1Origin.magnitude; + float distance_intersection_to_line2origin = intersectionToLine2Origin.magnitude; + Vector2 intersectionTowardsLine1 = UtilitiesDXXL_Math.ApproximatelyZero(intersectionToLine1Origin) ? line1Direction : intersectionToLine1Origin; + Vector2 intersectionTowardsLine2 = UtilitiesDXXL_Math.ApproximatelyZero(intersectionToLine2Origin) ? line2Direction : intersectionToLine2Origin; + + //Draw lineVectors: + DrawBasics2D.VectorFrom(line1Origin, line1Direction, colorOfProlongedLine1, widthOfDirVector, DrawText.MarkupColor(line1IdentifyingText, colorOfProlongedLine1), coneLength, false, zPos, true, 0.005f, false, 0.0f, durationInSec, hiddenByNearerObjects); + DrawBasics2D.VectorFrom(line2Origin, line2Direction, colorOfProlongedLine2, widthOfDirVector, DrawText.MarkupColor(line2IdentifyingText, colorOfProlongedLine2), coneLength, false, zPos, true, 0.005f, false, 0.0f, durationInSec, hiddenByNearerObjects); + + //Draw lineExtentions: + float lineExtentionPerSide = UtilitiesDXXL_Math.Max(minimumLineLength_forAngleLineToLine, line1Origin.magnitude, line2Origin.magnitude, 1.1f * distance_intersection_to_line1origin, 1.1f * distance_intersection_to_line2origin); + Line_fadeableAnimSpeed_2D.InternalDraw(line1Origin, line1Origin - line1_direction_normalized * lineExtentionPerSide, colorOfProlongedLine1, 0.0f, null, DrawBasics.LineStyle.solid, zPos, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed_2D.InternalDraw(line1Origin, line1Origin + line1_direction_normalized * lineExtentionPerSide, colorOfProlongedLine1, 0.0f, null, DrawBasics.LineStyle.solid, zPos, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed_2D.InternalDraw(line2Origin, line2Origin - line2_direction_normalized * lineExtentionPerSide, colorOfProlongedLine2, 0.0f, null, DrawBasics.LineStyle.solid, zPos, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed_2D.InternalDraw(line2Origin, line2Origin + line2_direction_normalized * lineExtentionPerSide, colorOfProlongedLine2, 0.0f, null, DrawBasics.LineStyle.solid, zPos, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //Draw Angle Display: + float angleDeg_towards1toTowards2 = Vector2.Angle(intersectionTowardsLine1, intersectionTowardsLine2); + bool towards1_to_towards2_isAcuteBelow90deg = angleDeg_towards1toTowards2 <= 90.0f; + float radius = Mathf.Min(0.5f * distance_intersection_to_line1origin, 0.5f * distance_intersection_to_line2origin); + radius = Mathf.Max(radius, 0.3f); + // if (text != null) { text = DrawText.MarkupSize(text, 4); } + if (text != null) { text = "
" + text + ""; } + + float returnedAngle; + if (returnObtuseAngleOver90deg) + { + if (towards1_to_towards2_isAcuteBelow90deg) + { + returnedAngle = Angle(intersectionTowardsLine1, -intersectionTowardsLine2, intersectionPos, color, radius, linesWidth, text, zPos, false, displayAndReturn_radInsteadOfDeg, coneLength, false, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + else + { + returnedAngle = Angle(intersectionTowardsLine1, intersectionTowardsLine2, intersectionPos, color, radius, linesWidth, text, zPos, false, displayAndReturn_radInsteadOfDeg, coneLength, false, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + } + else + { + if (towards1_to_towards2_isAcuteBelow90deg) + { + returnedAngle = Angle(intersectionTowardsLine1, intersectionTowardsLine2, intersectionPos, color, radius, linesWidth, text, zPos, false, displayAndReturn_radInsteadOfDeg, coneLength, false, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + else + { + returnedAngle = Angle(intersectionTowardsLine1, -intersectionTowardsLine2, intersectionPos, color, radius, linesWidth, text, zPos, false, displayAndReturn_radInsteadOfDeg, coneLength, false, addTextForAlternativeAngleUnit, durationInSec, hiddenByNearerObjects); + } + } + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return returnedAngle; } + + //Draw intersectionPos accentuating lines: + lineExtentionPerSide = radius * 0.1f; + float widthOfLineAccentuation = 0.015f * lineExtentionPerSide; + Vector2 halfLine1ExtentionVector = line1_direction_normalized * lineExtentionPerSide; + Vector2 halfLine2ExtentionVector = line2_direction_normalized * lineExtentionPerSide; + Line_fadeableAnimSpeed_2D.InternalDraw(intersectionPos - halfLine1ExtentionVector, intersectionPos + halfLine1ExtentionVector, colorOfProlongedLine1, widthOfLineAccentuation, null, DrawBasics.LineStyle.solid, zPos, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed_2D.InternalDraw(intersectionPos - halfLine2ExtentionVector, intersectionPos + halfLine2ExtentionVector, colorOfProlongedLine2, widthOfLineAccentuation, null, DrawBasics.LineStyle.solid, zPos, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + DrawBasics2D.Circle(intersectionPos, radius * 0.01f, color, 0.0f, null, DrawBasics.LineStyle.solid, zPos, 1.0f, DrawBasics.LineStyle.invisible, false, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_DrawBasics.Set_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_reversible(0); + DrawBasics2D.Point(intersectionPos, color, radius * 0.2f, 0.0f, 0.0f, null, color, zPos, false, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM(); + + //Draw additional lineNameText at intersection pos: + line1_2D.Recalc_line_throughTwoPoints_returnSteepForVertLines(line1Origin, line1Origin + line1Direction); + line2_2D.Recalc_line_throughTwoPoints_returnSteepForVertLines(line2Origin, line2Origin + line2Direction); + bool line1_isSteeperUpwardsWhenWalkingAlongPositiveX = line1_2D.m >= line2_2D.m; + float minNecessaryDistanceToLineOrigin_forSeparateLineNameTextToBeDrawn = 2.5f; + float textSize = 0.03f * radius; + + line1IdentifyingText = ((line1Name == null) || (line1Name == "")) ? " line1" : " " + line1Name; + line2IdentifyingText = ((line2Name == null) || (line2Name == "")) ? " line2" : " " + line2Name; + + if (distance_intersection_to_line1origin > Mathf.Max(2.0f * length_ofLine1Direction, minNecessaryDistanceToLineOrigin_forSeparateLineNameTextToBeDrawn)) + { + Vector2 textDir = (line1Direction.x > 0.0f) ? line1Direction : (-line1Direction); + DrawText.TextAnchorDXXL textAnchor = line1_isSteeperUpwardsWhenWalkingAlongPositiveX ? DrawText.TextAnchorDXXL.LowerLeft : DrawText.TextAnchorDXXL.UpperLeft; + UtilitiesDXXL_Text.Write2DFramed(line1IdentifyingText, intersectionPos, colorOfLine1Attachments, textSize, textDir, textAnchor, zPos, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.005f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + + if (distance_intersection_to_line2origin > Mathf.Max(2.0f * length_ofLine2Direction, minNecessaryDistanceToLineOrigin_forSeparateLineNameTextToBeDrawn)) + { + Vector2 textDir = (line2Direction.x > 0.0f) ? line2Direction : (-line2Direction); + DrawText.TextAnchorDXXL textAnchor = line1_isSteeperUpwardsWhenWalkingAlongPositiveX ? DrawText.TextAnchorDXXL.UpperLeft : DrawText.TextAnchorDXXL.LowerLeft; + UtilitiesDXXL_Text.Write2DFramed(line2IdentifyingText, intersectionPos, colorOfLine2Attachments, textSize, textDir, textAnchor, zPos, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.005f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + + return returnedAngle; + } + } + + static bool CheckIfLinesAreApproxParallel(out float displayedAndReturnedAngle_forParallelLines, bool returnObtuseAngleOver90deg, bool displayAndReturn_radInsteadOfDeg, Vector2 line1Direction, Vector2 line2Direction) + { + float angleDeg = Vector2.Angle(line1Direction, line2Direction); + float angleDeg_acute = (angleDeg > 90.0f) ? (180.0f - angleDeg) : angleDeg; + float angleDeg_obtuse = (angleDeg < 90.0f) ? (180.0f - angleDeg) : angleDeg; + float angleRad_acute = Mathf.Deg2Rad * angleDeg_acute; + float angleRad_obtuse = Mathf.Deg2Rad * angleDeg_obtuse; + + if (returnObtuseAngleOver90deg) + { + if (displayAndReturn_radInsteadOfDeg) + { + displayedAndReturnedAngle_forParallelLines = angleRad_obtuse; + } + else + { + displayedAndReturnedAngle_forParallelLines = angleDeg_obtuse; + } + } + else + { + if (displayAndReturn_radInsteadOfDeg) + { + displayedAndReturnedAngle_forParallelLines = angleRad_acute; + } + else + { + displayedAndReturnedAngle_forParallelLines = angleDeg_acute; + } + } + + bool linesAreApproxParallel = (angleDeg_acute < 0.02f); //the minimum angle that "UnityEngine.Vector2.Angle()" can return seems to be between "0.01" and "0.02". Below that it always returns 0. + return linesAreApproxParallel; + } + + public static void DistanceThreshold(Vector2 startPos, Vector2 endPos, float thresholdDistance, string text = null, bool displayDistanceAlsoAsText = false, float lineWidth = 0.0f, float custom_zPos = float.PositiveInfinity, bool exactlyThresholdLength_countsAsShorter = true, float endPlates_size = 0.0f, DrawBasics.LineStyle overwriteStyle_forNear = DrawBasics.LineStyle.electricNoise, DrawBasics.LineStyle overwriteStyle_forFar = DrawBasics.LineStyle.solid, Color overwriteColor_forNear = default(Color), Color overwriteColor_forFar = default(Color), float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(thresholdDistance, "thresholdDistance")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPos, "startPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(endPos, "endPos")) { return; } + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(startPos, endPos)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(startPos, "[ DistanceThreshold2D with distance of 0]
" + text, UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forNear, UtilitiesDXXL_Colors.red_boolFalse), lineWidth, durationInSec, hiddenByNearerObjects); + return; + } + + Color usedColor = new Color(); + DrawBasics.LineStyle usedLineStyle = DrawBasics.LineStyle.solid; + float distance = (endPos - startPos).magnitude; + float stylePatternScaleFactor = distance; + + if (displayDistanceAlsoAsText) + { + text = string.IsNullOrEmpty(text) ? ("distance =
" + distance) : ("distance =
" + distance + "
" + text); + } + + UtilitiesDXXL_Measurements.ChooseColorAndStyleForDistanceThresholdLine(ref usedColor, ref usedLineStyle, distance, thresholdDistance, exactlyThresholdLength_countsAsShorter, overwriteStyle_forNear, overwriteStyle_forFar, overwriteColor_forNear, overwriteColor_forFar); + + UtilitiesDXXL_DrawBasics.Set_relSizeOfTextOnLines_reversible(0.65f); + UtilitiesDXXL_DrawBasics.Set_shiftTextPosOnLines_toNonIntersecting_reversible(true); + Line_fadeableAnimSpeed_2D.InternalDraw(startPos, endPos, usedColor, lineWidth, text, usedLineStyle, custom_zPos, stylePatternScaleFactor, 0.0f, null, endPlates_size, 0.0f, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, true, true); + UtilitiesDXXL_DrawBasics.Reverse_relSizeOfTextOnLines(); + UtilitiesDXXL_DrawBasics.Reverse_shiftTextPosOnLines_toNonIntersecting(); + } + + public static void DistanceThresholds(Vector2 startPos, Vector2 endPos, float smallerThresholdDistance, float biggerThresholdDistance, string text = null, bool displayDistanceAlsoAsText = false, float lineWidth = 0.0f, float custom_zPos = float.PositiveInfinity, bool exactlyThresholdLength_countsAsShorter = true, float endPlates_size = 0.0f, DrawBasics.LineStyle overwriteStyle_forNear = DrawBasics.LineStyle.electricNoise, DrawBasics.LineStyle overwriteStyle_forMiddle = DrawBasics.LineStyle.electricImpulses, DrawBasics.LineStyle overwriteStyle_forFar = DrawBasics.LineStyle.solid, Color overwriteColor_forNear = default(Color), Color overwriteColor_forMiddle = default(Color), Color overwriteColor_forFar = default(Color), float enlargeSmallTextToThisMinTextSize = 0.005f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(smallerThresholdDistance, "smallerThresholdDistance")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(biggerThresholdDistance, "biggerThresholdDistance")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPos, "startPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(endPos, "endPos")) { return; } + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(startPos, endPos)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(startPos, "[ DistanceThresholds2D with distance of 0]
" + text, UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forNear, UtilitiesDXXL_Colors.red_boolFalse), lineWidth, durationInSec, hiddenByNearerObjects); + return; + } + + if (smallerThresholdDistance > biggerThresholdDistance) + { + text = "[ threshold distances are automatically flipped: smaller (" + smallerThresholdDistance + " -> " + biggerThresholdDistance + ") / bigger (" + biggerThresholdDistance + " -> " + smallerThresholdDistance + ")]
" + text; + float smallerClipboard = smallerThresholdDistance; + smallerThresholdDistance = biggerThresholdDistance; + biggerThresholdDistance = smallerClipboard; + } + + Color usedColor = new Color(); + DrawBasics.LineStyle usedLineStyle = DrawBasics.LineStyle.solid; + float distance = (endPos - startPos).magnitude; + float stylePatternScaleFactor = distance; + + if (displayDistanceAlsoAsText) + { + text = string.IsNullOrEmpty(text) ? ("distance =
" + distance) : ("distance =
" + distance + "
" + text); + } + + UtilitiesDXXL_Measurements.ChooseColorAndStyleForDistanceThresholdsLine(ref usedColor, ref usedLineStyle, distance, smallerThresholdDistance, biggerThresholdDistance, exactlyThresholdLength_countsAsShorter, overwriteStyle_forNear, overwriteStyle_forMiddle, overwriteStyle_forFar, overwriteColor_forNear, overwriteColor_forMiddle, overwriteColor_forFar); + + UtilitiesDXXL_DrawBasics.Set_relSizeOfTextOnLines_reversible(0.65f); + UtilitiesDXXL_DrawBasics.Set_shiftTextPosOnLines_toNonIntersecting_reversible(true); + Line_fadeableAnimSpeed_2D.InternalDraw(startPos, endPos, usedColor, lineWidth, text, usedLineStyle, custom_zPos, stylePatternScaleFactor, 0.0f, null, endPlates_size, 0.0f, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, true, true); + UtilitiesDXXL_DrawBasics.Reverse_relSizeOfTextOnLines(); + UtilitiesDXXL_DrawBasics.Reverse_shiftTextPosOnLines_toNonIntersecting(); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/DrawMeasurements2D.cs.meta b/Runtime/DrawDebugLibrary/DrawMeasurements2D.cs.meta new file mode 100644 index 0000000..b25d764 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawMeasurements2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23267629324b1f541a71d41e2cef2607 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawPhysics.cs b/Runtime/DrawDebugLibrary/DrawPhysics.cs new file mode 100644 index 0000000..09bc90a --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawPhysics.cs @@ -0,0 +1,464 @@ +namespace DrawXXL +{ + using UnityEngine; + public class DrawPhysics + { + public static Color colorForNonHittingCasts = UtilitiesDXXL_Colors.red_boolFalse; + public static Color colorForHittingCasts = UtilitiesDXXL_Colors.green_boolTrue; + public static Color colorForCastLineBeyondHit = UtilitiesDXXL_Colors.orange_lineThresholdMiddleDistance; + public static Color colorForCastsHitText = UtilitiesDXXL_Colors.purple_raycastHitTextDefault; + public static Color overwriteColorForCastsHitNormals = default(Color); + public static float scaleFactor_forCastHitTextSize = 1.0f; + public static float castSilhouetteVisualizerDensity = 1.0f; + public static int maxSilhouettesPerCastVisualization = 100; + public static int hitResultsWithMoreDetailedDisplay = 2; + public static bool drawCastNameTag_atCastOrigin = true; + public static bool drawCastNameTag_atHitPositions = true; + + public enum VisualizationQuality + { + high_withFullDetails, + medium_meaningReducedTextAndSilhouettes, + low_withoutAnyTextOrSilhouettes + }; + public static VisualizationQuality visualizationQuality = VisualizationQuality.high_withFullDetails; + + private static int maxListedColliders_inOverlapVolumesTextList = 10; + public static int MaxListedColliders_inOverlapVolumesTextList + { + get { return maxListedColliders_inOverlapVolumesTextList; } + set { maxListedColliders_inOverlapVolumesTextList = Mathf.Max(value, 1); } + } + + public static int maxOverlapingCollidersWithUntruncatedText = 10; + public static float forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = 0.0f; + public static float forcedConstantWorldspaceTextSize_forOverlapResultTexts = 0.0f; + + public static Vector2 directionOfHitResultText = default(Vector2); + + /// 执行盒体投射并绘制首次碰撞结果(无 hitInfo 输出参数版本) + public static bool BoxCast(Vector3 center, Vector3 halfExtents, Vector3 direction, Quaternion orientation = default(Quaternion), float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + bool hasHit = Physics.BoxCast(center, halfExtents, direction, out RaycastHit hitInfo, orientation, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawBoxcastTillFirstHit(hasHit, center, halfExtents, orientation, direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行盒体投射并绘制首次碰撞结果(带 hitInfo 输出参数版本) + public static bool BoxCast(Vector3 center, Vector3 halfExtents, Vector3 direction, out RaycastHit hitInfo, Quaternion orientation = default(Quaternion), float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + bool hasHit = Physics.BoxCast(center, halfExtents, direction, out hitInfo, orientation, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawBoxcastTillFirstHit(hasHit, center, halfExtents, orientation, direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行盒体投射并绘制所有碰撞结果 + public static RaycastHit[] BoxCastAll(Vector3 center, Vector3 halfExtents, Vector3 direction, Quaternion orientation = default(Quaternion), float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + RaycastHit[] hitInfos = Physics.BoxCastAll(center, halfExtents, direction, orientation, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hitInfos; } + int numberOfUsedSlotsInHitInfoArray = 0; + if (hitInfos != null) { numberOfUsedSlotsInHitInfoArray = hitInfos.Length; } + UtilitiesDXXL_Physics.DrawBoxcastPotMultipleHits(center, halfExtents, orientation, direction, maxDistance, hitInfos, numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return hitInfos; + } + + /// 执行盒体投射并将碰撞结果存入预分配数组,同时绘制所有碰撞结果 + public static int BoxCastNonAlloc(Vector3 center, Vector3 halfExtents, Vector3 direction, RaycastHit[] results, Quaternion orientation = default(Quaternion), float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + int numberOfUsedSlotsInHitInfoArray = Physics.BoxCastNonAlloc(center, halfExtents, direction, results, orientation, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoArray; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoArray, results); + UtilitiesDXXL_Physics.DrawBoxcastPotMultipleHits(center, halfExtents, orientation, direction, maxDistance, results, resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoArray; + } + + /// 执行胶囊体投射并绘制首次碰撞结果(带 hitInfo 输出参数版本) + public static bool CapsuleCast(Vector3 point1, Vector3 point2, float radius, Vector3 direction, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.CapsuleCast(point1, point2, radius, direction, out hitInfo, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawCapsulecastTillFirstHit(radius, hasHit, point1, point2, direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行胶囊体投射并绘制首次碰撞结果(无 hitInfo 输出参数版本) + public static bool CapsuleCast(Vector3 point1, Vector3 point2, float radius, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.CapsuleCast(point1, point2, radius, direction, out RaycastHit hitInfo, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawCapsulecastTillFirstHit(radius, hasHit, point1, point2, direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行胶囊体投射并绘制所有碰撞结果 + public static RaycastHit[] CapsuleCastAll(Vector3 point1, Vector3 point2, float radius, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + RaycastHit[] hitInfos = Physics.CapsuleCastAll(point1, point2, radius, direction, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hitInfos; } + int numberOfUsedSlotsInHitInfoArray = 0; + if (hitInfos != null) { numberOfUsedSlotsInHitInfoArray = hitInfos.Length; } + UtilitiesDXXL_Physics.DrawCapsulecastPotMultipleHits(radius, point1, point2, direction, maxDistance, hitInfos, numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return hitInfos; + } + + /// 执行胶囊体投射并将碰撞结果存入预分配数组,同时绘制所有碰撞结果 + public static int CapsuleCastNonAlloc(Vector3 point1, Vector3 point2, float radius, Vector3 direction, RaycastHit[] results, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + int numberOfUsedSlotsInHitInfoArray = Physics.CapsuleCastNonAlloc(point1, point2, radius, direction, results, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoArray; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoArray, results); + UtilitiesDXXL_Physics.DrawCapsulecastPotMultipleHits(radius, point1, point2, direction, maxDistance, results, resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoArray; + } + + /// 执行线段投射并绘制首次碰撞结果(带 hitInfo 输出参数版本) + public static bool Linecast(Vector3 start, Vector3 end, out RaycastHit hitInfo, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.Linecast(start, end, out hitInfo, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return hasHit; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return hasHit; } + Vector3 startToEnd = end - start; + float length = startToEnd.magnitude; + UtilitiesDXXL_Physics.DrawRaycastTillFirstHit(hasHit, start, startToEnd, length, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行线段投射并绘制首次碰撞结果(无 hitInfo 输出参数版本) + public static bool Linecast(Vector3 start, Vector3 end, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.Linecast(start, end, out RaycastHit hitInfo, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return hasHit; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return hasHit; } + Vector3 startToEnd = end - start; + float length = startToEnd.magnitude; + UtilitiesDXXL_Physics.DrawRaycastTillFirstHit(hasHit, start, startToEnd, length, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行射线投射并绘制首次碰撞结果(Ray + hitInfo 版本) + public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.Raycast(ray, out hitInfo, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawRaycastTillFirstHit(hasHit, ray.origin, ray.direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行射线投射并绘制首次碰撞结果(Ray 无 hitInfo 版本) + public static bool Raycast(Ray ray, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.Raycast(ray, out RaycastHit hitInfo, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawRaycastTillFirstHit(hasHit, ray.origin, ray.direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行射线投射并绘制首次碰撞结果(Vector3 + hitInfo 版本) + public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.Raycast(origin, direction, out hitInfo, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawRaycastTillFirstHit(hasHit, origin, direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行射线投射并绘制首次碰撞结果(Vector3 无 hitInfo 版本) + public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.Raycast(origin, direction, out RaycastHit hitInfo, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawRaycastTillFirstHit(hasHit, origin, direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行射线投射并绘制所有碰撞结果(Vector3 版本) + public static RaycastHit[] RaycastAll(Vector3 origin, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + RaycastHit[] hitInfos = Physics.RaycastAll(origin, direction, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hitInfos; } + int numberOfUsedSlotsInHitInfoArray = 0; + if (hitInfos != null) { numberOfUsedSlotsInHitInfoArray = hitInfos.Length; } + UtilitiesDXXL_Physics.DrawRaycastPotMultipleHits(origin, direction, maxDistance, hitInfos, numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return hitInfos; + } + + /// 执行射线投射并绘制所有碰撞结果(Ray 版本) + public static RaycastHit[] RaycastAll(Ray ray, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + RaycastHit[] hitInfos = Physics.RaycastAll(ray, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hitInfos; } + int numberOfUsedSlotsInHitInfoArray = 0; + if (hitInfos != null) { numberOfUsedSlotsInHitInfoArray = hitInfos.Length; } + UtilitiesDXXL_Physics.DrawRaycastPotMultipleHits(ray.origin, ray.direction, maxDistance, hitInfos, numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return hitInfos; + } + + /// 执行射线投射并将碰撞结果存入预分配数组,同时绘制所有碰撞结果(Ray 版本) + public static int RaycastNonAlloc(Ray ray, RaycastHit[] results, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + int numberOfUsedSlotsInHitInfoArray = Physics.RaycastNonAlloc(ray, results, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoArray; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoArray, results); + UtilitiesDXXL_Physics.DrawRaycastPotMultipleHits(ray.origin, ray.direction, maxDistance, results, resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoArray; + } + + /// 执行射线投射并将碰撞结果存入预分配数组,同时绘制所有碰撞结果(Vector3 版本) + public static int RaycastNonAlloc(Vector3 origin, Vector3 direction, RaycastHit[] results, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + int numberOfUsedSlotsInHitInfoArray = Physics.RaycastNonAlloc(origin, direction, results, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoArray; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoArray, results); + UtilitiesDXXL_Physics.DrawRaycastPotMultipleHits(origin, direction, maxDistance, results, resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoArray; + } + + /// 执行球体投射并绘制首次碰撞结果(Ray 无 hitInfo 版本) + public static bool SphereCast(Ray ray, float radius, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.SphereCast(ray, radius, out RaycastHit hitInfo, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawSpherecastTillFirstHit(radius, hasHit, ray.origin, ray.direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行球体投射并绘制首次碰撞结果(Ray + hitInfo 版本) + public static bool SphereCast(Ray ray, float radius, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.SphereCast(ray, radius, out hitInfo, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawSpherecastTillFirstHit(radius, hasHit, ray.origin, ray.direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行球体投射并绘制首次碰撞结果(Vector3 无 hitInfo 版本) + public static bool SphereCast(Vector3 origin, float radius, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.SphereCast(origin, radius, direction, out RaycastHit hitInfo, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawSpherecastTillFirstHit(radius, hasHit, origin, direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行球体投射并绘制首次碰撞结果(Vector3 + hitInfo 版本) + public static bool SphereCast(Vector3 origin, float radius, Vector3 direction, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + bool hasHit = Physics.SphereCast(origin, radius, direction, out hitInfo, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hasHit; } + UtilitiesDXXL_Physics.DrawSpherecastTillFirstHit(radius, hasHit, origin, direction, maxDistance, hitInfo, nameTag, durationInSec, hiddenByNearerObjects); + return hasHit; + } + + /// 执行球体投射并绘制所有碰撞结果(Ray 版本) + public static RaycastHit[] SphereCastAll(Ray ray, float radius, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + RaycastHit[] hitInfos = Physics.SphereCastAll(ray, radius, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hitInfos; } + int numberOfUsedSlotsInHitInfoArray = 0; + if (hitInfos != null) { numberOfUsedSlotsInHitInfoArray = hitInfos.Length; } + UtilitiesDXXL_Physics.DrawSpherecastPotMultipleHits(radius, ray.origin, ray.direction, maxDistance, hitInfos, numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return hitInfos; + } + + /// 执行球体投射并绘制所有碰撞结果(Vector3 版本) + public static RaycastHit[] SphereCastAll(Vector3 origin, float radius, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + RaycastHit[] hitInfos = Physics.SphereCastAll(origin, radius, direction, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return hitInfos; } + int numberOfUsedSlotsInHitInfoArray = 0; + if (hitInfos != null) { numberOfUsedSlotsInHitInfoArray = hitInfos.Length; } + UtilitiesDXXL_Physics.DrawSpherecastPotMultipleHits(radius, origin, direction, maxDistance, hitInfos, numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return hitInfos; + } + + /// 执行球体投射并将碰撞结果存入预分配数组,同时绘制所有碰撞结果(Ray 版本) + public static int SphereCastNonAlloc(Ray ray, float radius, RaycastHit[] results, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + int numberOfUsedSlotsInHitInfoArray = Physics.SphereCastNonAlloc(ray, radius, results, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoArray; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoArray, results); + UtilitiesDXXL_Physics.DrawSpherecastPotMultipleHits(radius, ray.origin, ray.direction, maxDistance, results, resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoArray; + } + + /// 执行球体投射并将碰撞结果存入预分配数组,同时绘制所有碰撞结果(Vector3 版本) + public static int SphereCastNonAlloc(Vector3 origin, float radius, Vector3 direction, RaycastHit[] results, float maxDistance = Mathf.Infinity, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + int numberOfUsedSlotsInHitInfoArray = Physics.SphereCastNonAlloc(origin, radius, direction, results, maxDistance, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoArray; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoArray, results); + UtilitiesDXXL_Physics.DrawSpherecastPotMultipleHits(radius, origin, direction, maxDistance, results, resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoArray, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoArray; + } + + /// 检测盒体是否与任何碰撞体重叠并绘制检测结果 + public static bool CheckBox(Vector3 center, Vector3 halfExtents, Quaternion orientation = default(Quaternion), int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + bool doesOverlap = Physics.CheckBox(center, halfExtents, orientation, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return doesOverlap; } + UtilitiesDXXL_Physics.DrawCheckedBox(doesOverlap, center, halfExtents, orientation, nameTag, durationInSec, hiddenByNearerObjects); + return doesOverlap; + } + + /// 检测胶囊体是否与任何碰撞体重叠并绘制检测结果 + public static bool CheckCapsule(Vector3 start, Vector3 end, float radius, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + bool doesOverlap = Physics.CheckCapsule(start, end, radius, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return doesOverlap; } + UtilitiesDXXL_Physics.DrawCheckedCapsule(doesOverlap, start, end, radius, nameTag, durationInSec, hiddenByNearerObjects); + return doesOverlap; + } + + /// 检测球体是否与任何碰撞体重叠并绘制检测结果 + public static bool CheckSphere(Vector3 position, float radius, int layerMask = Physics.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + bool doesOverlap = Physics.CheckSphere(position, radius, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return doesOverlap; } + UtilitiesDXXL_Physics.DrawCheckedSphere(doesOverlap, position, radius, nameTag, durationInSec, hiddenByNearerObjects); + return doesOverlap; + } + + /// 获取与盒体重叠的所有碰撞器并绘制重叠结果 + public static Collider[] OverlapBox(Vector3 center, Vector3 halfExtents, Quaternion orientation = default(Quaternion), int layerMask = Physics.AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + Collider[] overlappingColliders = Physics.OverlapBox(center, halfExtents, orientation, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingColliders; } + + bool doesOverlap = false; + int numberOfOverlappingColliders = 0; + if (overlappingColliders != null && overlappingColliders.Length > 0) + { + doesOverlap = true; + numberOfOverlappingColliders = overlappingColliders.Length; + } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(center, "center")) { return overlappingColliders; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(halfExtents, "halfExtents")) { return overlappingColliders; } + + float approxSize_ofOverlapVolume =UtilitiesDXXL_Math.GetAverageBoxExtent(2.0f* halfExtents); + UtilitiesDXXL_Physics.DrawMarkersAtOverlappingColliders(center, doesOverlap, overlappingColliders, numberOfOverlappingColliders, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Physics.DrawOverlapResultBox(doesOverlap, numberOfOverlappingColliders, overlappingColliders, center, halfExtents, orientation, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingColliders; + } + + /// 获取与盒体重叠的碰撞器并存入预分配数组,同时绘制重叠结果 + public static int OverlapBoxNonAlloc(Vector3 center, Vector3 halfExtents, Collider[] results, Quaternion orientation = default(Quaternion), int layerMask = Physics.AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + orientation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(orientation); + int numberOfOverlappingColliders = Physics.OverlapBoxNonAlloc(center, halfExtents, results, orientation, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(center, "center")) { return numberOfOverlappingColliders; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(halfExtents, "halfExtents")) { return numberOfOverlappingColliders; } + + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + bool doesOverlap = (used_numberOfOverlappingColliders > 0); + float approxSize_ofOverlapVolume = UtilitiesDXXL_Math.GetAverageBoxExtent(2.0f * halfExtents); + UtilitiesDXXL_Physics.DrawMarkersAtOverlappingColliders(center, doesOverlap, results, used_numberOfOverlappingColliders, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); ; + UtilitiesDXXL_Physics.DrawOverlapResultBox(doesOverlap, used_numberOfOverlappingColliders, results, center, halfExtents, orientation, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 获取与胶囊体重叠的所有碰撞器并绘制重叠结果 + public static Collider[] OverlapCapsule(Vector3 point0, Vector3 point1, float radius, int layerMask = Physics.AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider[] overlappingColliders = Physics.OverlapCapsule(point0, point1, radius, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingColliders; } + + bool doesOverlap = false; + int numberOfOverlappingColliders = 0; + if (overlappingColliders != null && overlappingColliders.Length > 0) + { + doesOverlap = true; + numberOfOverlappingColliders = overlappingColliders.Length; + } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return overlappingColliders; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(point0, "point0")) { return overlappingColliders; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(point1, "point1")) { return overlappingColliders; } + + Vector3 capsuleCenter = 0.5f * (point0 + point1); + float approxSize_ofOverlapVolume = 3.0f * radius; + UtilitiesDXXL_Physics.DrawMarkersAtOverlappingColliders(capsuleCenter, doesOverlap, overlappingColliders, numberOfOverlappingColliders, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); ; + UtilitiesDXXL_Physics.DrawOverlapResultCapsule(doesOverlap, numberOfOverlappingColliders, overlappingColliders, point0, point1, radius, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingColliders; + } + + /// 获取与胶囊体重叠的碰撞器并存入预分配数组,同时绘制重叠结果 + public static int OverlapCapsuleNonAlloc(Vector3 point0, Vector3 point1, float radius, Collider[] results, int layerMask = Physics.AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics.OverlapCapsuleNonAlloc(point0, point1, radius, results, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return numberOfOverlappingColliders; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(point0, "point0")) { return numberOfOverlappingColliders; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(point1, "point1")) { return numberOfOverlappingColliders; } + + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + bool doesOverlap = (used_numberOfOverlappingColliders > 0); + Vector3 capsuleCenter = 0.5f * (point0 + point1); + float approxSize_ofOverlapVolume = 3.0f * radius; + UtilitiesDXXL_Physics.DrawMarkersAtOverlappingColliders(capsuleCenter, doesOverlap, results, used_numberOfOverlappingColliders, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); ; + UtilitiesDXXL_Physics.DrawOverlapResultCapsule(doesOverlap, used_numberOfOverlappingColliders, results, point0, point1, radius, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 获取与球体重叠的所有碰撞器并绘制重叠结果 + public static Collider[] OverlapSphere(Vector3 position, float radius, int layerMask = Physics.AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider[] overlappingColliders = Physics.OverlapSphere(position, radius, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingColliders; } + + bool doesOverlap = false; + int numberOfOverlappingColliders = 0; + if (overlappingColliders != null && overlappingColliders.Length > 0) + { + doesOverlap = true; + numberOfOverlappingColliders = overlappingColliders.Length; + } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return overlappingColliders; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return overlappingColliders; } + + float approxSize_ofOverlapVolume = 2.0f * radius; + UtilitiesDXXL_Physics.DrawMarkersAtOverlappingColliders(position, doesOverlap, overlappingColliders, numberOfOverlappingColliders, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); ; + UtilitiesDXXL_Physics.DrawOverlapResultSphere(doesOverlap, numberOfOverlappingColliders, overlappingColliders, position, radius, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingColliders; + } + + /// 获取与球体重叠的碰撞器并存入预分配数组,同时绘制重叠结果 + public static int OverlapSphereNonAlloc(Vector3 position, float radius, Collider[] results, int layerMask = Physics.AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics.OverlapSphereNonAlloc(position, radius, results, layerMask, queryTriggerInteraction); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return numberOfOverlappingColliders; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return numberOfOverlappingColliders; } + + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + bool doesOverlap = (used_numberOfOverlappingColliders > 0); + float approxSize_ofOverlapVolume = 2.0f * radius; + UtilitiesDXXL_Physics.DrawMarkersAtOverlappingColliders(position, doesOverlap, results, used_numberOfOverlappingColliders, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); ; + UtilitiesDXXL_Physics.DrawOverlapResultSphere(doesOverlap, used_numberOfOverlappingColliders, results, position, radius, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/DrawPhysics.cs.meta b/Runtime/DrawDebugLibrary/DrawPhysics.cs.meta new file mode 100644 index 0000000..2ea2f61 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawPhysics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8948cc163159cee4eada74209f65b5ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawPhysics2D.cs b/Runtime/DrawDebugLibrary/DrawPhysics2D.cs new file mode 100644 index 0000000..f66a1a3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawPhysics2D.cs @@ -0,0 +1,682 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class DrawPhysics2D + { + public static Color colorForNonHittingCasts = UtilitiesDXXL_Colors.red_boolFalse; + public static Color colorForHittingCasts = UtilitiesDXXL_Colors.green_boolTrue; + public static Color colorForCastLineBeyondHit = UtilitiesDXXL_Colors.orange_lineThresholdMiddleDistance; + public static Color colorForCastsHitText = UtilitiesDXXL_Colors.purple_raycastHitTextDefault; + public static Color overwriteColorForCastsHitNormals = default(Color); + public static float scaleFactor_forCastHitTextSize = 1.0f; + public static float castCorridorVisualizerDensity = 1.0f; + public static int maxCorridorVisualizersPerCastVisualization = 600; + public static int hitResultsWithMoreDetailedDisplay = 2; + public static bool drawCastNameTag_atCastOrigin = true; + public static bool drawCastNameTag_atHitPositions = true; + public static DrawPhysics.VisualizationQuality visualizationQuality = DrawPhysics.VisualizationQuality.high_withFullDetails; + + private static int maxListedColliders_inOverlapVolumesTextList = 10; + public static int MaxListedColliders_inOverlapVolumesTextList + { + get { return maxListedColliders_inOverlapVolumesTextList; } + set { maxListedColliders_inOverlapVolumesTextList = Mathf.Max(value, 1); } + } + + public static int maxOverlapingCollidersWithUntruncatedText = 10; + + private static int maxNumberOfPreallocatedHits = 100; + public static int MaxNumberOfPreallocatedHits + { + get { return maxNumberOfPreallocatedHits; } + set + { + maxNumberOfPreallocatedHits = value; + if (maxNumberOfPreallocatedHits < 1) + { + Debug.LogWarning("Minimum value for 'maxNumberOfPreallocatedHits' is 1. Delivered value of " + maxNumberOfPreallocatedHits + " has been rounded up to 1."); + maxNumberOfPreallocatedHits = 1; + } + if (maxNumberOfPreallocatedHits > 100000000) + { + Debug.LogWarning("Maximum value for 'maxNumberOfPreallocatedHits' is 100000000. Delivered value of " + maxNumberOfPreallocatedHits + " has been rounded down to 100000000."); + maxNumberOfPreallocatedHits = 100000000; + } + UtilitiesDXXL_Physics2D.preallocatedRayHit2DResultsArray_copiedFromList = new RaycastHit2D[maxNumberOfPreallocatedHits]; + UtilitiesDXXL_Physics2D.preallocatedCollider2DResultsArray_copiedFromList = new Collider2D[maxNumberOfPreallocatedHits]; + } + } + + public static float custom_zPos_forCastVisualisation = float.PositiveInfinity; + public static float forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = 0.0f; + public static float forcedConstantWorldspaceTextSize_forOverlapResultTexts = 0.0f; + + public static Vector2 directionOfHitResultText = default(Vector2); + + /// 绘制 BoxCast 调试可视化,返回第一个命中结果 + public static RaycastHit2D BoxCast(Vector2 origin, Vector2 size, float angle, Vector2 direction, float distance = Mathf.Infinity, int layerMask = Physics2D.AllLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D result = Physics2D.BoxCast(origin, size, angle, direction, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return result; } + bool hasHit = (result.collider != null); + UtilitiesDXXL_Physics2D.DrawBoxcastTillFirstHit(hasHit, origin, size, angle, direction, distance, result, nameTag, durationInSec, hiddenByNearerObjects); + return result; + } + + /// 绘制 BoxCast 调试可视化,返回命中数量(数组重载) + public static int BoxCast(Vector2 origin, Vector2 size, float angle, Vector2 direction, ContactFilter2D contactFilter, RaycastHit2D[] results, float distance = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.BoxCast(origin, size, angle, direction, contactFilter, results, distance); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawBoxcastPotMultipleHits(origin, size, angle, direction, distance, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 BoxCast 调试可视化,返回命中数量(List 重载) + public static int BoxCast(Vector2 origin, Vector2 size, float angle, Vector2 direction, ContactFilter2D contactFilter, List results, float distance = float.PositiveInfinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.BoxCast(origin, size, angle, direction, contactFilter, results, distance); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultList(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int numberOfCopiedSlots = UtilitiesDXXL_Physics2D.CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, results, numberOfUsedSlotsInHitInfoCollection); + UtilitiesDXXL_Physics2D.ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(preallocatedArrayIsTooSmall, ref nameTag, numberOfUsedSlotsInHitInfoCollection); + UtilitiesDXXL_Physics2D.DrawBoxcastPotMultipleHits(origin, size, angle, direction, distance, UtilitiesDXXL_Physics2D.preallocatedRayHit2DResultsArray_copiedFromList, numberOfCopiedSlots, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 BoxCastAll 调试可视化,返回所有命中结果 + public static RaycastHit2D[] BoxCastAll(Vector2 origin, Vector2 size, float angle, Vector2 direction, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D[] results = Physics2D.BoxCastAll(origin, size, angle, direction, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return results; } + int numberOfUsedSlotsInHitInfoCollection = (results == null) ? 0 : results.Length; + UtilitiesDXXL_Physics2D.DrawBoxcastPotMultipleHits(origin, size, angle, direction, distance, results, numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return results; + } + + /// 绘制 BoxCastNonAlloc 调试可视化,将结果存入预分配数组 + public static int BoxCastNonAlloc(Vector2 origin, Vector2 size, float angle, Vector2 direction, RaycastHit2D[] results, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.BoxCastNonAlloc(origin, size, angle, direction, results, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawBoxcastPotMultipleHits(origin, size, angle, direction, distance, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 CapsuleCast 调试可视化,返回第一个命中结果 + public static RaycastHit2D CapsuleCast(Vector2 origin, Vector2 size, CapsuleDirection2D capsuleDirection, float angle, Vector2 direction, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D result = Physics2D.CapsuleCast(origin, size, capsuleDirection, angle, direction, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return result; } + bool hasHit = (result.collider != null); + UtilitiesDXXL_Physics2D.DrawCapsulecastTillFirstHit(hasHit, origin, size, direction, capsuleDirection, angle, distance, result, nameTag, durationInSec, hiddenByNearerObjects); + return result; + } + + /// 绘制 CapsuleCast 调试可视化,返回命中数量(数组重载) + public static int CapsuleCast(Vector2 origin, Vector2 size, CapsuleDirection2D capsuleDirection, float angle, Vector2 direction, ContactFilter2D contactFilter, RaycastHit2D[] results, float distance = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.CapsuleCast(origin, size, capsuleDirection, angle, direction, contactFilter, results, distance); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawCapsulecastPotMultipleHits(origin, size, direction, capsuleDirection, angle, distance, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 CapsuleCast 调试可视化,返回命中数量(List 重载) + public static int CapsuleCast(Vector2 origin, Vector2 size, CapsuleDirection2D capsuleDirection, float angle, Vector2 direction, ContactFilter2D contactFilter, List results, float distance = float.PositiveInfinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.CapsuleCast(origin, size, capsuleDirection, angle, direction, contactFilter, results, distance); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultList(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int numberOfCopiedSlots = UtilitiesDXXL_Physics2D.CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, results, numberOfUsedSlotsInHitInfoCollection); + UtilitiesDXXL_Physics2D.ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(preallocatedArrayIsTooSmall, ref nameTag, numberOfUsedSlotsInHitInfoCollection); + UtilitiesDXXL_Physics2D.DrawCapsulecastPotMultipleHits(origin, size, direction, capsuleDirection, angle, distance, UtilitiesDXXL_Physics2D.preallocatedRayHit2DResultsArray_copiedFromList, numberOfCopiedSlots, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 CapsuleCastAll 调试可视化,返回所有命中结果 + public static RaycastHit2D[] CapsuleCastAll(Vector2 origin, Vector2 size, CapsuleDirection2D capsuleDirection, float angle, Vector2 direction, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D[] results = Physics2D.CapsuleCastAll(origin, size, capsuleDirection, angle, direction, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return results; } + int numberOfUsedSlotsInHitInfoCollection = (results == null) ? 0 : results.Length; + UtilitiesDXXL_Physics2D.DrawCapsulecastPotMultipleHits(origin, size, direction, capsuleDirection, angle, distance, results, numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return results; + } + + /// 绘制 CapsuleCastNonAlloc 调试可视化,将结果存入预分配数组 + public static int CapsuleCastNonAlloc(Vector2 origin, Vector2 size, CapsuleDirection2D capsuleDirection, float angle, Vector2 direction, RaycastHit2D[] results, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.CapsuleCastNonAlloc(origin, size, capsuleDirection, angle, direction, results, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawCapsulecastPotMultipleHits(origin, size, direction, capsuleDirection, angle, distance, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 CircleCast 调试可视化,返回第一个命中结果 + public static RaycastHit2D CircleCast(Vector2 origin, float radius, Vector2 direction, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D result = Physics2D.CircleCast(origin, radius, direction, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return result; } + bool hasHit = (result.collider != null); + UtilitiesDXXL_Physics2D.DrawCirclecastTillFirstHit(radius, hasHit, origin, direction, distance, result, nameTag, durationInSec, hiddenByNearerObjects); + return result; + } + + /// 绘制 CircleCast 调试可视化,返回命中数量(数组重载) + public static int CircleCast(Vector2 origin, float radius, Vector2 direction, ContactFilter2D contactFilter, RaycastHit2D[] results, float distance = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.CircleCast(origin, radius, direction, contactFilter, results, distance); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawCirclecastPotMultipleHits(radius, origin, direction, distance, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 CircleCast 调试可视化,返回命中数量(List 重载) + public static int CircleCast(Vector2 origin, float radius, Vector2 direction, ContactFilter2D contactFilter, List results, float distance = float.PositiveInfinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.CircleCast(origin, radius, direction, contactFilter, results, distance); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultList(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int numberOfCopiedSlots = UtilitiesDXXL_Physics2D.CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, results, numberOfUsedSlotsInHitInfoCollection); + UtilitiesDXXL_Physics2D.ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(preallocatedArrayIsTooSmall, ref nameTag, numberOfUsedSlotsInHitInfoCollection); + UtilitiesDXXL_Physics2D.DrawCirclecastPotMultipleHits(radius, origin, direction, distance, UtilitiesDXXL_Physics2D.preallocatedRayHit2DResultsArray_copiedFromList, numberOfCopiedSlots, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 CircleCastAll 调试可视化,返回所有命中结果 + public static RaycastHit2D[] CircleCastAll(Vector2 origin, float radius, Vector2 direction, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D[] results = Physics2D.CircleCastAll(origin, radius, direction, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return results; } + int numberOfUsedSlotsInHitInfoCollection = (results == null) ? 0 : results.Length; + UtilitiesDXXL_Physics2D.DrawCirclecastPotMultipleHits(radius, origin, direction, distance, results, numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return results; + } + + /// 绘制 CircleCastNonAlloc 调试可视化,将结果存入预分配数组 + public static int CircleCastNonAlloc(Vector2 origin, float radius, Vector2 direction, RaycastHit2D[] results, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.CircleCastNonAlloc(origin, radius, direction, results, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawCirclecastPotMultipleHits(radius, origin, direction, distance, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 3D 射线与 2D 碰撞体相交检测的调试可视化,返回第一个交点结果 + public static RaycastHit2D GetRayIntersection(Ray ray, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D result = Physics2D.GetRayIntersection(ray, distance, layerMask); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return result; } + bool hasHit = (result.collider != null); + UtilitiesDXXL_Physics2D.DrawRaycast3DTillFirstHit(hasHit, ray, distance, result, nameTag, durationInSec, hiddenByNearerObjects); + return result; + + } + + /// 绘制 GetRayIntersectionAll 调试可视化,返回所有交点结果 + public static RaycastHit2D[] GetRayIntersectionAll(Ray ray, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D[] results = Physics2D.GetRayIntersectionAll(ray, distance, layerMask); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return results; } + int numberOfUsedSlotsInHitInfoCollection = (results == null) ? 0 : results.Length; + UtilitiesDXXL_Physics2D.DrawRaycast3DPotMultipleHits(ray, distance, results, numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return results; + } + + /// 绘制 GetRayIntersectionNonAlloc 调试可视化,将交点结果存入预分配数组 + public static int GetRayIntersectionNonAlloc(Ray ray, RaycastHit2D[] results, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.GetRayIntersectionNonAlloc(ray, results, distance, layerMask); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawRaycast3DPotMultipleHits(ray, distance, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 Linecast 调试可视化,返回第一个命中结果 + public static RaycastHit2D Linecast(Vector2 start, Vector2 end, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D result = Physics2D.Linecast(start, end, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return result; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return result; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return result; } + + bool hasHit = (result.collider != null); + Vector2 startToEnd = end - start; + float length = startToEnd.magnitude; + UtilitiesDXXL_Physics2D.DrawRaycastTillFirstHit(hasHit, start, startToEnd, length, result, nameTag, durationInSec, hiddenByNearerObjects); + return result; + } + + /// 绘制 Linecast 调试可视化,返回命中数量(数组重载) + public static int Linecast(Vector2 start, Vector2 end, ContactFilter2D contactFilter, RaycastHit2D[] results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.Linecast(start, end, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return numberOfUsedSlotsInHitInfoCollection; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return numberOfUsedSlotsInHitInfoCollection; } + + Vector2 startToEnd = end - start; + float length = startToEnd.magnitude; + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawRaycastPotMultipleHits(start, startToEnd, length, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 Linecast 调试可视化,返回命中数量(List 重载) + public static int Linecast(Vector2 start, Vector2 end, ContactFilter2D contactFilter, List results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.Linecast(start, end, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return numberOfUsedSlotsInHitInfoCollection; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return numberOfUsedSlotsInHitInfoCollection; } + + Vector2 startToEnd = end - start; + float length = startToEnd.magnitude; + UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultList(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int numberOfCopiedSlots = UtilitiesDXXL_Physics2D.CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, results, numberOfUsedSlotsInHitInfoCollection); + UtilitiesDXXL_Physics2D.ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(preallocatedArrayIsTooSmall, ref nameTag, numberOfUsedSlotsInHitInfoCollection); + UtilitiesDXXL_Physics2D.DrawRaycastPotMultipleHits(start, startToEnd, length, UtilitiesDXXL_Physics2D.preallocatedRayHit2DResultsArray_copiedFromList, numberOfCopiedSlots, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 LinecastAll 调试可视化,返回所有命中结果 + public static RaycastHit2D[] LinecastAll(Vector2 start, Vector2 end, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D[] results = Physics2D.LinecastAll(start, end, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return results; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return results; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return results; } + + int numberOfUsedSlotsInHitInfoCollection = (results == null) ? 0 : results.Length; + Vector2 startToEnd = end - start; + float length = startToEnd.magnitude; + UtilitiesDXXL_Physics2D.DrawRaycastPotMultipleHits(start, startToEnd, length, results, numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return results; + } + + /// 绘制 LinecastNonAlloc 调试可视化,将命中结果存入预分配数组 + public static int LinecastNonAlloc(Vector2 start, Vector2 end, RaycastHit2D[] results, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.LinecastNonAlloc(start, end, results, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return numberOfUsedSlotsInHitInfoCollection; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return numberOfUsedSlotsInHitInfoCollection; } + + Vector2 startToEnd = end - start; + float length = startToEnd.magnitude; + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawRaycastPotMultipleHits(start, startToEnd, length, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 Raycast 调试可视化,返回第一个命中结果 + public static RaycastHit2D Raycast(Vector2 origin, Vector2 direction, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D result = Physics2D.Raycast(origin, direction, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return result; } + bool hasHit = (result.collider != null); + UtilitiesDXXL_Physics2D.DrawRaycastTillFirstHit(hasHit, origin, direction, distance, result, nameTag, durationInSec, hiddenByNearerObjects); + return result; + } + + /// 绘制 Raycast 调试可视化,返回命中数量(数组重载) + public static int Raycast(Vector2 origin, Vector2 direction, ContactFilter2D contactFilter, RaycastHit2D[] results, float distance = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.Raycast(origin, direction, contactFilter, results, distance); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawRaycastPotMultipleHits(origin, direction, distance, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 Raycast 调试可视化,返回命中数量(List 重载) + public static int Raycast(Vector2 origin, Vector2 direction, ContactFilter2D contactFilter, List results, float distance = float.PositiveInfinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.Raycast(origin, direction, contactFilter, results, distance); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultList(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int numberOfCopiedSlots = UtilitiesDXXL_Physics2D.CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, results, numberOfUsedSlotsInHitInfoCollection); + UtilitiesDXXL_Physics2D.ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(preallocatedArrayIsTooSmall, ref nameTag, numberOfUsedSlotsInHitInfoCollection); + UtilitiesDXXL_Physics2D.DrawRaycastPotMultipleHits(origin, direction, distance, UtilitiesDXXL_Physics2D.preallocatedRayHit2DResultsArray_copiedFromList, numberOfCopiedSlots, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 RaycastAll 调试可视化,返回所有命中结果 + public static RaycastHit2D[] RaycastAll(Vector2 origin, Vector2 direction, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + RaycastHit2D[] results = Physics2D.RaycastAll(origin, direction, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return results; } + int numberOfUsedSlotsInHitInfoCollection = (results == null) ? 0 : results.Length; + UtilitiesDXXL_Physics2D.DrawRaycastPotMultipleHits(origin, direction, distance, results, numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return results; + } + + /// 绘制 RaycastNonAlloc 调试可视化,将结果存入预分配数组 + public static int RaycastNonAlloc(Vector2 origin, Vector2 direction, RaycastHit2D[] results, float distance = Mathf.Infinity, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfUsedSlotsInHitInfoCollection = Physics2D.RaycastNonAlloc(origin, direction, results, distance, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfUsedSlotsInHitInfoCollection; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoCollection, results); + int used_numberOfUsedSlotsInHitInfoCollection = resultsArrayIsNull ? 0 : numberOfUsedSlotsInHitInfoCollection; + UtilitiesDXXL_Physics2D.DrawRaycastPotMultipleHits(origin, direction, distance, results, used_numberOfUsedSlotsInHitInfoCollection, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfUsedSlotsInHitInfoCollection; + } + + /// 绘制 OverlapArea 调试可视化,返回第一个重叠碰撞体 + public static Collider2D OverlapArea(Vector2 pointA, Vector2 pointB, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider2D overlappingCollider = Physics2D.OverlapArea(pointA, pointB, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingCollider; } + UtilitiesDXXL_Physics2D.Area2D_to_Box2D(out Vector2 boxCenterPos_V2, out Vector2 boxSize_V2, pointA, pointB); + UtilitiesDXXL_Physics2D.DrawBoxOverlapResultOfMax1Collision(true, boxCenterPos_V2, boxSize_V2, 0.0f, overlappingCollider, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingCollider; + } + + /// 绘制 OverlapArea 调试可视化,返回重叠碰撞体数量(数组重载) + public static int OverlapArea(Vector2 pointA, Vector2 pointB, ContactFilter2D contactFilter, Collider2D[] results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapArea(pointA, pointB, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + UtilitiesDXXL_Physics2D.Area2D_to_Box2D(out Vector2 boxCenterPos_V2, out Vector2 boxSize_V2, pointA, pointB); + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + UtilitiesDXXL_Physics2D.DrawBoxOverlapResultOfPotMultipleCollisions(true, boxCenterPos_V2, boxSize_V2, 0.0f, used_numberOfOverlappingColliders, results, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapArea 调试可视化,返回重叠碰撞体数量(List 重载) + public static int OverlapArea(Vector2 pointA, Vector2 pointB, ContactFilter2D contactFilter, List results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapArea(pointA, pointB, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + UtilitiesDXXL_Physics2D.Area2D_to_Box2D(out Vector2 boxCenterPos_V2, out Vector2 boxSize_V2, pointA, pointB); + UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultList(ref nameTag, numberOfOverlappingColliders, results); + int numberOfCopiedSlots = UtilitiesDXXL_Physics2D.CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, results, numberOfOverlappingColliders); + UtilitiesDXXL_Physics2D.ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(preallocatedArrayIsTooSmall, ref nameTag, numberOfOverlappingColliders); + UtilitiesDXXL_Physics2D.DrawBoxOverlapResultOfPotMultipleCollisions(true, boxCenterPos_V2, boxSize_V2, 0.0f, numberOfCopiedSlots, UtilitiesDXXL_Physics2D.preallocatedCollider2DResultsArray_copiedFromList, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapAreaAll 调试可视化,返回所有重叠碰撞体 + public static Collider2D[] OverlapAreaAll(Vector2 pointA, Vector2 pointB, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider2D[] overlappingColliders = Physics2D.OverlapAreaAll(pointA, pointB, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingColliders; } + UtilitiesDXXL_Physics2D.Area2D_to_Box2D(out Vector2 boxCenterPos_V2, out Vector2 boxSize_V2, pointA, pointB); + int numberOfOverlappingColliders = 0; + if (overlappingColliders != null && overlappingColliders.Length > 0) + { + numberOfOverlappingColliders = overlappingColliders.Length; + } + UtilitiesDXXL_Physics2D.DrawBoxOverlapResultOfPotMultipleCollisions(true, boxCenterPos_V2, boxSize_V2, 0.0f, numberOfOverlappingColliders, overlappingColliders, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingColliders; + } + + /// 绘制 OverlapAreaNonAlloc 调试可视化,将重叠碰撞体结果存入预分配数组 + public static int OverlapAreaNonAlloc(Vector2 pointA, Vector2 pointB, Collider2D[] results, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapAreaNonAlloc(pointA, pointB, results, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + UtilitiesDXXL_Physics2D.Area2D_to_Box2D(out Vector2 boxCenterPos_V2, out Vector2 boxSize_V2, pointA, pointB); + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + UtilitiesDXXL_Physics2D.DrawBoxOverlapResultOfPotMultipleCollisions(true, boxCenterPos_V2, boxSize_V2, 0.0f, used_numberOfOverlappingColliders, results, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapBox 调试可视化,返回第一个重叠碰撞体 + public static Collider2D OverlapBox(Vector2 point, Vector2 size, float angle, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider2D overlappingCollider = Physics2D.OverlapBox(point, size, angle, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingCollider; } + UtilitiesDXXL_Physics2D.DrawBoxOverlapResultOfMax1Collision(false, point, size, angle, overlappingCollider, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingCollider; + } + + /// 绘制 OverlapBox 调试可视化,返回重叠碰撞体数量(数组重载) + public static int OverlapBox(Vector2 point, Vector2 size, float angle, ContactFilter2D contactFilter, Collider2D[] results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapBox(point, size, angle, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + UtilitiesDXXL_Physics2D.DrawBoxOverlapResultOfPotMultipleCollisions(false, point, size, angle, used_numberOfOverlappingColliders, results, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapBox 调试可视化,返回重叠碰撞体数量(List 重载) + public static int OverlapBox(Vector2 point, Vector2 size, float angle, ContactFilter2D contactFilter, List results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapBox(point, size, angle, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultList(ref nameTag, numberOfOverlappingColliders, results); + int numberOfCopiedSlots = UtilitiesDXXL_Physics2D.CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, results, numberOfOverlappingColliders); + UtilitiesDXXL_Physics2D.ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(preallocatedArrayIsTooSmall, ref nameTag, numberOfOverlappingColliders); + UtilitiesDXXL_Physics2D.DrawBoxOverlapResultOfPotMultipleCollisions(false, point, size, angle, numberOfCopiedSlots, UtilitiesDXXL_Physics2D.preallocatedCollider2DResultsArray_copiedFromList, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapBoxAll 调试可视化,返回所有重叠碰撞体 + public static Collider2D[] OverlapBoxAll(Vector2 point, Vector2 size, float angle, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider2D[] overlappingColliders = Physics2D.OverlapBoxAll(point, size, angle, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingColliders; } + int numberOfOverlappingColliders = 0; + if (overlappingColliders != null && overlappingColliders.Length > 0) + { + numberOfOverlappingColliders = overlappingColliders.Length; + } + UtilitiesDXXL_Physics2D.DrawBoxOverlapResultOfPotMultipleCollisions(false, point, size, angle, numberOfOverlappingColliders, overlappingColliders, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingColliders; + } + + /// 绘制 OverlapBoxNonAlloc 调试可视化,将重叠碰撞体结果存入预分配数组 + public static int OverlapBoxNonAlloc(Vector2 point, Vector2 size, float angle, Collider2D[] results, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapBoxNonAlloc(point, size, angle, results, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + UtilitiesDXXL_Physics2D.DrawBoxOverlapResultOfPotMultipleCollisions(false, point, size, angle, used_numberOfOverlappingColliders, results, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapCapsule 调试可视化,返回第一个重叠碰撞体 + public static Collider2D OverlapCapsule(Vector2 point, Vector2 size, CapsuleDirection2D direction, float angle, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider2D overlappingCollider = Physics2D.OverlapCapsule(point, size, direction, angle, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingCollider; } + UtilitiesDXXL_Physics2D.DrawCapsuleOverlapResultOfMax1Collision(point, size, direction, angle, overlappingCollider, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingCollider; + } + + /// 绘制 OverlapCapsule 调试可视化,返回重叠碰撞体数量(数组重载) + public static int OverlapCapsule(Vector2 point, Vector2 size, CapsuleDirection2D direction, float angle, ContactFilter2D contactFilter, Collider2D[] results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapCapsule(point, size, direction, angle, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + UtilitiesDXXL_Physics2D.DrawCapsuleOverlapResultOfPotMultipleCollisions(point, size, direction, angle, used_numberOfOverlappingColliders, results, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapCapsule 调试可视化,返回重叠碰撞体数量(List 重载) + public static int OverlapCapsule(Vector2 point, Vector2 size, CapsuleDirection2D direction, float angle, ContactFilter2D contactFilter, List results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapCapsule(point, size, direction, angle, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultList(ref nameTag, numberOfOverlappingColliders, results); + int numberOfCopiedSlots = UtilitiesDXXL_Physics2D.CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, results, numberOfOverlappingColliders); + UtilitiesDXXL_Physics2D.ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(preallocatedArrayIsTooSmall, ref nameTag, numberOfOverlappingColliders); + UtilitiesDXXL_Physics2D.DrawCapsuleOverlapResultOfPotMultipleCollisions(point, size, direction, angle, numberOfCopiedSlots, UtilitiesDXXL_Physics2D.preallocatedCollider2DResultsArray_copiedFromList, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapCapsuleAll 调试可视化,返回所有重叠碰撞体 + public static Collider2D[] OverlapCapsuleAll(Vector2 point, Vector2 size, CapsuleDirection2D direction, float angle, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider2D[] overlappingColliders = Physics2D.OverlapCapsuleAll(point, size, direction, angle, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingColliders; } + int numberOfOverlappingColliders = 0; + if (overlappingColliders != null && overlappingColliders.Length > 0) + { + numberOfOverlappingColliders = overlappingColliders.Length; + } + UtilitiesDXXL_Physics2D.DrawCapsuleOverlapResultOfPotMultipleCollisions(point, size, direction, angle, numberOfOverlappingColliders, overlappingColliders, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingColliders; + } + + /// 绘制 OverlapCapsuleNonAlloc 调试可视化,将重叠碰撞体结果存入预分配数组 + public static int OverlapCapsuleNonAlloc(Vector2 point, Vector2 size, CapsuleDirection2D direction, float angle, Collider2D[] results, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapCapsuleNonAlloc(point, size, direction, angle, results, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + UtilitiesDXXL_Physics2D.DrawCapsuleOverlapResultOfPotMultipleCollisions(point, size, direction, angle, used_numberOfOverlappingColliders, results, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapCircle 调试可视化,返回第一个重叠碰撞体 + public static Collider2D OverlapCircle(Vector2 point, float radius, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider2D overlappingCollider = Physics2D.OverlapCircle(point, radius, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingCollider; } + UtilitiesDXXL_Physics2D.DrawCircleOverlapResultOfMax1Collision(point, radius, overlappingCollider, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingCollider; + } + + /// 绘制 OverlapCircle 调试可视化,返回重叠碰撞体数量(数组重载) + public static int OverlapCircle(Vector2 point, float radius, ContactFilter2D contactFilter, Collider2D[] results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapCircle(point, radius, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + UtilitiesDXXL_Physics2D.DrawCircleOverlapResultOfPotMultipleCollisions(point, radius, used_numberOfOverlappingColliders, results, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapCircle 调试可视化,返回重叠碰撞体数量(List 重载) + public static int OverlapCircle(Vector2 point, float radius, ContactFilter2D contactFilter, List results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapCircle(point, radius, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultList(ref nameTag, numberOfOverlappingColliders, results); + int numberOfCopiedSlots = UtilitiesDXXL_Physics2D.CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, results, numberOfOverlappingColliders); + UtilitiesDXXL_Physics2D.ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(preallocatedArrayIsTooSmall, ref nameTag, numberOfOverlappingColliders); + UtilitiesDXXL_Physics2D.DrawCircleOverlapResultOfPotMultipleCollisions(point, radius, numberOfCopiedSlots, UtilitiesDXXL_Physics2D.preallocatedCollider2DResultsArray_copiedFromList, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapCircleAll 调试可视化,返回所有重叠碰撞体 + public static Collider2D[] OverlapCircleAll(Vector2 point, float radius, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider2D[] overlappingColliders = Physics2D.OverlapCircleAll(point, radius, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingColliders; } + int numberOfOverlappingColliders = 0; + if (overlappingColliders != null && overlappingColliders.Length > 0) + { + numberOfOverlappingColliders = overlappingColliders.Length; + } + UtilitiesDXXL_Physics2D.DrawCircleOverlapResultOfPotMultipleCollisions(point, radius, numberOfOverlappingColliders, overlappingColliders, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingColliders; + } + + /// 绘制 OverlapCircleNonAlloc 调试可视化,将重叠碰撞体结果存入预分配数组 + public static int OverlapCircleNonAlloc(Vector2 point, float radius, Collider2D[] results, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapCircleNonAlloc(point, radius, results, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + UtilitiesDXXL_Physics2D.DrawCircleOverlapResultOfPotMultipleCollisions(point, radius, used_numberOfOverlappingColliders, results, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapPoint 调试可视化,返回第一个重叠碰撞体 + public static Collider2D OverlapPoint(Vector2 point, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider2D overlappingCollider = Physics2D.OverlapPoint(point, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingCollider; } + UtilitiesDXXL_Physics2D.DrawPointOverlapResultOfMax1Collision(point, overlappingCollider, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingCollider; + } + + /// 绘制 OverlapPoint 调试可视化,返回重叠碰撞体数量(数组重载) + public static int OverlapPoint(Vector2 point, ContactFilter2D contactFilter, Collider2D[] results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapPoint(point, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + UtilitiesDXXL_Physics2D.DrawPointOverlapResultOfPotMultipleCollisions(point, used_numberOfOverlappingColliders, results, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapPoint 调试可视化,返回重叠碰撞体数量(List 重载) + public static int OverlapPoint(Vector2 point, ContactFilter2D contactFilter, List results, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapPoint(point, contactFilter, results); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultList(ref nameTag, numberOfOverlappingColliders, results); + int numberOfCopiedSlots = UtilitiesDXXL_Physics2D.CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, results, numberOfOverlappingColliders); + UtilitiesDXXL_Physics2D.ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(preallocatedArrayIsTooSmall, ref nameTag, numberOfOverlappingColliders); + UtilitiesDXXL_Physics2D.DrawPointOverlapResultOfPotMultipleCollisions(point, numberOfCopiedSlots, UtilitiesDXXL_Physics2D.preallocatedCollider2DResultsArray_copiedFromList, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + /// 绘制 OverlapPointAll 调试可视化,返回所有重叠碰撞体 + public static Collider2D[] OverlapPointAll(Vector2 point, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + Collider2D[] overlappingColliders = Physics2D.OverlapPointAll(point, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return overlappingColliders; } + int numberOfOverlappingColliders = 0; + if (overlappingColliders != null && overlappingColliders.Length > 0) + { + numberOfOverlappingColliders = overlappingColliders.Length; + } + UtilitiesDXXL_Physics2D.DrawPointOverlapResultOfPotMultipleCollisions(point, numberOfOverlappingColliders, overlappingColliders, nameTag, durationInSec, hiddenByNearerObjects); + return overlappingColliders; + } + + /// 绘制 OverlapPointNonAlloc 调试可视化,将重叠碰撞体结果存入预分配数组 + public static int OverlapPointNonAlloc(Vector2 point, Collider2D[] results, int layerMask = Physics2D.DefaultRaycastLayers, float minDepth = Mathf.NegativeInfinity, float maxDepth = Mathf.Infinity, string nameTag = null, float durationInSec = 0.0f, bool hiddenByNearerObjects = false) + { + int numberOfOverlappingColliders = Physics2D.OverlapPointNonAlloc(point, results, layerMask, minDepth, maxDepth); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return numberOfOverlappingColliders; } + bool resultsArrayIsNull = UtilitiesDXXL_Physics2D.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, results); + int used_numberOfOverlappingColliders = resultsArrayIsNull ? 0 : numberOfOverlappingColliders; + UtilitiesDXXL_Physics2D.DrawPointOverlapResultOfPotMultipleCollisions(point, used_numberOfOverlappingColliders, results, nameTag, durationInSec, hiddenByNearerObjects); + return numberOfOverlappingColliders; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/DrawPhysics2D.cs.meta b/Runtime/DrawDebugLibrary/DrawPhysics2D.cs.meta new file mode 100644 index 0000000..e2d9cf4 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawPhysics2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06f686b93af4fb6428505e60f2389ef0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawScreenspace.cs b/Runtime/DrawDebugLibrary/DrawScreenspace.cs new file mode 100644 index 0000000..b31d83c --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawScreenspace.cs @@ -0,0 +1,1749 @@ +namespace DrawXXL +{ + using System.Collections.Generic; + using UnityEngine; + + public class DrawScreenspace + { + public enum DefaultScreenspaceWindowForDrawing + { + sceneViewWindow, + gameViewWindow + }; + public static DefaultScreenspaceWindowForDrawing defaultScreenspaceWindowForDrawing = DefaultScreenspaceWindowForDrawing.gameViewWindow; + + public static Camera defaultCameraForDrawing = null; + public const float minTextSize_relToViewportHeight = 0.01f; + public static float drawOffsetBehindCamsNearPlane = 0.01f; + + public static void Line(Vector2 start, Vector2 end, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Line") == false) { return; } + Line(automaticallyFoundCamera, start, end, color, width_relToViewportHeight, text, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void Line(Camera targetCamera, Vector2 start, Vector2 end, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLine.Add(new ScreenspaceLine(targetCamera, start, end, color, width_relToViewportHeight, text, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, end, color, width_relToViewportHeight, text, style, stylePatternScaleFactor, animationSpeed, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void Ray(Vector2 start, Vector2 direction, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Ray") == false) { return; } + Ray(automaticallyFoundCamera, start, direction, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + public static void Ray(Camera targetCamera, Vector2 start, Vector2 direction, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceRay.Add(new ScreenspaceRay(targetCamera, start, direction, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + Ray_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, direction, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineFrom(Vector2 start, Vector2 direction, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineFrom") == false) { return; } + LineFrom(automaticallyFoundCamera, start, direction, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineFrom(Camera targetCamera, Vector2 start, Vector2 direction, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineFrom.Add(new ScreenspaceLineFrom(targetCamera, start, direction, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + LineFrom_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, direction, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineTo(Vector2 direction, Vector2 end, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineTo") == false) { return; } + LineTo(automaticallyFoundCamera, direction, end, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineTo(Camera targetCamera, Vector2 direction, Vector2 end, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineTo.Add(new ScreenspaceLineTo(targetCamera, direction, end, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + LineTo_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, direction, end, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineColorFade(Vector2 start, Vector2 end, Color startColor, Color endColor, float width_relToViewportHeight = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineColorFade") == false) { return; } + LineColorFade(automaticallyFoundCamera, start, end, startColor, endColor, width_relToViewportHeight, text, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + public static void LineColorFade(Camera targetCamera, Vector2 start, Vector2 end, Color startColor, Color endColor, float width_relToViewportHeight = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineColorFade.Add(new ScreenspaceLineColorFade(targetCamera, start, end, startColor, endColor, width_relToViewportHeight, text, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + Line_fadeableAnimSpeed_screenspace.InternalDrawColorFade(targetCamera, start, end, startColor, endColor, width_relToViewportHeight, text, style, stylePatternScaleFactor, animationSpeed, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void RayColorFade(Vector2 start, Vector2 direction, Color startColor, Color endColor, float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.RayColorFade") == false) { return; } + RayColorFade(automaticallyFoundCamera, start, direction, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + public static void RayColorFade(Camera targetCamera, Vector2 start, Vector2 direction, Color startColor, Color endColor, float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceRayColorFade.Add(new ScreenspaceRayColorFade(targetCamera, start, direction, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + Ray_fadeableAnimSpeed_screenspace.InternalDrawColorFade(targetCamera, start, direction, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineFrom_withColorFade(Vector2 start, Vector2 direction, Color startColor, Color endColor, float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineFrom_withColorFade") == false) { return; } + LineFrom_withColorFade(automaticallyFoundCamera, start, direction, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineFrom_withColorFade(Camera targetCamera, Vector2 start, Vector2 direction, Color startColor, Color endColor, float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineFrom_withColorFade.Add(new ScreenspaceLineFrom_withColorFade(targetCamera, start, direction, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + LineFrom_fadeableAnimSpeed_screenspace.InternalDraw_withColorFade(targetCamera, start, direction, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineTo_withColorFade(Vector2 direction, Vector2 end, Color startColor, Color endColor, float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineTo_withColorFade") == false) { return; } + LineTo_withColorFade(automaticallyFoundCamera, direction, end, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineTo_withColorFade(Camera targetCamera, Vector2 direction, Vector2 end, Color startColor, Color endColor, float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineTo_withColorFade.Add(new ScreenspaceLineTo_withColorFade(targetCamera, direction, end, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + LineTo_fadeableAnimSpeed_screenspace.InternalDraw_withColorFade(targetCamera, direction, end, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineCircled(Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool skipFallbackDisplayOfZeroAngles = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineCircled") == false) { return; } + + LineCircled(automaticallyFoundCamera, circleCenter, startAngleDegCC_relativeToUp, endAngleDegCC_relativeToUp, radius_relToViewportHeight, color, width_relToViewportHeight, text, skipFallbackDisplayOfZeroAngles, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec); + } + public static void LineCircled(Camera targetCamera, Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool skipFallbackDisplayOfZeroAngles = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(startAngleDegCC_relativeToUp, "startAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(endAngleDegCC_relativeToUp, "endAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_relToViewportHeight, "radius_relToViewportHeight")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam.Add(new ScreenspaceLineCircled_angleToAngle_cam(targetCamera, circleCenter, startAngleDegCC_relativeToUp, endAngleDegCC_relativeToUp, radius_relToViewportHeight, color, width_relToViewportHeight, text, skipFallbackDisplayOfZeroAngles, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec)); + return; + } + + Quaternion rotation_fromGlobalUp_toLineStartAngleInXYplane = Quaternion.AngleAxis(startAngleDegCC_relativeToUp, Vector3.forward); + Vector3 circleCenter_to_startPos_inUnwarpedSpace_normalized = rotation_fromGlobalUp_toLineStartAngleInXYplane * Vector3.up; + Vector2 circleCenter_to_startPos_inWarpedSpace_normalized = DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(circleCenter_to_startPos_inUnwarpedSpace_normalized, targetCamera); + Vector2 circleCenter_to_startPos_inWarpedScreenspaceSpace = circleCenter_to_startPos_inWarpedSpace_normalized * radius_relToViewportHeight; + Vector2 startPos = circleCenter + circleCenter_to_startPos_inWarpedScreenspaceSpace; + float turnAngleDegCC = endAngleDegCC_relativeToUp - startAngleDegCC_relativeToUp; + LineCircled(targetCamera, startPos, circleCenter, turnAngleDegCC, color, width_relToViewportHeight, text, skipFallbackDisplayOfZeroAngles, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec); + } + + public static void LineCircled(Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool skipFallbackDisplayOfZeroAngles = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineCircled") == false) { return; } + LineCircled(automaticallyFoundCamera, startPos, circleCenter, turnAngleDegCC, color, width_relToViewportHeight, text, skipFallbackDisplayOfZeroAngles, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec); + } + public static void LineCircled(Camera targetCamera, Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool skipFallbackDisplayOfZeroAngles = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam.Add(new ScreenspaceLineCircled_angleFromStartPos_cam(targetCamera, startPos, circleCenter, turnAngleDegCC, color, width_relToViewportHeight, text, skipFallbackDisplayOfZeroAngles, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec)); + return; + } + + UtilitiesDXXL_LineCircled.LineCircledScreenspace(targetCamera, startPos, circleCenter, turnAngleDegCC, color, width_relToViewportHeight, text, skipFallbackDisplayOfZeroAngles, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, true); + } + + public static void CircleSegment(Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius_relToViewportHeight = 0.05f, Color color = default(Color), string text = null, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.CircleSegment") == false) { return; } + CircleSegment(automaticallyFoundCamera, circleCenter, startAngleDegCC_relativeToUp, endAngleDegCC_relativeToUp, radius_relToViewportHeight, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, minAngleDeg_withoutTextLineBreak, durationInSec); + } + public static void CircleSegment(Camera targetCamera, Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius_relToViewportHeight = 0.05f, Color color = default(Color), string text = null, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(startAngleDegCC_relativeToUp, "startAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(endAngleDegCC_relativeToUp, "endAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_relToViewportHeight, "radius_relToViewportHeight")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam.Add(new ScreenspaceCircleSegment_angleToAngle_cam(targetCamera, circleCenter, startAngleDegCC_relativeToUp, endAngleDegCC_relativeToUp, radius_relToViewportHeight, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, minAngleDeg_withoutTextLineBreak, durationInSec)); + return; + } + + Quaternion rotation_fromGlobalUp_toLineStartAngleInXYplane = Quaternion.AngleAxis(startAngleDegCC_relativeToUp, Vector3.forward); + Vector3 circleCenter_to_startPos_inUnwarpedSpace_normalized = rotation_fromGlobalUp_toLineStartAngleInXYplane * Vector3.up; + Vector2 circleCenter_to_startPos_inWarpedSpace_normalized = DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(circleCenter_to_startPos_inUnwarpedSpace_normalized, targetCamera); + Vector2 circleCenter_to_startPosOnPerimeter_inWarpedScreenspaceSpace = circleCenter_to_startPos_inWarpedSpace_normalized * radius_relToViewportHeight; + Vector2 startPosOnPerimeter = circleCenter + circleCenter_to_startPosOnPerimeter_inWarpedScreenspaceSpace; + float turnAngleDegCC = endAngleDegCC_relativeToUp - startAngleDegCC_relativeToUp; + CircleSegment(targetCamera, startPosOnPerimeter, circleCenter, turnAngleDegCC, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, minAngleDeg_withoutTextLineBreak, durationInSec); + } + + public static void CircleSegment(Vector2 startPosOnPerimeter, Vector2 circleCenter, float turnAngleDegCC, Color color = default(Color), string text = null, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.CircleSegment") == false) { return; } + CircleSegment(automaticallyFoundCamera, startPosOnPerimeter, circleCenter, turnAngleDegCC, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, minAngleDeg_withoutTextLineBreak, durationInSec); + } + public static void CircleSegment(Camera targetCamera, Vector2 startPosOnPerimeter, Vector2 circleCenter, float turnAngleDegCC, Color color = default(Color), string text = null, float radiusPortionWhereDrawFillStarts = 0.0f, bool skipFallbackDisplayOfZeroAngles = false, float fillDensity = 1.0f, float minAngleDeg_withoutTextLineBreak = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam.Add(new ScreenspaceCircleSegment_angleFromStartPos_cam(targetCamera, startPosOnPerimeter, circleCenter, turnAngleDegCC, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, minAngleDeg_withoutTextLineBreak, durationInSec)); + return; + } + + UtilitiesDXXL_LineCircled.CircleSegmentScreenspace(targetCamera, startPosOnPerimeter, circleCenter, turnAngleDegCC, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL.LowerLeftOfWholeTextBlock, durationInSec, true); + } + + public static void LineString(Vector2[] points, Color color = default(Color), bool closeGapBetweenLastAndFirstPoint = false, float width_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineString") == false) { return; } + LineString(automaticallyFoundCamera, points, color, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec); + } + + public static void LineString(Camera targetCamera, Vector2[] points, Color color = default(Color), bool closeGapBetweenLastAndFirstPoint = false, float width_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineString_array_cam.Add(new ScreenspaceLineString_array_cam(targetCamera, points, color, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec)); + return; + } + + if (points.Length == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_relToViewportHeight, "width_relToViewportHeight")) { return; } + width_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(width_relToViewportHeight); + + for (int i = 0; i < (points.Length - 1); i++) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, points[i], points[i + 1], color, width_relToViewportHeight, null, style, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, points[points.Length - 1], points[0], color, width_relToViewportHeight, null, style, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + if (drawPointerIfOffscreen || (text != null && text != "")) + { + UtilitiesDXXL_List.CopyContentOfVector2ArrayToList(ref UtilitiesDXXL_Screenspace.vertices_inViewportSpace0to1, ref points, points.Length); + Color invertedColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(color); + UtilitiesDXXL_Screenspace.TagPointCollection(targetCamera, text, null, points.Length, 0.3f * width_relToViewportHeight, invertedColor, invertedColor, drawPointerIfOffscreen, false, durationInSec, 1.0f, true); + } + } + + public static void LineString(List points, Color color = default(Color), bool closeGapBetweenLastAndFirstPoint = false, float width_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineString") == false) { return; } + LineString(automaticallyFoundCamera, points, color, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec); + } + public static void LineString(Camera targetCamera, List points, Color color = default(Color), bool closeGapBetweenLastAndFirstPoint = false, float width_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineString_list_cam.Add(new ScreenspaceLineString_list_cam(targetCamera, points, color, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec)); + return; + } + + if (points.Count == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_relToViewportHeight, "width_relToViewportHeight")) { return; } + width_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(width_relToViewportHeight); + + for (int i = 0; i < (points.Count - 1); i++) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, points[i], points[i + 1], color, width_relToViewportHeight, null, style, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, points[points.Count - 1], points[0], color, width_relToViewportHeight, null, style, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + if (drawPointerIfOffscreen || (text != null && text != "")) + { + UtilitiesDXXL_List.CopyContentOfVector2Lists(ref UtilitiesDXXL_Screenspace.vertices_inViewportSpace0to1, ref points, points.Count); + Color invertedColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(color); + UtilitiesDXXL_Screenspace.TagPointCollection(targetCamera, text, null, points.Count, 0.3f * width_relToViewportHeight, invertedColor, invertedColor, drawPointerIfOffscreen, false, durationInSec, 1.0f, true); + } + } + + public static void LineStringColorFade(Vector2[] points, Color startColor, Color endColor, bool closeGapBetweenLastAndFirstPoint = false, float width_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineStringColorFade") == false) { return; } + LineStringColorFade(automaticallyFoundCamera, points, startColor, endColor, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec); + } + public static void LineStringColorFade(Camera targetCamera, Vector2[] points, Color startColor, Color endColor, bool closeGapBetweenLastAndFirstPoint = false, float width_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineStringColorFade_array_cam.Add(new ScreenspaceLineStringColorFade_array_cam(targetCamera, points, startColor, endColor, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec)); + return; + } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_relToViewportHeight, "width_relToViewportHeight")) { return; } + width_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(width_relToViewportHeight); + + if (points.Length == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + int iOffset_forColorFade = -1; + if (closeGapBetweenLastAndFirstPoint) + { + iOffset_forColorFade = 0; + } + + for (int i = 0; i < (points.Length - 1); i++) + { + Color color = UtilitiesDXXL_DrawBasics.GetFadedColorFromSegments(startColor, endColor, i, points.Length + iOffset_forColorFade); + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, points[i], points[i + 1], color, width_relToViewportHeight, null, style, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, points[points.Length - 1], points[0], endColor, width_relToViewportHeight, null, style, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + if (drawPointerIfOffscreen || (text != null && text != "")) + { + UtilitiesDXXL_List.CopyContentOfVector2ArrayToList(ref UtilitiesDXXL_Screenspace.vertices_inViewportSpace0to1, ref points, points.Length); + Color invertedAverageColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(Color.Lerp(startColor, endColor, 0.5f)); + UtilitiesDXXL_Screenspace.TagPointCollection(targetCamera, text, null, points.Length, 0.3f * width_relToViewportHeight, invertedAverageColor, invertedAverageColor, drawPointerIfOffscreen, false, durationInSec, 1.0f, true); + } + + } + public static void LineStringColorFade(List points, Color startColor, Color endColor, bool closeGapBetweenLastAndFirstPoint = false, float width_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineStringColorFade") == false) { return; } + LineStringColorFade(automaticallyFoundCamera, points, startColor, endColor, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec); + } + public static void LineStringColorFade(Camera targetCamera, List points, Color startColor, Color endColor, bool closeGapBetweenLastAndFirstPoint = false, float width_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineStringColorFade_list_cam.Add(new ScreenspaceLineStringColorFade_list_cam(targetCamera, points, startColor, endColor, closeGapBetweenLastAndFirstPoint, width_relToViewportHeight, text, drawPointerIfOffscreen, style, stylePatternScaleFactor, durationInSec)); + return; + } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_relToViewportHeight, "width_relToViewportHeight")) { return; } + width_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(width_relToViewportHeight); + + if (points.Count == 0) + { + Debug.Log("'points' has 0 items -> no drawing"); + return; + } + + int iOffset_forColorFade = -1; + if (closeGapBetweenLastAndFirstPoint) + { + iOffset_forColorFade = 0; + } + + for (int i = 0; i < (points.Count - 1); i++) + { + Color color = UtilitiesDXXL_DrawBasics.GetFadedColorFromSegments(startColor, endColor, i, points.Count + iOffset_forColorFade); + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, points[i], points[i + 1], color, width_relToViewportHeight, null, style, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + if (closeGapBetweenLastAndFirstPoint) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, points[points.Count - 1], points[0], endColor, width_relToViewportHeight, null, style, stylePatternScaleFactor, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + if (drawPointerIfOffscreen || (text != null && text != "")) + { + UtilitiesDXXL_List.CopyContentOfVector2Lists(ref UtilitiesDXXL_Screenspace.vertices_inViewportSpace0to1, ref points, points.Count); + Color invertedAverageColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(Color.Lerp(startColor, endColor, 0.5f)); + UtilitiesDXXL_Screenspace.TagPointCollection(targetCamera, text, null, points.Count, 0.3f * width_relToViewportHeight, invertedAverageColor, invertedAverageColor, drawPointerIfOffscreen, false, durationInSec, 1.0f, true); + } + } + + public static void Shape(Vector3 centerPosition_in3DWorldspace, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, Color color = default(Color), float width_relToViewportHeight = 0.1f, float height_relToViewportHeight = 0.1f, float zRotationDegCC = 0.0f, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = true, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceShape_3Dpos.Add(new ScreenspaceShape_3Dpos(centerPosition_in3DWorldspace, shape, color, width_relToViewportHeight, height_relToViewportHeight, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Shape") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, centerPosition_in3DWorldspace, false); + Shape(position_in2DViewportSpace, shape, color, width_relToViewportHeight, height_relToViewportHeight, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Shape(Camera targetCamera, Vector3 centerPosition_in3DWorldspace, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, Color color = default(Color), float width_relToViewportHeight = 0.1f, float height_relToViewportHeight = 0.1f, float zRotationDegCC = 0.0f, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = true, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceShape_3Dpos_cam.Add(new ScreenspaceShape_3Dpos_cam(targetCamera, centerPosition_in3DWorldspace, shape, color, width_relToViewportHeight, height_relToViewportHeight, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(targetCamera, centerPosition_in3DWorldspace, false); + Shape(targetCamera, position_in2DViewportSpace, shape, color, width_relToViewportHeight, height_relToViewportHeight, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Shape(Vector2 centerPosition_in2DViewportSpace, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, Color color = default(Color), float width_relToViewportHeight = 0.1f, float height_relToViewportHeight = 0.1f, float zRotationDegCC = 0.0f, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = true, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Shape") == false) { return; } + Shape(automaticallyFoundCamera, centerPosition_in2DViewportSpace, shape, color, width_relToViewportHeight, height_relToViewportHeight, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Shape(Camera targetCamera, Vector2 centerPosition_in2DViewportSpace, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, Color color = default(Color), float width_relToViewportHeight = 0.1f, float height_relToViewportHeight = 0.1f, float zRotationDegCC = 0.0f, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = true, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceShape_2Dpos_cam.Add(new ScreenspaceShape_2Dpos_cam(targetCamera, centerPosition_in2DViewportSpace, shape, color, width_relToViewportHeight, height_relToViewportHeight, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + UtilitiesDXXL_Screenspace.DrawShape(targetCamera, centerPosition_in2DViewportSpace, shape, color, color, width_relToViewportHeight, height_relToViewportHeight, zRotationDegCC, linesWidth_relToViewportHeight, text, lineStyle, stylePatternScaleFactor, fillStyle, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, durationInSec, 1.0f, null, true); + } + + public static void Rectangle(Rect rect, Color color = default(Color), DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth_relTScreenHeight = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Rectangle") == false) { return; } + Rectangle(automaticallyFoundCamera, rect, color, shape, linesWidth_relTScreenHeight, text, lineStyle, stylePatternScaleFactor, fillStyle, durationInSec); + } + public static void Rectangle(Camera targetCamera, Rect rect, Color color = default(Color), DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth_relToScreenHeight = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Rectangle(targetCamera, rect.position, rect.width, rect.height, color, shape, linesWidth_relToScreenHeight, text, lineStyle, stylePatternScaleFactor, fillStyle, durationInSec); + } + + static InternalDXXL_Plane rectPlane = new InternalDXXL_Plane(); + public static void Rectangle(Vector2 lowLeftCorner, float width_relToScreenWidth, float height_relToScreenHeight, Color color = default(Color), DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth_relToScreenHeight = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Rectangle") == false) { return; } + Rectangle(automaticallyFoundCamera, lowLeftCorner, width_relToScreenWidth, height_relToScreenHeight, color, shape, linesWidth_relToScreenHeight, text, lineStyle, stylePatternScaleFactor, fillStyle, durationInSec); + } + public static void Rectangle(Camera targetCamera, Vector2 lowLeftCorner, float width_relToScreenWidth, float height_relToScreenHeight, Color color = default(Color), DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth_relToScreenHeight = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth_relToScreenHeight, "linesWidth_relToScreenHeight")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceRectangle.Add(new ScreenspaceRectangle(targetCamera, lowLeftCorner, width_relToScreenWidth, height_relToScreenHeight, color, shape, linesWidth_relToScreenHeight, text, lineStyle, stylePatternScaleFactor, fillStyle, durationInSec)); + return; + } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_relToScreenWidth, "width_relToScreenWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height_relToScreenHeight, "height_relToScreenHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth_relToScreenHeight, "linesWidth_relToScreenHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stylePatternScaleFactor, "stylePatternScaleFactor")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(lowLeftCorner, "lowLeftCorner")) { return; } + + if (UtilitiesDXXL_Screenspace.HasDefaultViewPortRect(targetCamera) == false) + { + text = "[ 'DrawScreenspace.Rectangle()' is not fit for non-default camera viewport rects
-> Fallback to 'Shape()']
" + text; + Vector2 centerPosition = new Vector2(lowLeftCorner.x + 0.5f * width_relToScreenWidth, lowLeftCorner.y + 0.5f * height_relToScreenHeight); + float width_relToScreenHeight = width_relToScreenWidth * targetCamera.aspect; + Shape(targetCamera, centerPosition, shape, color, width_relToScreenHeight, height_relToScreenHeight, 0.0f, linesWidth_relToScreenHeight, text, false, lineStyle, stylePatternScaleFactor, fillStyle, false, durationInSec); + return; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(width_relToScreenWidth) && UtilitiesDXXL_Math.ApproximatelyZero(height_relToScreenHeight)) + { + UtilitiesDXXL_Screenspace.PointFallback(targetCamera, lowLeftCorner, "[ RectangleScreenspace with extent of 0]
" + text, color, linesWidth_relToScreenHeight, durationInSec); + return; + } + + Rect rect = new Rect(lowLeftCorner, new Vector2(width_relToScreenWidth, height_relToScreenHeight)); + lineStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(lineStyle); + float distanceToRectPlane = targetCamera.nearClipPlane + drawOffsetBehindCamsNearPlane; + Vector3 screenSpaceCenter_insideRectPlane = targetCamera.transform.position + targetCamera.transform.forward * distanceToRectPlane; + float heightOfScreenSpace_insideRectPlane; + if (targetCamera.orthographic) + { + //orthographic cam: + heightOfScreenSpace_insideRectPlane = 2.0f * targetCamera.orthographicSize; + stylePatternScaleFactor = stylePatternScaleFactor * targetCamera.orthographicSize; + } + else + { + //perspective cam: + float tanOfHalfFieldOfView = Mathf.Tan(0.5f * targetCamera.fieldOfView * Mathf.Deg2Rad); + heightOfScreenSpace_insideRectPlane = 2.0f * distanceToRectPlane * tanOfHalfFieldOfView; + stylePatternScaleFactor = stylePatternScaleFactor * heightOfScreenSpace_insideRectPlane; + } + float linesWidth_worldSpace = heightOfScreenSpace_insideRectPlane * linesWidth_relToScreenHeight; + linesWidth_worldSpace = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth_worldSpace); + float halfLinesWidth_worldSpace = 0.5f * linesWidth_worldSpace; + float widthOfScreenspace_insideRectPlane = heightOfScreenSpace_insideRectPlane * targetCamera.aspect; + Vector3 camLeftNormalized = Vector3.Cross(targetCamera.transform.forward, targetCamera.transform.up); + Vector3 camRightNormalized = -camLeftNormalized; + Vector3 screenSpaceLowLeft_insideRectPlane = screenSpaceCenter_insideRectPlane + camLeftNormalized * (0.5f * widthOfScreenspace_insideRectPlane) - targetCamera.transform.up * (0.5f * heightOfScreenSpace_insideRectPlane); + Vector3 screenSpaceXspan0to1_insideRectPlane = camRightNormalized * widthOfScreenspace_insideRectPlane; + Vector3 screenSpaceYspan0to1_insideRectPlane = targetCamera.transform.up * heightOfScreenSpace_insideRectPlane; + Vector3 centerOfDrawnRect = screenSpaceLowLeft_insideRectPlane + screenSpaceXspan0to1_insideRectPlane * rect.center.x + screenSpaceYspan0to1_insideRectPlane * rect.center.y; + float heightOfDrawnRect = heightOfScreenSpace_insideRectPlane * rect.height; + float widthOfDrawnRect = widthOfScreenspace_insideRectPlane * rect.width; + int usedSlotsIn_verticesGlobal; + + if (shape == DrawShapes.Shape2DType.square) + { + Vector3 bottomLeftCorner_ofDrawnRect_worldSpace = screenSpaceLowLeft_insideRectPlane + screenSpaceXspan0to1_insideRectPlane * rect.x + screenSpaceYspan0to1_insideRectPlane * rect.y; + Vector3 topLeftCorner_ofDrawnRect_worldSpace = screenSpaceLowLeft_insideRectPlane + screenSpaceXspan0to1_insideRectPlane * rect.x + screenSpaceYspan0to1_insideRectPlane * (rect.y + rect.height); + Vector3 bottomRightCorner_ofDrawnRect_worldSpace = screenSpaceLowLeft_insideRectPlane + screenSpaceXspan0to1_insideRectPlane * (rect.x + rect.width) + screenSpaceYspan0to1_insideRectPlane * rect.y; + Vector3 topRightCorner_ofDrawnRect_worldSpace = screenSpaceLowLeft_insideRectPlane + screenSpaceXspan0to1_insideRectPlane * (rect.x + rect.width) + screenSpaceYspan0to1_insideRectPlane * (rect.y + rect.height); + rectPlane.Recreate(centerOfDrawnRect, targetCamera.transform.forward); + + UtilitiesDXXL_DrawBasics.Line(bottomLeftCorner_ofDrawnRect_worldSpace - targetCamera.transform.up * halfLinesWidth_worldSpace, topLeftCorner_ofDrawnRect_worldSpace + targetCamera.transform.up * halfLinesWidth_worldSpace, color, linesWidth_worldSpace, null, lineStyle, stylePatternScaleFactor, 0.0f, null, rectPlane, true, 0.0f, 0.0f, durationInSec, false, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(bottomRightCorner_ofDrawnRect_worldSpace - targetCamera.transform.up * halfLinesWidth_worldSpace, topRightCorner_ofDrawnRect_worldSpace + targetCamera.transform.up * halfLinesWidth_worldSpace, color, linesWidth_worldSpace, null, lineStyle, stylePatternScaleFactor, 0.0f, null, rectPlane, true, 0.0f, 0.0f, durationInSec, false, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(bottomLeftCorner_ofDrawnRect_worldSpace + camLeftNormalized * halfLinesWidth_worldSpace, bottomRightCorner_ofDrawnRect_worldSpace + camRightNormalized * halfLinesWidth_worldSpace, color, linesWidth_worldSpace, null, lineStyle, stylePatternScaleFactor, 0.0f, null, rectPlane, true, 0.0f, 0.0f, durationInSec, false, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(topLeftCorner_ofDrawnRect_worldSpace + camLeftNormalized * halfLinesWidth_worldSpace, topRightCorner_ofDrawnRect_worldSpace + camRightNormalized * halfLinesWidth_worldSpace, color, linesWidth_worldSpace, null, lineStyle, stylePatternScaleFactor, 0.0f, null, rectPlane, true, 0.0f, 0.0f, durationInSec, false, false, false, null, false, 0.0f); + usedSlotsIn_verticesGlobal = 4; + + UtilitiesDXXL_List.AddToAVectorList(ref UtilitiesDXXL_Shapes.verticesGlobal, bottomLeftCorner_ofDrawnRect_worldSpace, 0); + UtilitiesDXXL_List.AddToAVectorList(ref UtilitiesDXXL_Shapes.verticesGlobal, bottomRightCorner_ofDrawnRect_worldSpace, 1); + UtilitiesDXXL_List.AddToAVectorList(ref UtilitiesDXXL_Shapes.verticesGlobal, topRightCorner_ofDrawnRect_worldSpace, 2); + UtilitiesDXXL_List.AddToAVectorList(ref UtilitiesDXXL_Shapes.verticesGlobal, topLeftCorner_ofDrawnRect_worldSpace, 3); + } + else + { + usedSlotsIn_verticesGlobal = DrawShapes.FlatShape(centerOfDrawnRect, shape, widthOfDrawnRect, heightOfDrawnRect, color, targetCamera.transform.forward, targetCamera.transform.up, linesWidth_worldSpace, null, lineStyle, stylePatternScaleFactor, true, DrawBasics.LineStyle.invisible, false, durationInSec, false); + } + + if (fillStyle != DrawBasics.LineStyle.invisible) + { + Color fillColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.3f); + fillStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(fillStyle); + rectPlane.Recreate(centerOfDrawnRect, targetCamera.transform.forward); + float distanceBetweenLines_screenSpace = 0.01f; + float distanceBetweenLines_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, rect.center, true, distanceBetweenLines_screenSpace); + UtilitiesDXXL_Shapes.DrawShapeFilling(shape, fillStyle, usedSlotsIn_verticesGlobal, distanceBetweenLines_worldSpace, fillColor, targetCamera.transform.up, stylePatternScaleFactor, rectPlane, durationInSec, false); + } + + if (text != null && text != "") + { + float lineHeight = 0.02f * heightOfScreenSpace_insideRectPlane; + lineHeight = Mathf.Min(lineHeight, 0.9f * heightOfDrawnRect); + Vector3 topLeftCorner_ofDrawnRect = screenSpaceLowLeft_insideRectPlane + screenSpaceXspan0to1_insideRectPlane * rect.x + screenSpaceYspan0to1_insideRectPlane * (rect.y + rect.height); + Vector3 textPosition = topLeftCorner_ofDrawnRect + (0.02f * widthOfDrawnRect + halfLinesWidth_worldSpace) * camRightNormalized - (1.7f * lineHeight + halfLinesWidth_worldSpace) * targetCamera.transform.up; + UtilitiesDXXL_Text.Write(text, textPosition, color, lineHeight, camRightNormalized, targetCamera.transform.up, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.96f * widthOfDrawnRect - linesWidth_worldSpace, false, durationInSec, false, false, false, true); + } + } + + public static void Box(Rect rect, Color color = default(Color), float zRotationDegCC = 0.0f, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Box") == false) { return; } + Box(automaticallyFoundCamera, rect, color, zRotationDegCC, shape, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Box(Camera targetCamera, Rect rect, Color color = default(Color), float zRotationDegCC = 0.0f, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceBox_rect_cam.Add(new ScreenspaceBox_rect_cam(targetCamera, rect, color, zRotationDegCC, shape, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + float width_relToViewportHeight = rect.size.x * targetCamera.aspect; + Shape(targetCamera, rect.center, shape, color, width_relToViewportHeight, rect.size.y, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Box(Vector3 centerPosition_in3DWorldspace, Vector2 size_relToViewportHeight, Color color = default(Color), float zRotationDegCC = 0.0f, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool forceSizeInterpretationToWarpedViewportSpace = false, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceBox_3Dpos_vec.Add(new ScreenspaceBox_3Dpos_vec(centerPosition_in3DWorldspace, size_relToViewportHeight, color, zRotationDegCC, shape, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Box") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, centerPosition_in3DWorldspace, false); + Box(position_in2DViewportSpace, size_relToViewportHeight, color, zRotationDegCC, shape, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Box(Camera targetCamera, Vector3 centerPosition_in3DWorldspace, Vector2 size_relToViewportHeight, Color color = default(Color), float zRotationDegCC = 0.0f, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool forceSizeInterpretationToWarpedViewportSpace = false, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceBox_3Dpos_vec_cam.Add(new ScreenspaceBox_3Dpos_vec_cam(targetCamera, centerPosition_in3DWorldspace, size_relToViewportHeight, color, zRotationDegCC, shape, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(targetCamera, centerPosition_in3DWorldspace, false); + Box(targetCamera, position_in2DViewportSpace, size_relToViewportHeight, color, zRotationDegCC, shape, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Box(Vector2 centerPosition_in2DViewportSpace, Vector2 size_relToViewportHeight, Color color = default(Color), float zRotationDegCC = 0.0f, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool forceSizeInterpretationToWarpedViewportSpace = false, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Box") == false) { return; } + Box(automaticallyFoundCamera, centerPosition_in2DViewportSpace, size_relToViewportHeight, color, zRotationDegCC, shape, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Box(Camera targetCamera, Vector2 centerPosition_in2DViewportSpace, Vector2 size_relToViewportHeight, Color color = default(Color), float zRotationDegCC = 0.0f, DrawShapes.Shape2DType shape = DrawShapes.Shape2DType.square, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool forceSizeInterpretationToWarpedViewportSpace = false, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceBox_2Dpos_vec_cam.Add(new ScreenspaceBox_2Dpos_vec_cam(targetCamera, centerPosition_in2DViewportSpace, size_relToViewportHeight, color, zRotationDegCC, shape, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + if (forceSizeInterpretationToWarpedViewportSpace) + { + size_relToViewportHeight = DirectionInUnitsOfWarpedSpace_to_sameLookingDirectionInUnitsOfUnwarpedSpace(size_relToViewportHeight, targetCamera); + } + Shape(targetCamera, centerPosition_in2DViewportSpace, shape, color, size_relToViewportHeight.x, size_relToViewportHeight.y, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Circle(Rect rect, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Circle") == false) { return; } + Circle(automaticallyFoundCamera, rect, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Circle(Camera targetCamera, Rect rect, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCircle_rect_cam.Add(new ScreenspaceCircle_rect_cam(targetCamera, rect, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + Box(targetCamera, rect, color, 0.0f, DrawShapes.Shape2DType.circle, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Circle(Vector3 centerPosition_in3DWorldspace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCircle_3Dpos_vecRad.Add(new ScreenspaceCircle_3Dpos_vecRad(centerPosition_in3DWorldspace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Circle") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, centerPosition_in3DWorldspace, false); + Circle(position_in2DViewportSpace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Circle(Camera targetCamera, Vector3 centerPosition_in3DWorldspace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam.Add(new ScreenspaceCircle_3Dpos_vecRad_cam(targetCamera, centerPosition_in3DWorldspace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(targetCamera, centerPosition_in3DWorldspace, false); + Circle(targetCamera, position_in2DViewportSpace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Circle(Vector2 centerPosition_in2DViewportSpace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Circle") == false) { return; } + Circle(automaticallyFoundCamera, centerPosition_in2DViewportSpace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Circle(Camera targetCamera, Vector2 centerPosition_in2DViewportSpace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_relToViewportHeight, "radius_relToViewportHeight")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam.Add(new ScreenspaceCircle_2Dpos_vecRad_cam(targetCamera, centerPosition_in2DViewportSpace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + float diameter_relToViewportHeight = 2.0f * radius_relToViewportHeight; + bool forceSizeInterpretationToWarpedViewportSpace = false; + Box(targetCamera, centerPosition_in2DViewportSpace, new Vector2(diameter_relToViewportHeight, diameter_relToViewportHeight), color, 0.0f, DrawShapes.Shape2DType.circle, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Capsule(Vector3 posOfCircle1_in3DWorldspace, Vector3 posOfCircle2_in3DWorldspace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos.Add(new ScreenspaceCapsule_3Dpos_vecC1C2Pos(posOfCircle1_in3DWorldspace, posOfCircle2_in3DWorldspace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Capsule") == false) { return; } + Vector2 position1_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, posOfCircle1_in3DWorldspace, false); + Vector2 position2_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, posOfCircle2_in3DWorldspace, false); + Capsule(position1_in2DViewportSpace, position2_in2DViewportSpace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Capsule(Camera targetCamera, Vector3 posOfCircle1_in3DWorldspace, Vector3 posOfCircle2_in3DWorldspace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam.Add(new ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam(targetCamera, posOfCircle1_in3DWorldspace, posOfCircle2_in3DWorldspace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + Vector2 position1_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(targetCamera, posOfCircle1_in3DWorldspace, false); + Vector2 position2_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(targetCamera, posOfCircle2_in3DWorldspace, false); + Capsule(targetCamera, position1_in2DViewportSpace, position2_in2DViewportSpace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Capsule(Vector2 posOfCircle1_in2DViewportSpace, Vector2 posOfCircle2_in2DViewportSpace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Capsule") == false) { return; } + Capsule(automaticallyFoundCamera, posOfCircle1_in2DViewportSpace, posOfCircle2_in2DViewportSpace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Capsule(Camera targetCamera, Vector2 posOfCircle1_in2DViewportSpace, Vector2 posOfCircle2_in2DViewportSpace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam.Add(new ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam(targetCamera, posOfCircle1_in2DViewportSpace, posOfCircle2_in2DViewportSpace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + UtilitiesDXXL_Screenspace.Capsule(targetCamera, posOfCircle1_in2DViewportSpace, posOfCircle2_in2DViewportSpace, radius_relToViewportHeight, color, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Capsule(Rect rect, Color color = default(Color), CapsuleDirection2D capsuleDirection = CapsuleDirection2D.Vertical, float zRotationDegCC = 0.0f, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Capsule") == false) { return; } + Capsule(automaticallyFoundCamera, rect, color, capsuleDirection, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Capsule(Camera targetCamera, Rect rect, Color color = default(Color), CapsuleDirection2D capsuleDirection = CapsuleDirection2D.Vertical, float zRotationDegCC = 0.0f, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCapsule_rect_cam.Add(new ScreenspaceCapsule_rect_cam(targetCamera, rect, color, capsuleDirection, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + float width_relToViewportHeight = rect.size.x * targetCamera.aspect; + Vector2 size_relToViewportHeight = new Vector2(width_relToViewportHeight, rect.size.y); + bool forceSizeInterpretationToWarpedViewportSpace = false; + Capsule(targetCamera, rect.center, size_relToViewportHeight, color, capsuleDirection, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Capsule(Vector3 centerPosition_in3DWorldspace, Vector2 size_relToViewportHeight, Color color = default(Color), CapsuleDirection2D capsuleDirection = CapsuleDirection2D.Vertical, float zRotationDegCC = 0.0f, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool forceSizeInterpretationToWarpedViewportSpace = false, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize.Add(new ScreenspaceCapsule_3Dpos_vecPosSize(centerPosition_in3DWorldspace, size_relToViewportHeight, color, capsuleDirection, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Capsule") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, centerPosition_in3DWorldspace, false); + Capsule(position_in2DViewportSpace, size_relToViewportHeight, color, capsuleDirection, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Capsule(Camera targetCamera, Vector3 centerPosition_in3DWorldspace, Vector2 size_relToViewportHeight, Color color = default(Color), CapsuleDirection2D capsuleDirection = CapsuleDirection2D.Vertical, float zRotationDegCC = 0.0f, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool forceSizeInterpretationToWarpedViewportSpace = false, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam.Add(new ScreenspaceCapsule_3Dpos_vecPosSize_cam(targetCamera, centerPosition_in3DWorldspace, size_relToViewportHeight, color, capsuleDirection, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(targetCamera, centerPosition_in3DWorldspace, false); + Capsule(targetCamera, position_in2DViewportSpace, size_relToViewportHeight, color, capsuleDirection, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Capsule(Vector2 centerPosition_in2DViewportSpace, Vector2 size_relToViewportHeight, Color color = default(Color), CapsuleDirection2D capsuleDirection = CapsuleDirection2D.Vertical, float zRotationDegCC = 0.0f, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool forceSizeInterpretationToWarpedViewportSpace = false, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Capsule") == false) { return; } + Capsule(automaticallyFoundCamera, centerPosition_in2DViewportSpace, size_relToViewportHeight, color, capsuleDirection, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Capsule(Camera targetCamera, Vector2 centerPosition_in2DViewportSpace, Vector2 size_relToViewportHeight, Color color = default(Color), CapsuleDirection2D capsuleDirection = CapsuleDirection2D.Vertical, float zRotationDegCC = 0.0f, float linesWidth_relToViewportHeight = 0.0f, string text = null, bool drawPointerIfOffscreen = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool forceSizeInterpretationToWarpedViewportSpace = false, bool addTextForOutsideDistance_toOffscreenPointer = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam.Add(new ScreenspaceCapsule_2Dpos_vecPosSize_cam(targetCamera, centerPosition_in2DViewportSpace, size_relToViewportHeight, color, capsuleDirection, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, forceSizeInterpretationToWarpedViewportSpace, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + if (forceSizeInterpretationToWarpedViewportSpace) + { + size_relToViewportHeight = DirectionInUnitsOfWarpedSpace_to_sameLookingDirectionInUnitsOfUnwarpedSpace(size_relToViewportHeight, targetCamera); + } + UtilitiesDXXL_Screenspace.Capsule(targetCamera, centerPosition_in2DViewportSpace, size_relToViewportHeight, color, capsuleDirection, zRotationDegCC, linesWidth_relToViewportHeight, text, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, durationInSec, true); + } + + public static void PointArray(Vector2[] points, Color color = default(Color), float sizeOfMarkingCross_relToViewportHeight = 0.1f, float markingCrossLinesWidth_relToViewportHeight = 0.0f, bool drawCoordsAsText = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.PointArray") == false) { return; } + PointArray(automaticallyFoundCamera, points, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, drawCoordsAsText, durationInSec); + } + public static void PointArray(Camera targetCamera, Vector2[] points, Color color = default(Color), float sizeOfMarkingCross_relToViewportHeight = 0.1f, float markingCrossLinesWidth_relToViewportHeight = 0.0f, bool drawCoordsAsText = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspacePointArray.Add(new ScreenspacePointArray(targetCamera, points, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, drawCoordsAsText, durationInSec)); + return; + } + + for (int i = 0; i < points.Length; i++) + { + Point(targetCamera, points[i], null, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, 0.0f, false, false, drawCoordsAsText, false, durationInSec); + } + } + public static void PointList(List points, Color color = default(Color), float sizeOfMarkingCross_relToViewportHeight = 0.1f, float markingCrossLinesWidth_relToViewportHeight = 0.0f, bool drawCoordsAsText = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.PointList") == false) { return; } + PointList(automaticallyFoundCamera, points, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, drawCoordsAsText, durationInSec); + } + public static void PointList(Camera targetCamera, List points, Color color = default(Color), float sizeOfMarkingCross_relToViewportHeight = 0.1f, float markingCrossLinesWidth_relToViewportHeight = 0.0f, bool drawCoordsAsText = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(points, "points")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspacePointList.Add(new ScreenspacePointList(targetCamera, points, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, drawCoordsAsText, durationInSec)); + return; + } + + for (int i = 0; i < points.Count; i++) + { + Point(targetCamera, points[i], null, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, 0.0f, false, false, drawCoordsAsText, false, durationInSec); + } + } + + public static void Point(Vector2 position, Color color, float sizeOfMarkingCross_relToViewportHeight = 0.1f, float zRotationDegCC = 0.0f, float markingCrossLinesWidth_relToViewportHeight = 0.0f, bool drawPointerIfOffscreen = false, string text = null, bool pointer_as_textAttachStyle = true, bool drawCoordsAsText = true, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspacePoint.Add(new ScreenspacePoint(position, color, sizeOfMarkingCross_relToViewportHeight, zRotationDegCC, markingCrossLinesWidth_relToViewportHeight, drawPointerIfOffscreen, text, pointer_as_textAttachStyle, drawCoordsAsText, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Point") == false) { return; } + Point(automaticallyFoundCamera, position, color, sizeOfMarkingCross_relToViewportHeight, zRotationDegCC, markingCrossLinesWidth_relToViewportHeight, drawPointerIfOffscreen, text, pointer_as_textAttachStyle, drawCoordsAsText, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Point(Camera targetCamera, Vector2 position, Color color, float sizeOfMarkingCross_relToViewportHeight = 0.1f, float zRotationDegCC = 0.0f, float markingCrossLinesWidth_relToViewportHeight = 0.0f, bool drawPointerIfOffscreen = false, string text = null, bool pointer_as_textAttachStyle = true, bool drawCoordsAsText = true, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Point(targetCamera, position, text, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, zRotationDegCC, drawPointerIfOffscreen, pointer_as_textAttachStyle, drawCoordsAsText, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + + public static void Point(Vector2 position, string text = null, Color color = default(Color), float sizeOfMarkingCross_relToViewportHeight = 0.1f, float markingCrossLinesWidth_relToViewportHeight = 0.0f, float zRotationDegCC = 0.0f, bool drawPointerIfOffscreen = false, bool pointer_as_textAttachStyle = true, bool drawCoordsAsText = true, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Point") == false) { return; } + Point(automaticallyFoundCamera, position, text, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, zRotationDegCC, drawPointerIfOffscreen, pointer_as_textAttachStyle, drawCoordsAsText, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + public static void Point(Camera targetCamera, Vector2 position, string text = null, Color color = default(Color), float sizeOfMarkingCross_relToViewportHeight = 0.1f, float markingCrossLinesWidth_relToViewportHeight = 0.0f, float zRotationDegCC = 0.0f, bool drawPointerIfOffscreen = false, bool pointer_as_textAttachStyle = true, bool drawCoordsAsText = true, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(sizeOfMarkingCross_relToViewportHeight, "sizeOfMarkingCross_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(markingCrossLinesWidth_relToViewportHeight, "markingCrossLinesWidth_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zRotationDegCC, "zRotationDegCC")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspacePoint_prioText_cam.Add(new ScreenspacePoint_prioText_cam(targetCamera, position, text, color, sizeOfMarkingCross_relToViewportHeight, markingCrossLinesWidth_relToViewportHeight, zRotationDegCC, drawPointerIfOffscreen, pointer_as_textAttachStyle, drawCoordsAsText, addTextForOutsideDistance_toOffscreenPointer, durationInSec)); + return; + } + + bool isOffscreen = !InternalDXXL_BoundsCamViewportSpace.IsInsideViewportInclBorder(position); + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + markingCrossLinesWidth_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(markingCrossLinesWidth_relToViewportHeight); + sizeOfMarkingCross_relToViewportHeight = Mathf.Abs(sizeOfMarkingCross_relToViewportHeight); + sizeOfMarkingCross_relToViewportHeight = UtilitiesDXXL_Math.Max(sizeOfMarkingCross_relToViewportHeight, 4.0f * markingCrossLinesWidth_relToViewportHeight, 0.016f); + + if (isOffscreen == false) + { + bool isZeroRotation = UtilitiesDXXL_Math.ApproximatelyZero(zRotationDegCC); + + float halfAbsMarkingCrossLinesWidth_relToViewportHeight = 0.5f * markingCrossLinesWidth_relToViewportHeight; + float halfAbsMarkingCrossLinesWidth_relToViewportWidth = halfAbsMarkingCrossLinesWidth_relToViewportHeight / targetCamera.aspect; + + float halfMarkingCrossSize_relToViewportHeight = 0.5f * sizeOfMarkingCross_relToViewportHeight; + float halfMarkingCrossSize_relToViewportWidth = halfMarkingCrossSize_relToViewportHeight / targetCamera.aspect; + + Vector2 point_toUnrotatedLeftMiddle = new Vector2(-halfMarkingCrossSize_relToViewportWidth, 0.0f); + Vector2 point_toUnrotatedRightMiddle = new Vector2(halfMarkingCrossSize_relToViewportWidth, 0.0f); + Vector2 point_toUnrotatedLowMiddle = new Vector2(0.0f, -halfMarkingCrossSize_relToViewportHeight); + Vector2 point_toUnrotatedHighMiddle = new Vector2(0.0f, halfMarkingCrossSize_relToViewportHeight); + + Vector2 leftMiddlePos_viewportSpace = position + point_toUnrotatedLeftMiddle; + Vector2 rightMiddlePos_viewportSpace = position + point_toUnrotatedRightMiddle; + Vector2 lowMiddlePos_viewportSpace = position + point_toUnrotatedLowMiddle; + Vector2 highMiddlePos_viewportSpace = position + point_toUnrotatedHighMiddle; + + Color colorOf_nonRotLinesAndCoordsText = color; + + if (isZeroRotation) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, leftMiddlePos_viewportSpace, rightMiddlePos_viewportSpace, color, markingCrossLinesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, lowMiddlePos_viewportSpace, highMiddlePos_viewportSpace, color, markingCrossLinesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + else + { + if (drawCoordsAsText) + { + colorOf_nonRotLinesAndCoordsText = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, (markingCrossLinesWidth_relToViewportHeight > 0.0f) ? 0.6f : 0.4f); + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, leftMiddlePos_viewportSpace, rightMiddlePos_viewportSpace, colorOf_nonRotLinesAndCoordsText, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, lowMiddlePos_viewportSpace, highMiddlePos_viewportSpace, colorOf_nonRotLinesAndCoordsText, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + point_toUnrotatedLeftMiddle = new Vector2(-halfMarkingCrossSize_relToViewportHeight, 0.0f); + point_toUnrotatedRightMiddle = new Vector2(halfMarkingCrossSize_relToViewportHeight, 0.0f); + point_toUnrotatedLowMiddle = new Vector2(0.0f, -halfMarkingCrossSize_relToViewportHeight); + point_toUnrotatedHighMiddle = new Vector2(0.0f, halfMarkingCrossSize_relToViewportHeight); + + Quaternion rotation = Quaternion.AngleAxis(zRotationDegCC, Vector3.forward); + + Vector2 point_toRotatedLeftMiddle = rotation * point_toUnrotatedLeftMiddle; + point_toRotatedLeftMiddle = new Vector2(point_toRotatedLeftMiddle.x / targetCamera.aspect, point_toRotatedLeftMiddle.y); + Vector2 point_toRotatedRightMiddle = rotation * point_toUnrotatedRightMiddle; + point_toRotatedRightMiddle = new Vector2(point_toRotatedRightMiddle.x / targetCamera.aspect, point_toRotatedRightMiddle.y); + Vector2 point_toRotatedLowMiddle = rotation * point_toUnrotatedLowMiddle; + point_toRotatedLowMiddle = new Vector2(point_toRotatedLowMiddle.x / targetCamera.aspect, point_toRotatedLowMiddle.y); + Vector2 point_toRotatedHighMiddle = rotation * point_toUnrotatedHighMiddle; + point_toRotatedHighMiddle = new Vector2(point_toRotatedHighMiddle.x / targetCamera.aspect, point_toRotatedHighMiddle.y); + + leftMiddlePos_viewportSpace = position + point_toRotatedLeftMiddle; + rightMiddlePos_viewportSpace = position + point_toRotatedRightMiddle; + lowMiddlePos_viewportSpace = position + point_toRotatedLowMiddle; + highMiddlePos_viewportSpace = position + point_toRotatedHighMiddle; + + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, leftMiddlePos_viewportSpace, rightMiddlePos_viewportSpace, color, markingCrossLinesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, lowMiddlePos_viewportSpace, highMiddlePos_viewportSpace, color, markingCrossLinesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + DrawCoordsAsText(drawCoordsAsText, targetCamera, position, colorOf_nonRotLinesAndCoordsText, halfMarkingCrossSize_relToViewportHeight, halfMarkingCrossSize_relToViewportWidth, halfAbsMarkingCrossLinesWidth_relToViewportWidth, halfAbsMarkingCrossLinesWidth_relToViewportHeight, minTextSize_relToViewportHeight, durationInSec); + } + + bool forcePointerDueToIsOffscreen = (isOffscreen && drawPointerIfOffscreen); + if (forcePointerDueToIsOffscreen || (text != null && text != "")) + { + if (pointer_as_textAttachStyle || isOffscreen) + { + float widthOfLinesTowardsText = 0.3f * markingCrossLinesWidth_relToViewportHeight; + PointTag(targetCamera, position, text, null, color, drawPointerIfOffscreen, widthOfLinesTowardsText, sizeOfMarkingCross_relToViewportHeight, default, 1.6f, false, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + else + { + float textSize_relToViewportHeight = 0.25f * sizeOfMarkingCross_relToViewportHeight; + textSize_relToViewportHeight = Mathf.Max(textSize_relToViewportHeight, minTextSize_relToViewportHeight); + UtilitiesDXXL_Text.WriteScreenspace(targetCamera, " " + text, position, color, textSize_relToViewportHeight, zRotationDegCC, DrawText.TextAnchorDXXL.UpperLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, false, durationInSec, false); + } + } + + return; + } + + static void DrawCoordsAsText(bool drawCoordsAsText, Camera camera, Vector2 position, Color colorOf_nonRotLinesAndCoordsText, float halfMarkingCrossSize_relToViewportHeight, float halfMarkingCrossSize_relToViewportWidth, float halfAbsMarkingCrossLinesWidth_relToViewportWidth, float halfAbsMarkingCrossLinesWidth_relToViewportHeight, float minTextSizeInScreenSpace, float durationInSec) + { + if (drawCoordsAsText) + { + Color colorOf_xySigns = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorOf_nonRotLinesAndCoordsText, 0.35f); + float coordsTextSize = Mathf.Max(0.1f * halfMarkingCrossSize_relToViewportHeight, minTextSizeInScreenSpace); + + float nonForced_yTextWidth = halfMarkingCrossSize_relToViewportWidth - halfAbsMarkingCrossLinesWidth_relToViewportWidth; + Vector2 posOf_yText = new Vector2(position.x + halfMarkingCrossSize_relToViewportWidth - nonForced_yTextWidth, position.y + halfAbsMarkingCrossLinesWidth_relToViewportHeight + 0.3f * coordsTextSize * camera.aspect); + UtilitiesDXXL_Text.WriteScreenspace(camera, " " + position.y, posOf_yText, colorOf_nonRotLinesAndCoordsText, coordsTextSize, 0.0f, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, nonForced_yTextWidth, 0.0f, false, 0.0f, false, durationInSec, false); + float sizeOfBiggestCharInFirstLine_inYValueText = DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine; + Vector2 posOf_ySign = new Vector2(position.x - halfMarkingCrossSize_relToViewportWidth, posOf_yText.y); + UtilitiesDXXL_Text.WriteScreenspace(camera, "y=", posOf_ySign, colorOf_xySigns, sizeOfBiggestCharInFirstLine_inYValueText, 0.0f, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, false, 0.0f, false, durationInSec, false); + + float nonForced_xTextWidth = halfMarkingCrossSize_relToViewportHeight - halfAbsMarkingCrossLinesWidth_relToViewportHeight; + Vector2 posOf_xText = new Vector2(position.x - halfAbsMarkingCrossLinesWidth_relToViewportWidth - 0.3f * coordsTextSize, position.y + halfMarkingCrossSize_relToViewportHeight - nonForced_xTextWidth); + UtilitiesDXXL_Text.WriteScreenspace(camera, " " + position.x, posOf_xText, colorOf_nonRotLinesAndCoordsText, coordsTextSize, 90.0f, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, nonForced_xTextWidth / camera.aspect, 0.0f, false, 0.0f, false, durationInSec, false); + float sizeOfBiggestCharInFirstLine_inXValueText = DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine; + Vector2 posOf_xSign = new Vector2(posOf_xText.x, position.y - halfMarkingCrossSize_relToViewportHeight); + UtilitiesDXXL_Text.WriteScreenspace(camera, "x=", posOf_xSign, colorOf_xySigns, sizeOfBiggestCharInFirstLine_inXValueText, 90.0f, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, false, 0.0f, false, durationInSec, false); + } + } + + public static void PointTag(Vector3 position_in3DWorldspace, string text = null, string titleText = null, Color color = default(Color), bool drawPointerIfOffscreen = true, float linesWidth_relToViewportHeight = 0.0f, float size_asTextOffsetDistance_relToViewportHeight = 0.2f, Vector2 textOffsetDirection = default(Vector2), float textSizeScaleFactor = 1.0f, bool skipConeDrawing = false, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f, Vector2 customTowardsPoint_ofDefaultTextOffsetDirection = default(Vector2)) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspacePointTag_3Dpos.Add(new ScreenspacePointTag_3Dpos(position_in3DWorldspace, text, titleText, color, drawPointerIfOffscreen, linesWidth_relToViewportHeight, size_asTextOffsetDistance_relToViewportHeight, textOffsetDirection, textSizeScaleFactor, skipConeDrawing, addTextForOutsideDistance_toOffscreenPointer, durationInSec, customTowardsPoint_ofDefaultTextOffsetDirection)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.PointTag") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + PointTag(position_in2DViewportSpace, text, titleText, color, drawPointerIfOffscreen, linesWidth_relToViewportHeight, size_asTextOffsetDistance_relToViewportHeight, textOffsetDirection, textSizeScaleFactor, skipConeDrawing, addTextForOutsideDistance_toOffscreenPointer, durationInSec, customTowardsPoint_ofDefaultTextOffsetDirection); + } + public static void PointTag(Camera targetCamera, Vector3 position_in3DWorldspace, string text = null, string titleText = null, Color color = default(Color), bool drawPointerIfOffscreen = true, float linesWidth_relToViewportHeight = 0.0f, float size_asTextOffsetDistance_relToViewportHeight = 0.2f, Vector2 textOffsetDirection = default(Vector2), float textSizeScaleFactor = 1.0f, bool skipConeDrawing = false, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f, Vector2 customTowardsPoint_ofDefaultTextOffsetDirection = default(Vector2)) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspacePointTag_3Dpos_cam.Add(new ScreenspacePointTag_3Dpos_cam(targetCamera, position_in3DWorldspace, text, titleText, color, drawPointerIfOffscreen, linesWidth_relToViewportHeight, size_asTextOffsetDistance_relToViewportHeight, textOffsetDirection, textSizeScaleFactor, skipConeDrawing, addTextForOutsideDistance_toOffscreenPointer, durationInSec, customTowardsPoint_ofDefaultTextOffsetDirection)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(targetCamera, position_in3DWorldspace, false); + PointTag(targetCamera, position_in2DViewportSpace, text, titleText, color, drawPointerIfOffscreen, linesWidth_relToViewportHeight, size_asTextOffsetDistance_relToViewportHeight, textOffsetDirection, textSizeScaleFactor, skipConeDrawing, addTextForOutsideDistance_toOffscreenPointer, durationInSec, customTowardsPoint_ofDefaultTextOffsetDirection); + } + + public static void PointTag(Vector2 position_in2DViewportSpace, string text = null, string titleText = null, Color color = default(Color), bool drawPointerIfOffscreen = true, float linesWidth_relToViewportHeight = 0.0f, float size_asTextOffsetDistance_relToViewportHeight = 0.2f, Vector2 textOffsetDirection = default(Vector2), float textSizeScaleFactor = 1.0f, bool skipConeDrawing = false, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f, Vector2 customTowardsPoint_ofDefaultTextOffsetDirection = default(Vector2)) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.PointTag") == false) { return; } + PointTag(automaticallyFoundCamera, position_in2DViewportSpace, text, titleText, color, drawPointerIfOffscreen, linesWidth_relToViewportHeight, size_asTextOffsetDistance_relToViewportHeight, textOffsetDirection, textSizeScaleFactor, skipConeDrawing, addTextForOutsideDistance_toOffscreenPointer, durationInSec, customTowardsPoint_ofDefaultTextOffsetDirection); + } + public static void PointTag(Camera targetCamera, Vector2 position_in2DViewportSpace, string text = null, string titleText = null, Color color = default(Color), bool drawPointerIfOffscreen = true, float linesWidth_relToViewportHeight = 0.0f, float size_asTextOffsetDistance_relToViewportHeight = 0.2f, Vector2 textOffsetDirection = default(Vector2), float textSizeScaleFactor = 1.0f, bool skipConeDrawing = false, bool addTextForOutsideDistance_toOffscreenPointer = true, float durationInSec = 0.0f, Vector2 customTowardsPoint_ofDefaultTextOffsetDirection = default(Vector2)) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspacePointTag_2Dpos_cam.Add(new ScreenspacePointTag_2Dpos_cam(targetCamera, position_in2DViewportSpace, text, titleText, color, drawPointerIfOffscreen, linesWidth_relToViewportHeight, size_asTextOffsetDistance_relToViewportHeight, textOffsetDirection, textSizeScaleFactor, skipConeDrawing, addTextForOutsideDistance_toOffscreenPointer, durationInSec, customTowardsPoint_ofDefaultTextOffsetDirection)); + return; + } + + UtilitiesDXXL_Screenspace.PointTag(targetCamera, position_in2DViewportSpace, text, titleText, color, color, drawPointerIfOffscreen, linesWidth_relToViewportHeight, size_asTextOffsetDistance_relToViewportHeight, textOffsetDirection, textSizeScaleFactor, skipConeDrawing, addTextForOutsideDistance_toOffscreenPointer, durationInSec, customTowardsPoint_ofDefaultTextOffsetDirection); + } + + public static void Vector(Vector2 vectorStartPos, Vector2 vectorEndPos, Color color = default(Color), float lineWidth_relToViewportHeight = 0.0f, string text = null, float coneLength_relToViewportHeight = 0.05f, bool pointerAtBothSides = false, bool writeComponentValuesAsText = false, float endPlatesSize_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Vector") == false) { return; } + Vector(automaticallyFoundCamera, vectorStartPos, vectorEndPos, color, lineWidth_relToViewportHeight, text, coneLength_relToViewportHeight, pointerAtBothSides, writeComponentValuesAsText, endPlatesSize_relToViewportHeight, durationInSec); + } + public static void Vector(Camera targetCamera, Vector2 vectorStartPos, Vector2 vectorEndPos, Color color = default(Color), float lineWidth_relToViewportHeight = 0.0f, string text = null, float coneLength_relToViewportHeight = 0.05f, bool pointerAtBothSides = false, bool writeComponentValuesAsText = false, float endPlatesSize_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorStartPos, "vectorStartPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + VectorFrom(targetCamera, vectorStartPos, vectorEndPos - vectorStartPos, color, lineWidth_relToViewportHeight, text, false, coneLength_relToViewportHeight, pointerAtBothSides, writeComponentValuesAsText, endPlatesSize_relToViewportHeight, durationInSec); + } + + public static void VectorFrom(Vector2 vectorStartPos, Vector2 vector, Color color = default(Color), float lineWidth_relToViewportHeight = 0.0f, string text = null, bool interpretVectorAsUnwarped = false, float coneLength_relToViewportHeight = 0.05f, bool pointerAtBothSides = false, bool writeComponentValuesAsText = false, float endPlatesSize_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.VectorFrom") == false) { return; } + VectorFrom(automaticallyFoundCamera, vectorStartPos, vector, color, lineWidth_relToViewportHeight, text, interpretVectorAsUnwarped, coneLength_relToViewportHeight, pointerAtBothSides, writeComponentValuesAsText, endPlatesSize_relToViewportHeight, durationInSec); + } + public static void VectorFrom(Camera targetCamera, Vector2 vectorStartPos, Vector2 vector, Color color = default(Color), float lineWidth_relToViewportHeight = 0.0f, string text = null, bool interpretVectorAsUnwarped = false, float coneLength_relToViewportHeight = 0.05f, bool pointerAtBothSides = false, bool writeComponentValuesAsText = false, float endPlatesSize_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth_relToViewportHeight, "lineWidth_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(coneLength_relToViewportHeight, "coneLength_relToViewportHeight")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorStartPos, "vectorStartPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector, "vector")) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceVectorFrom.Add(new ScreenspaceVectorFrom(targetCamera, vectorStartPos, vector, color, lineWidth_relToViewportHeight, text, interpretVectorAsUnwarped, coneLength_relToViewportHeight, pointerAtBothSides, writeComponentValuesAsText, endPlatesSize_relToViewportHeight, durationInSec)); + return; + } + + lineWidth_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth_relToViewportHeight); + + if (UtilitiesDXXL_Math.ApproximatelyZero(vector)) + { + UtilitiesDXXL_Screenspace.PointFallback(targetCamera, vectorStartPos, "[ VectorScreenspace with length of 0]
" + text, color, lineWidth_relToViewportHeight, durationInSec); + return; + } + + Vector2 vector_inNonSquareViewportSpace = interpretVectorAsUnwarped ? DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(vector, targetCamera) : vector; + Vector2 vectorEndPos_inNonSquareViewportSpace = vectorStartPos + vector_inNonSquareViewportSpace; + Vector2 middleOfVector_inNonSquareViewportSpace = 0.5f * (vectorStartPos + vectorEndPos_inNonSquareViewportSpace); + + bool isThinLine; + float lineWidth_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_relToViewportHeight)) + { + isThinLine = true; + } + else + { + lineWidth_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, middleOfVector_inNonSquareViewportSpace, true, lineWidth_relToViewportHeight); + isThinLine = false; + } + + Vector3 vectorStartPos_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, vectorStartPos, false); + Vector3 vectorEndPos_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, vectorEndPos_inNonSquareViewportSpace, false); + Vector3 vector_worldSpace = vectorEndPos_worldSpace - vectorStartPos_worldSpace; + Vector3 vectorNormalized_worldSpace = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(vector_worldSpace, out float vectorLength_worldSpace); + coneLength_relToViewportHeight = Mathf.Max(coneLength_relToViewportHeight, 0.0f); + float coneLength_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, middleOfVector_inNonSquareViewportSpace, true, coneLength_relToViewportHeight); + coneLength_worldSpace = Mathf.Clamp(coneLength_worldSpace, 0.01f * vectorLength_worldSpace, 0.45f * vectorLength_worldSpace); + + float coneAngleDeg = 25.0f; + if (isThinLine == false) + { + float coneSize_to_lineWidth_scaler = 1.3f; + float minConeAngleDeg = 2.0f * Mathf.Rad2Deg * Mathf.Atan(coneSize_to_lineWidth_scaler * lineWidth_worldSpace / coneLength_worldSpace); + coneAngleDeg = Mathf.Max(coneAngleDeg, minConeAngleDeg); + } + + float lengthTillConeStart_worldSpace = vectorLength_worldSpace - coneLength_worldSpace; + Vector3 endConeBaseCenter_worldSpace = vectorStartPos_worldSpace + vectorNormalized_worldSpace * lengthTillConeStart_worldSpace; + Vector3 startConeBaseCenter_worldSpace = vectorStartPos_worldSpace; + if (pointerAtBothSides) + { + startConeBaseCenter_worldSpace = vectorStartPos_worldSpace + vectorNormalized_worldSpace * coneLength_worldSpace; + } + + Vector3 startPos_ofNonConedLineSegment_worldSpace; + Vector3 endPos_ofNonConedLineSegment_worldSpace; + if (vectorStartPos.x < vectorEndPos_inNonSquareViewportSpace.x) + { + startPos_ofNonConedLineSegment_worldSpace = startConeBaseCenter_worldSpace; + endPos_ofNonConedLineSegment_worldSpace = endConeBaseCenter_worldSpace; + } + else + { + startPos_ofNonConedLineSegment_worldSpace = endConeBaseCenter_worldSpace; + endPos_ofNonConedLineSegment_worldSpace = startConeBaseCenter_worldSpace; + } + + UtilitiesDXXL_Screenspace.camPlane.Recreate(targetCamera.transform.position, targetCamera.transform.forward); + if (writeComponentValuesAsText) + { + text = "( " + vector.x + " , " + vector.y + " )
" + text; + } + float minTextSize_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, middleOfVector_inNonSquareViewportSpace, true, minTextSize_relToViewportHeight); + UtilitiesDXXL_DrawBasics.Line(startPos_ofNonConedLineSegment_worldSpace, endPos_ofNonConedLineSegment_worldSpace, color, lineWidth_worldSpace, text, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, UtilitiesDXXL_Screenspace.camPlane, true, 0.0f, minTextSize_worldSpace, durationInSec, false, false, false, targetCamera, false, 0.0f); + + float shorteningOf_straightLineInsideCone_worldSpace = 0.0f; + if (isThinLine == false) + { + shorteningOf_straightLineInsideCone_worldSpace = (0.5f * lineWidth_worldSpace) / Mathf.Tan(Mathf.Deg2Rad * 0.5f * coneAngleDeg); + shorteningOf_straightLineInsideCone_worldSpace = Mathf.Min(shorteningOf_straightLineInsideCone_worldSpace, 0.99f * coneLength_worldSpace); + } + + Vector3 lineEndInsideEndCone_worldSpace = vectorEndPos_worldSpace - vectorNormalized_worldSpace * shorteningOf_straightLineInsideCone_worldSpace; + UtilitiesDXXL_DrawBasics.Line(endConeBaseCenter_worldSpace, lineEndInsideEndCone_worldSpace, color, lineWidth_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, UtilitiesDXXL_Screenspace.camPlane, true, 0.0f, 0.0f, durationInSec, false, false, false, targetCamera, false, 0.0f); + if (pointerAtBothSides) + { + Vector3 lineEndInsideStartCone_worldSpace = vectorStartPos_worldSpace + vectorNormalized_worldSpace * shorteningOf_straightLineInsideCone_worldSpace; + UtilitiesDXXL_DrawBasics.Line(startConeBaseCenter_worldSpace, lineEndInsideStartCone_worldSpace, color, lineWidth_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, UtilitiesDXXL_Screenspace.camPlane, true, 0.0f, 0.0f, durationInSec, false, false, false, targetCamera, false, 0.0f); + } + + Vector3 upVector_ofConeBaseRect_worldSpace = targetCamera.transform.forward; + DrawShapes.ConeFilled(vectorEndPos_worldSpace, coneLength_worldSpace, -vector_worldSpace, upVector_ofConeBaseRect_worldSpace, 0.0f, coneAngleDeg, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, false); + if (pointerAtBothSides) + { + DrawShapes.ConeFilled(vectorStartPos_worldSpace, coneLength_worldSpace, vector_worldSpace, upVector_ofConeBaseRect_worldSpace, 0.0f, coneAngleDeg, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, false); + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(endPlatesSize_relToViewportHeight) == false) + { + DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.invisible; + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, vectorStartPos, vectorEndPos_inNonSquareViewportSpace, color, 0.0f, null, lineStyle, 1.0f, 0.0f, null, endPlatesSize_relToViewportHeight, 0.0f, 0.0f, durationInSec); + } + } + + public static void VectorTo(Vector2 vector, Vector2 vectorEndPos, Color color = default(Color), float lineWidth_relToViewportHeight = 0.0f, string text = null, bool interpretVectorAsUnwarped = false, float coneLength_relToViewportHeight = 0.05f, bool pointerAtBothSides = false, bool writeComponentValuesAsText = false, float endPlatesSize_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.VectorTo") == false) { return; } + VectorTo(automaticallyFoundCamera, vector, vectorEndPos, color, lineWidth_relToViewportHeight, text, interpretVectorAsUnwarped, coneLength_relToViewportHeight, pointerAtBothSides, writeComponentValuesAsText, endPlatesSize_relToViewportHeight, durationInSec); + } + public static void VectorTo(Camera targetCamera, Vector2 vector, Vector2 vectorEndPos, Color color = default(Color), float lineWidth_relToViewportHeight = 0.0f, string text = null, bool interpretVectorAsUnwarped = false, float coneLength_relToViewportHeight = 0.05f, bool pointerAtBothSides = false, bool writeComponentValuesAsText = false, float endPlatesSize_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector, "vector")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceVectorTo.Add(new ScreenspaceVectorTo(targetCamera, vector, vectorEndPos, color, lineWidth_relToViewportHeight, text, interpretVectorAsUnwarped, coneLength_relToViewportHeight, pointerAtBothSides, writeComponentValuesAsText, endPlatesSize_relToViewportHeight, durationInSec)); + return; + } + + Vector2 vectorEndPos_inNonSquareViewportSpace = vectorEndPos; + Vector2 vectorStartPos_inNonSquareViewportSpace; + if (interpretVectorAsUnwarped) + { + vectorStartPos_inNonSquareViewportSpace = vectorEndPos_inNonSquareViewportSpace - DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(vector, targetCamera); + } + else + { + vectorStartPos_inNonSquareViewportSpace = vectorEndPos_inNonSquareViewportSpace - vector; + } + VectorFrom(targetCamera, vectorStartPos_inNonSquareViewportSpace, vector, color, lineWidth_relToViewportHeight, text, interpretVectorAsUnwarped, coneLength_relToViewportHeight, pointerAtBothSides, writeComponentValuesAsText, endPlatesSize_relToViewportHeight, durationInSec); + } + + public static void VectorCircled(Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float lineWidth_relToViewportHeight = 0.0f, string text = null, float coneLength_relToViewportHeight = 0.05f, bool skipFallbackDisplayOfZeroAngles = false, bool pointerAtBothSides = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.VectorCircled") == false) { return; } + VectorCircled(automaticallyFoundCamera, circleCenter, startAngleDegCC_relativeToUp, endAngleDegCC_relativeToUp, radius_relToViewportHeight, color, lineWidth_relToViewportHeight, text, coneLength_relToViewportHeight, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec); + } + public static void VectorCircled(Camera targetCamera, Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius_relToViewportHeight = 0.05f, Color color = default(Color), float lineWidth_relToViewportHeight = 0.0f, string text = null, float coneLength_relToViewportHeight = 0.05f, bool skipFallbackDisplayOfZeroAngles = false, bool pointerAtBothSides = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(startAngleDegCC_relativeToUp, "startAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(endAngleDegCC_relativeToUp, "endAngleDegCC_relativeToUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_relToViewportHeight, "radius_relToViewportHeight")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam.Add(new ScreenspaceVectorCircled_angleToAngle_cam(targetCamera, circleCenter, startAngleDegCC_relativeToUp, endAngleDegCC_relativeToUp, radius_relToViewportHeight, color, lineWidth_relToViewportHeight, text, coneLength_relToViewportHeight, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec)); + return; + } + + Quaternion rotation_fromGlobalUp_toLineStartAngleInXYplane = Quaternion.AngleAxis(startAngleDegCC_relativeToUp, Vector3.forward); + Vector3 circleCenter_to_startPos_inUnwarpedSpace_normalized = rotation_fromGlobalUp_toLineStartAngleInXYplane * Vector3.up; + Vector2 circleCenter_to_startPos_inWarpedSpace_normalized = DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(circleCenter_to_startPos_inUnwarpedSpace_normalized, targetCamera); + Vector2 circleCenter_to_startPos_inWarpedScreenspaceSpace = circleCenter_to_startPos_inWarpedSpace_normalized * radius_relToViewportHeight; + Vector2 startPos = circleCenter + circleCenter_to_startPos_inWarpedScreenspaceSpace; + float turnAngleDegCC = endAngleDegCC_relativeToUp - startAngleDegCC_relativeToUp; + VectorCircled(targetCamera, startPos, circleCenter, turnAngleDegCC, color, lineWidth_relToViewportHeight, text, coneLength_relToViewportHeight, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec); + } + + public static void VectorCircled(Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color = default(Color), float lineWidth_relToViewportHeight = 0.0f, string text = null, float coneLength_relToViewportHeight = 0.05f, bool skipFallbackDisplayOfZeroAngles = false, bool pointerAtBothSides = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.VectorCircled") == false) { return; } + VectorCircled(automaticallyFoundCamera, startPos, circleCenter, turnAngleDegCC, color, lineWidth_relToViewportHeight, text, coneLength_relToViewportHeight, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec); + } + public static void VectorCircled(Camera targetCamera, Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color = default(Color), float lineWidth_relToViewportHeight = 0.0f, string text = null, float coneLength_relToViewportHeight = 0.05f, bool skipFallbackDisplayOfZeroAngles = false, bool pointerAtBothSides = false, float minAngleDeg_withoutTextLineBreak = 45.0f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam.Add(new ScreenspaceVectorCircled_angleFromStartPos_cam(targetCamera, startPos, circleCenter, turnAngleDegCC, color, lineWidth_relToViewportHeight, text, coneLength_relToViewportHeight, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec)); + return; + } + UtilitiesDXXL_LineCircled.VectorCircledScreenspace(targetCamera, startPos, circleCenter, turnAngleDegCC, color, lineWidth_relToViewportHeight, text, coneLength_relToViewportHeight, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec); + } + + public static void Icon(Vector3 position_in3DWorldspace, DrawBasics.IconType icon, Color color = default(Color), float size_relToViewportHeight = 0.1f, string text = null, float zRotationDegCC = 0.0f, float strokeWidth_relToViewportHeight = 0.0f, bool displayPointerIfOffscreen = false, bool mirrorHorizontally = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceIcon_3Dpos.Add(new ScreenspaceIcon_3Dpos(position_in3DWorldspace, icon, color, size_relToViewportHeight, text, zRotationDegCC, strokeWidth_relToViewportHeight, displayPointerIfOffscreen, mirrorHorizontally, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Icon") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + Icon(position_in2DViewportSpace, icon, color, size_relToViewportHeight, text, zRotationDegCC, strokeWidth_relToViewportHeight, displayPointerIfOffscreen, mirrorHorizontally, durationInSec); + } + public static void Icon(Camera targetCamera, Vector3 position_in3DWorldspace, DrawBasics.IconType icon, Color color = default(Color), float size_relToViewportHeight = 0.1f, string text = null, float zRotationDegCC = 0.0f, float strokeWidth_relToViewportHeight = 0.0f, bool displayPointerIfOffscreen = false, bool mirrorHorizontally = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceIcon_3Dpos_cam.Add(new ScreenspaceIcon_3Dpos_cam(targetCamera, position_in3DWorldspace, icon, color, size_relToViewportHeight, text, zRotationDegCC, strokeWidth_relToViewportHeight, displayPointerIfOffscreen, mirrorHorizontally, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(targetCamera, position_in3DWorldspace, false); + Icon(targetCamera, position_in2DViewportSpace, icon, color, size_relToViewportHeight, text, zRotationDegCC, strokeWidth_relToViewportHeight, displayPointerIfOffscreen, mirrorHorizontally, durationInSec); + } + + public static void Icon(Vector2 position_in2DViewportSpace, DrawBasics.IconType icon, Color color = default(Color), float size_relToViewportHeight = 0.1f, string text = null, float zRotationDegCC = 0.0f, float strokeWidth_relToViewportHeight = 0.0f, bool displayPointerIfOffscreen = false, bool mirrorHorizontally = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Icon") == false) { return; } + Icon(automaticallyFoundCamera, position_in2DViewportSpace, icon, color, size_relToViewportHeight, text, zRotationDegCC, strokeWidth_relToViewportHeight, displayPointerIfOffscreen, mirrorHorizontally, durationInSec); + } + public static void Icon(Camera targetCamera, Vector2 position_in2DViewportSpace, DrawBasics.IconType icon, Color color = default(Color), float size_relToViewportHeight = 0.1f, string text = null, float zRotationDegCC = 0.0f, float strokeWidth_relToViewportHeight = 0.0f, bool displayPointerIfOffscreen = false, bool mirrorHorizontally = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size_relToViewportHeight, "size_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zRotationDegCC, "zRotationDegCC")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position_in2DViewportSpace, "position")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceIcon_2Dpos_cam.Add(new ScreenspaceIcon_2Dpos_cam(targetCamera, position_in2DViewportSpace, icon, color, size_relToViewportHeight, text, zRotationDegCC, strokeWidth_relToViewportHeight, displayPointerIfOffscreen, mirrorHorizontally, durationInSec)); + return; + } + + float distanceThresholdOutsideScreen_relToViewportHeight = 0.4f * size_relToViewportHeight; + if (InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportYWithPadding(position_in2DViewportSpace, distanceThresholdOutsideScreen_relToViewportHeight)) + { + if (displayPointerIfOffscreen) + { + Point(targetCamera, position_in2DViewportSpace, "[Icon(ScreenSpace) " + DrawText.MarkupIcon(icon) + " offscreen at " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(position_in2DViewportSpace) + "]
" + text, color, 0.1f, 0.0f, 0.0f, true, true, false, true, durationInSec); + } + return; + } + float distanceThresholdOutsideScreen_relToViewportWidth = distanceThresholdOutsideScreen_relToViewportHeight / targetCamera.aspect; + if (InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportXWithPadding(position_in2DViewportSpace, distanceThresholdOutsideScreen_relToViewportWidth)) + { + if (displayPointerIfOffscreen) + { + Point(targetCamera, position_in2DViewportSpace, "[Icon(ScreenSpace) " + DrawText.MarkupIcon(icon) + " offscreen at " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(position_in2DViewportSpace) + "]
" + text, color, 0.1f, 0.0f, 0.0f, true, true, false, true, durationInSec); + } + return; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(size_relToViewportHeight)) + { + UtilitiesDXXL_Screenspace.PointFallback(targetCamera, position_in2DViewportSpace, "[Icon(ScreenSpace) " + DrawText.MarkupIcon(icon) + " with size of 0]
" + text, color, 0.0f, durationInSec); + return; + } + + Vector3 position_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, position_in2DViewportSpace, false); + float size_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, position_in2DViewportSpace, true, size_relToViewportHeight); + Quaternion rotation_worldSpace = UtilitiesDXXL_Math.ApproximatelyZero(zRotationDegCC) ? targetCamera.transform.rotation : (Quaternion.AngleAxis(zRotationDegCC, targetCamera.transform.forward) * targetCamera.transform.rotation); + float minTextSize_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, position_in2DViewportSpace, true, minTextSize_relToViewportHeight); + + int strokeWidth_asPPMofSize = 0; + if ((UtilitiesDXXL_Math.ApproximatelyZero(strokeWidth_relToViewportHeight) == false) && (UtilitiesDXXL_Math.ApproximatelyZero(size_relToViewportHeight) == false)) + { + float strokeWidth_relToIconSize = strokeWidth_relToViewportHeight / size_relToViewportHeight; + strokeWidth_asPPMofSize = (int)(1000000.0f * strokeWidth_relToIconSize); + } + + bool autoFlipMirroredText_toFitObserverCam = false; + UtilitiesDXXL_DrawBasics.Icon(position_worldSpace, icon, color, size_worldSpace, text, rotation_worldSpace, strokeWidth_asPPMofSize, mirrorHorizontally, durationInSec, false, 0.15f, minTextSize_worldSpace, autoFlipMirroredText_toFitObserverCam); + } + + public static void Dot(Vector3 position_in3DWorldspace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), string text = null, float density = 1.0f, bool displayPointerIfOffscreen = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceDot_3Dpos.Add(new ScreenspaceDot_3Dpos(position_in3DWorldspace, radius_relToViewportHeight, color, text, density, displayPointerIfOffscreen, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Dot") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + Dot(position_in2DViewportSpace, radius_relToViewportHeight, color, text, density, displayPointerIfOffscreen, durationInSec); + } + + public static void Dot(Camera targetCamera, Vector3 position_in3DWorldspace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), string text = null, float density = 1.0f, bool displayPointerIfOffscreen = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceDot_3Dpos_cam.Add(new ScreenspaceDot_3Dpos_cam(targetCamera, position_in3DWorldspace, radius_relToViewportHeight, color, text, density, displayPointerIfOffscreen, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(targetCamera, position_in3DWorldspace, false); + Dot(targetCamera, position_in2DViewportSpace, radius_relToViewportHeight, color, text, density, displayPointerIfOffscreen, durationInSec); + } + + public static void Dot(Vector2 position_in2DViewportSpace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), string text = null, float density = 1.0f, bool displayPointerIfOffscreen = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.Dot") == false) { return; } + Dot(automaticallyFoundCamera, position_in2DViewportSpace, radius_relToViewportHeight, color, text, density, displayPointerIfOffscreen, durationInSec); + } + + public static void Dot(Camera targetCamera, Vector2 position_in2DViewportSpace, float radius_relToViewportHeight = 0.05f, Color color = default(Color), string text = null, float density = 1.0f, bool displayPointerIfOffscreen = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_relToViewportHeight, "radius_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(density, "density")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position_in2DViewportSpace, "position")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceDot_2Dpos_cam.Add(new ScreenspaceDot_2Dpos_cam(targetCamera, position_in2DViewportSpace, radius_relToViewportHeight, color, text, density, displayPointerIfOffscreen, durationInSec)); + return; + } + + float distanceThresholdOutsideScreen_relToViewportHeight = 0.975f * radius_relToViewportHeight; + if (InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportYWithPadding(position_in2DViewportSpace, distanceThresholdOutsideScreen_relToViewportHeight)) + { + if (displayPointerIfOffscreen) + { + Point(targetCamera, position_in2DViewportSpace, "[Dot(ScreenSpace) offscreen at " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(position_in2DViewportSpace) + "]
" + text, color, 0.1f, 0.0f, 0.0f, true, true, false, true, durationInSec); + } + return; + } + float distanceThresholdOutsideScreen_relToViewportWidth = distanceThresholdOutsideScreen_relToViewportHeight / targetCamera.aspect; + if (InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportXWithPadding(position_in2DViewportSpace, distanceThresholdOutsideScreen_relToViewportWidth)) + { + if (displayPointerIfOffscreen) + { + Point(targetCamera, position_in2DViewportSpace, "[Dot(ScreenSpace) offscreen at " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(position_in2DViewportSpace) + "]
" + text, color, 0.1f, 0.0f, 0.0f, true, true, false, true, durationInSec); + } + return; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(radius_relToViewportHeight)) + { + UtilitiesDXXL_Screenspace.PointFallback(targetCamera, position_in2DViewportSpace, "[Dot(ScreenSpace) with size of 0]
" + text, color, 0.0f, durationInSec); + return; + } + + Vector3 position_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, position_in2DViewportSpace, false); + float radius_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, position_in2DViewportSpace, true, radius_relToViewportHeight); + Quaternion rotation_worldSpace = targetCamera.transform.rotation; + float minTextSize_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, position_in2DViewportSpace, true, minTextSize_relToViewportHeight); + + bool autoFlipMirroredText_toFitObserverCam = false; + UtilitiesDXXL_DrawBasics.Dot(position_worldSpace, radius_worldSpace, rotation_worldSpace, color, text, density, durationInSec, false, 0.15f, minTextSize_worldSpace, autoFlipMirroredText_toFitObserverCam); + } + + public static void MovingArrowsRay(Vector2 start, Vector2 direction, Color color = default(Color), float lineWidth_relToViewportHeight = 0.016f, float distanceBetweenArrows_relToViewportHeight = 0.11f, float lengthOfArrows_relToViewportHeight = 0.05f, string text = null, float animationSpeed = 0.5f, bool backwardAnimationFlipsArrowDirection = true, bool interpretDirectionAsUnwarped = false, float endPlatesSize_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.MovingArrowsRay") == false) { return; } + MovingArrowsRay(automaticallyFoundCamera, start, direction, color, lineWidth_relToViewportHeight, distanceBetweenArrows_relToViewportHeight, lengthOfArrows_relToViewportHeight, text, animationSpeed, backwardAnimationFlipsArrowDirection, interpretDirectionAsUnwarped, endPlatesSize_relToViewportHeight, durationInSec); + } + public static void MovingArrowsRay(Camera targetCamera, Vector2 start, Vector2 direction, Color color = default(Color), float lineWidth_relToViewportHeight = 0.016f, float distanceBetweenArrows_relToViewportHeight = 0.11f, float lengthOfArrows_relToViewportHeight = 0.05f, string text = null, float animationSpeed = 0.5f, bool backwardAnimationFlipsArrowDirection = true, bool interpretDirectionAsUnwarped = false, float endPlatesSize_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceMovingArrowsRay.Add(new ScreenspaceMovingArrowsRay(targetCamera, start, direction, color, lineWidth_relToViewportHeight, distanceBetweenArrows_relToViewportHeight, lengthOfArrows_relToViewportHeight, text, animationSpeed, backwardAnimationFlipsArrowDirection, interpretDirectionAsUnwarped, endPlatesSize_relToViewportHeight, durationInSec)); + return; + } + + MovingArrowsRay_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, direction, color, lineWidth_relToViewportHeight, distanceBetweenArrows_relToViewportHeight, lengthOfArrows_relToViewportHeight, text, animationSpeed, null, backwardAnimationFlipsArrowDirection, interpretDirectionAsUnwarped, endPlatesSize_relToViewportHeight, durationInSec); + } + + public static void MovingArrowsLine(Vector2 start, Vector2 end, Color color = default(Color), float lineWidth_relToViewportHeight = 0.016f, float distanceBetweenArrows_relToViewportHeight = 0.11f, float lengthOfArrows_relToViewportHeight = 0.05f, string text = null, float animationSpeed = 0.5f, bool backwardAnimationFlipsArrowDirection = true, float endPlatesSize_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.MovingArrowsLine") == false) { return; } + MovingArrowsLine(automaticallyFoundCamera, start, end, color, lineWidth_relToViewportHeight, distanceBetweenArrows_relToViewportHeight, lengthOfArrows_relToViewportHeight, text, animationSpeed, backwardAnimationFlipsArrowDirection, endPlatesSize_relToViewportHeight, durationInSec); + } + + public static void MovingArrowsLine(Camera targetCamera, Vector2 start, Vector2 end, Color color = default(Color), float lineWidth_relToViewportHeight = 0.016f, float distanceBetweenArrows_relToViewportHeight = 0.11f, float lengthOfArrows_relToViewportHeight = 0.05f, string text = null, float animationSpeed = 0.5f, bool backwardAnimationFlipsArrowDirection = true, float endPlatesSize_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceMovingArrowsLine.Add(new ScreenspaceMovingArrowsLine(targetCamera, start, end, color, lineWidth_relToViewportHeight, distanceBetweenArrows_relToViewportHeight, lengthOfArrows_relToViewportHeight, text, animationSpeed, backwardAnimationFlipsArrowDirection, endPlatesSize_relToViewportHeight, durationInSec)); + return; + } + + MovingArrowsLine_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, end, color, lineWidth_relToViewportHeight, distanceBetweenArrows_relToViewportHeight, lengthOfArrows_relToViewportHeight, text, animationSpeed, null, backwardAnimationFlipsArrowDirection, endPlatesSize_relToViewportHeight, durationInSec); + } + + public static void RayWithAlternatingColors(Vector2 start, Vector2 direction, Color color1 = default(Color), Color color2 = default(Color), float lineWidth_relToViewportHeight = 0.0f, float lengthOfStripes_relToViewportHeight = 0.03f, string text = null, bool interpretDirectionAsUnwarped = false, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.RayWithAlternatingColors") == false) { return; } + RayWithAlternatingColors(automaticallyFoundCamera, start, direction, color1, color2, lineWidth_relToViewportHeight, lengthOfStripes_relToViewportHeight, text, interpretDirectionAsUnwarped, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, durationInSec); + } + public static void RayWithAlternatingColors(Camera targetCamera, Vector2 start, Vector2 direction, Color color1 = default(Color), Color color2 = default(Color), float lineWidth_relToViewportHeight = 0.0f, float lengthOfStripes_relToViewportHeight = 0.03f, string text = null, bool interpretDirectionAsUnwarped = false, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceRayWithAlternatingColors.Add(new ScreenspaceRayWithAlternatingColors(targetCamera, start, direction, color1, color2, lineWidth_relToViewportHeight, lengthOfStripes_relToViewportHeight, text, interpretDirectionAsUnwarped, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, durationInSec)); + return; + } + + RayWithAlternatingColors_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, direction, color1, color2, lineWidth_relToViewportHeight, lengthOfStripes_relToViewportHeight, text, interpretDirectionAsUnwarped, animationSpeed, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, durationInSec); + } + + public static void LineWithAlternatingColors(Vector2 start, Vector2 end, Color color1 = default(Color), Color color2 = default(Color), float lineWidth_relToViewportHeight = 0.0f, float lengthOfStripes_relToViewportHeight = 0.03f, string text = null, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineWithAlternatingColors") == false) { return; } + LineWithAlternatingColors(automaticallyFoundCamera, start, end, color1, color2, lineWidth_relToViewportHeight, lengthOfStripes_relToViewportHeight, text, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, durationInSec); + } + public static void LineWithAlternatingColors(Camera targetCamera, Vector2 start, Vector2 end, Color color1 = default(Color), Color color2 = default(Color), float lineWidth_relToViewportHeight = 0.0f, float lengthOfStripes_relToViewportHeight = 0.03f, string text = null, float animationSpeed = 0.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineWithAlternatingColors.Add(new ScreenspaceLineWithAlternatingColors(targetCamera, start, end, color1, color2, lineWidth_relToViewportHeight, lengthOfStripes_relToViewportHeight, text, animationSpeed, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, durationInSec)); + return; + } + LineWithAlternatingColors_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, end, color1, color2, lineWidth_relToViewportHeight, lengthOfStripes_relToViewportHeight, text, animationSpeed, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, durationInSec); + } + + public static void BlinkingRay(Vector2 start, Vector2 direction, Color primaryColor = default(Color), float blinkDurationInSec = 0.5f, float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, Color blinkColor = default(Color), float stylePatternScaleFactor = 1.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.BlinkingRay") == false) { return; } + BlinkingRay(automaticallyFoundCamera, start, direction, primaryColor, blinkDurationInSec, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, blinkColor, stylePatternScaleFactor, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + public static void BlinkingRay(Camera targetCamera, Vector2 start, Vector2 direction, Color primaryColor = default(Color), float blinkDurationInSec = 0.5f, float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, Color blinkColor = default(Color), float stylePatternScaleFactor = 1.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceBlinkingRay.Add(new ScreenspaceBlinkingRay(targetCamera, start, direction, primaryColor, blinkDurationInSec, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, blinkColor, stylePatternScaleFactor, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + Vector2 direction_inNonSquareViewportSpace = interpretDirectionAsUnwarped ? DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(direction, targetCamera) : direction; + Vector2 end = start + direction_inNonSquareViewportSpace; + BlinkingLine(targetCamera, start, end, primaryColor, blinkDurationInSec, width_relToViewportHeight, text, style, blinkColor, stylePatternScaleFactor, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void BlinkingLine(Vector2 start, Vector2 end, Color primaryColor = default(Color), float blinkDurationInSec = 0.5f, float width_relToViewportHeight = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, Color blinkColor = default(Color), float stylePatternScaleFactor = 1.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.BlinkingLine") == false) { return; } + BlinkingLine(automaticallyFoundCamera, start, end, primaryColor, blinkDurationInSec, width_relToViewportHeight, text, style, blinkColor, stylePatternScaleFactor, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + public static void BlinkingLine(Camera targetCamera, Vector2 start, Vector2 end, Color primaryColor = default(Color), float blinkDurationInSec = 0.5f, float width_relToViewportHeight = 0.0f, string text = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, Color blinkColor = default(Color), float stylePatternScaleFactor = 1.0f, float endPlatesSize_relToViewportHeight = 0.0f, float alphaFadeOutLength_0to1 = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(blinkDurationInSec, "blinkDurationInSec")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceBlinkingLine.Add(new ScreenspaceBlinkingLine(targetCamera, start, end, primaryColor, blinkDurationInSec, width_relToViewportHeight, text, style, blinkColor, stylePatternScaleFactor, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + blinkDurationInSec = Mathf.Max(blinkDurationInSec, UtilitiesDXXL_DrawBasics.min_blinkDurationInSec); + float passedBlinkIntervallsSinceStartup = UtilitiesDXXL_LineStyles.GetTime() / blinkDurationInSec; + primaryColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(primaryColor); + if (UtilitiesDXXL_Math.CheckIf_givenNumberIs_evenNotOdd(Mathf.FloorToInt(passedBlinkIntervallsSinceStartup))) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, end, primaryColor, width_relToViewportHeight, text, style, stylePatternScaleFactor, 0.0f, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + else + { + if (UtilitiesDXXL_Colors.IsDefaultColor(blinkColor)) + { + Color alternatingBlinkColor = UtilitiesDXXL_Colors.Invert_andAlphaTo1(primaryColor); + alternatingBlinkColor = UtilitiesDXXL_Colors.OverwriteColorNearGreyWithBlack(alternatingBlinkColor); + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, end, alternatingBlinkColor, width_relToViewportHeight, text, style, stylePatternScaleFactor, 0.0f, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + else + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, end, blinkColor, width_relToViewportHeight, text, style, stylePatternScaleFactor, 0.0f, null, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + } + } + + public static void RayUnderTension(Vector2 start, Vector2 direction, float relaxedLength_relToViewportHeight = 0.4f, Color relaxedColor = default(Color), DrawBasics.LineStyle style = DrawBasics.LineStyle.sine, float stretchFactor_forStretchedTensionColor = 2.0f, Color color_forStretchedTension = default(Color), float stretchFactor_forSqueezedTensionColor = 0.0f, Color color_forSqueezedTension = default(Color), float width_relToViewportHeight = 0.0f, string text = null, float alphaOfReferenceLengthDisplay = 0.1f, bool interpretDirectionAsUnwarped = false, float stylePatternScaleFactor = 1.0f, float endPlatesSize_relToViewportHeight = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.RayUnderTension") == false) { return; } + RayUnderTension(automaticallyFoundCamera, start, direction, relaxedLength_relToViewportHeight, relaxedColor, style, stretchFactor_forStretchedTensionColor, color_forStretchedTension, stretchFactor_forSqueezedTensionColor, color_forSqueezedTension, width_relToViewportHeight, text, alphaOfReferenceLengthDisplay, interpretDirectionAsUnwarped, stylePatternScaleFactor, endPlatesSize_relToViewportHeight, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void RayUnderTension(Camera targetCamera, Vector2 start, Vector2 direction, float relaxedLength_relToViewportHeight = 0.4f, Color relaxedColor = default(Color), DrawBasics.LineStyle style = DrawBasics.LineStyle.sine, float stretchFactor_forStretchedTensionColor = 2.0f, Color color_forStretchedTension = default(Color), float stretchFactor_forSqueezedTensionColor = 0.0f, Color color_forSqueezedTension = default(Color), float width_relToViewportHeight = 0.0f, string text = null, float alphaOfReferenceLengthDisplay = 0.1f, bool interpretDirectionAsUnwarped = false, float stylePatternScaleFactor = 1.0f, float endPlatesSize_relToViewportHeight = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceRayUnderTension.Add(new ScreenspaceRayUnderTension(targetCamera, start, direction, relaxedLength_relToViewportHeight, relaxedColor, style, stretchFactor_forStretchedTensionColor, color_forStretchedTension, stretchFactor_forSqueezedTensionColor, color_forSqueezedTension, width_relToViewportHeight, text, alphaOfReferenceLengthDisplay, interpretDirectionAsUnwarped, stylePatternScaleFactor, endPlatesSize_relToViewportHeight, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + Vector2 direction_inNonSquareViewportSpace = interpretDirectionAsUnwarped ? DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(direction, targetCamera) : direction; + LineUnderTension(targetCamera, start, start + direction_inNonSquareViewportSpace, relaxedLength_relToViewportHeight, relaxedColor, style, stretchFactor_forStretchedTensionColor, color_forStretchedTension, stretchFactor_forSqueezedTensionColor, color_forSqueezedTension, width_relToViewportHeight, text, alphaOfReferenceLengthDisplay, stylePatternScaleFactor, endPlatesSize_relToViewportHeight, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineUnderTension(Vector2 start, Vector2 end, float relaxedLength_relToViewportHeight = 0.4f, Color relaxedColor = default(Color), DrawBasics.LineStyle style = DrawBasics.LineStyle.sine, float stretchFactor_forStretchedTensionColor = 2.0f, Color color_forStretchedTension = default(Color), float stretchFactor_forSqueezedTensionColor = 0.0f, Color color_forSqueezedTension = default(Color), float width_relToViewportHeight = 0.0f, string text = null, float alphaOfReferenceLengthDisplay = 0.1f, float stylePatternScaleFactor = 1.0f, float endPlatesSize_relToViewportHeight = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawScreenspace.LineUnderTension") == false) { return; } + LineUnderTension(automaticallyFoundCamera, start, end, relaxedLength_relToViewportHeight, relaxedColor, style, stretchFactor_forStretchedTensionColor, color_forStretchedTension, stretchFactor_forSqueezedTensionColor, color_forSqueezedTension, width_relToViewportHeight, text, alphaOfReferenceLengthDisplay, stylePatternScaleFactor, endPlatesSize_relToViewportHeight, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static void LineUnderTension(Camera targetCamera, Vector2 start, Vector2 end, float relaxedLength_relToViewportHeight = 0.4f, Color relaxedColor = default(Color), DrawBasics.LineStyle style = DrawBasics.LineStyle.sine, float stretchFactor_forStretchedTensionColor = 2.0f, Color color_forStretchedTension = default(Color), float stretchFactor_forSqueezedTensionColor = 0.0f, Color color_forSqueezedTension = default(Color), float width_relToViewportHeight = 0.0f, string text = null, float alphaOfReferenceLengthDisplay = 0.1f, float stylePatternScaleFactor = 1.0f, float endPlatesSize_relToViewportHeight = 0.0f, float enlargeSmallTextToThisMinRelTextSize = minTextSize_relToViewportHeight, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceLineUnderTension.Add(new ScreenspaceLineUnderTension(targetCamera, start, end, relaxedLength_relToViewportHeight, relaxedColor, style, stretchFactor_forStretchedTensionColor, color_forStretchedTension, stretchFactor_forSqueezedTensionColor, color_forSqueezedTension, width_relToViewportHeight, text, alphaOfReferenceLengthDisplay, stylePatternScaleFactor, endPlatesSize_relToViewportHeight, enlargeSmallTextToThisMinRelTextSize, durationInSec)); + return; + } + + InternalDXXL_LineParamsFromCamViewportSpace lineParams = UtilitiesDXXL_Screenspace.GetLineParamsFromCamViewportSpace(targetCamera, start, end, width_relToViewportHeight, style, stylePatternScaleFactor, enlargeSmallTextToThisMinRelTextSize, 0.0f, endPlatesSize_relToViewportHeight); + if (lineParams == null) { return; } + + Vector2 middleV2 = 0.5f * (start + end); + float relaxedLength_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, middleV2, true, relaxedLength_relToViewportHeight); + bool parametersAreInvalid = UtilitiesDXXL_DrawBasics.GetSpecsOfLineUnderTension(out float tensionFactor, out Color usedColor, out float lineLength_worldSpace, lineParams.startAnchor_worldSpace, lineParams.endAnchor_worldSpace, relaxedLength_worldSpace, relaxedColor, color_forStretchedTension, color_forSqueezedTension, stretchFactor_forStretchedTensionColor, stretchFactor_forSqueezedTensionColor); + if (parametersAreInvalid) { return; } + + UtilitiesDXXL_DrawBasics.TryDrawReferenceLengthDisplay_ofLineUnderTension(lineParams.startAnchor_worldSpace, lineParams.endAnchor_worldSpace, alphaOfReferenceLengthDisplay, relaxedLength_worldSpace, relaxedColor, lineLength_worldSpace, lineParams.camPlane, durationInSec, false); + + UtilitiesDXXL_DrawBasics.Set_endPlates_sizeInterpretation_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + UtilitiesDXXL_DrawBasics.Line(lineParams.startAnchor_worldSpace, lineParams.endAnchor_worldSpace, usedColor, lineParams.width_worldSpace, text, lineParams.lineStyleForcedTo2D, lineParams.patternScaleFactor_worldSpace, 0.0f, null, lineParams.camPlane, true, 0.0f, lineParams.enlargeSmallTextToThisMinTextSize_worldSpace, durationInSec, false, false, false, targetCamera, false, lineParams.endPlatesSize_inAbsoluteWorldSpaceUnits, tensionFactor); + UtilitiesDXXL_DrawBasics.Reverse_endPlates_sizeInterpretation(); + } + + public static Vector2 DirectionInUnitsOfWarpedSpace_to_sameLookingDirectionInUnitsOfUnwarpedSpace(Vector2 directionInsideWarpedNonUniformViewportSpace_toConvert, Camera camera) + { + //when drawing in screenspace there is the problem that the interpretation of direction vectors is ambiguous. This is because the mostly non-squared screens result in a screenSpace/viewportSpace that has differnt length units for the x axis and y axis. For example the Vector (1,1) in a normal unwarped coordinate system goes to the upper right side with an angle of 45 degrees. In viewportSpace with an aspect ratio of 16 (width) : 9 (height), the same vector is horizontally stretched (warped) resulting in a flatter direction (of around 30 degrees) + //If you have a direction vector in units of the non-uniform viewportSpace and want the same looking vector (meaning appearing with the same angle and same length to the human viewer), but expressed in units of an unwarped uniform coordinate space, then you can use this function. + //Convention of the conversion executed by this function: The height of the camera viewport counts as 1 unit in the unwarped uniform coordinate space. + //see also the "DirectionInUnwarpedSpace_toSameLookingDirectionInWarpedSpace" function + + if (camera == null) + { + Debug.LogError("Cannot convert to unwarped space, because camera is 'null'."); + return directionInsideWarpedNonUniformViewportSpace_toConvert; + } + + return new Vector2(directionInsideWarpedNonUniformViewportSpace_toConvert.x * camera.aspect, directionInsideWarpedNonUniformViewportSpace_toConvert.y); + } + + public static Vector2 DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(Vector2 directionInsideUniform1by1SquareSpace_toConvert, Camera camera) + { + if (camera == null) + { + Debug.LogError("Cannot convert to warped space, because camera is 'null'."); + return directionInsideUniform1by1SquareSpace_toConvert; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(camera.aspect)) + { + Debug.LogError("Cannot convert to warped space, because camera.aspect is 0."); + return directionInsideUniform1by1SquareSpace_toConvert; + } + + return new Vector2(directionInsideUniform1by1SquareSpace_toConvert.x / camera.aspect, directionInsideUniform1by1SquareSpace_toConvert.y); + } + + public static Camera VisualizeAutomaticCameraForDrawing(bool visualizeFrustum = true, bool logPositionToConsole = true, Color color = default(Color), float durationInSec = 0.0f) + { + //If you want find out to which camera the Screenspace functions without camera parameter are drawing you can use this function. It can be handy if you have multiple cameras in the Scene and don't know which one is used for drawing to screenspace. See also "defaultCameraForDrawing" and "defaultScreenspaceWindowForDrawing". Note that it can also be the Scene View camera, in which case you cannot find the camera in your hierarchy. + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, null, false); + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ScreenspaceVisualizeAutomaticCameraForDrawing.Add(new ScreenspaceVisualizeAutomaticCameraForDrawing(visualizeFrustum, logPositionToConsole, color, durationInSec)); + return automaticallyFoundCamera; + } + + if (automaticallyFoundCamera != null) + { + if (logPositionToConsole) + { + Debug.Log("[Draw XXL] Position of the 'Automatic Camera for Drawing': " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(automaticallyFoundCamera.transform.position)); + } + + if (visualizeFrustum) + { + string displayedText = "This is the camera to which Draw XXL draws when using the
DrawScreenspace
class."; + bool hiddenByNearerObjects = false; + DrawEngineBasics.CameraFrustum(automaticallyFoundCamera, color, 0.18f, 0.0f, 60, displayedText, true, default(Vector3), durationInSec, hiddenByNearerObjects); + } + } + return automaticallyFoundCamera; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/DrawScreenspace.cs.meta b/Runtime/DrawDebugLibrary/DrawScreenspace.cs.meta new file mode 100644 index 0000000..85dcc56 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawScreenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3de7fccd43155f5458797acdf9bbf363 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawShapes.cs b/Runtime/DrawDebugLibrary/DrawShapes.cs new file mode 100644 index 0000000..e3312d8 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawShapes.cs @@ -0,0 +1,1184 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class DrawShapes + { + public enum Shape2DType { square, triangle, pentagon, hexagon, septagon, octagon, decagon, circle, circle4struts, star3, star4, star5, star6, star8, star10, star16, star32, star64, ellipse05, ellipse025, ellipse0125 }; + public enum PlaneNormalFromTransform { right, up, forward, left, down, back }; + + public enum AutomaticOrientationOfFlatShapes + { + screen, + screen_butVerticalInWorldSpace, + xyPlane, + xzPlane, + zyPlane + } + public static AutomaticOrientationOfFlatShapes automaticOrientationOfFlatShapes = AutomaticOrientationOfFlatShapes.screen; + public static float forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = 0.0f; + public static float forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + + private static float shapeFillDensity = 1.0f; + public static float ShapeFillDensity + { + get { return shapeFillDensity; } + set + { + shapeFillDensity = value; + shapeFillDensity = Mathf.Abs(shapeFillDensity); + shapeFillDensity = Mathf.Max(shapeFillDensity, 0.01f); + } + } + + private static int linesPerSphereCircle = 64; + public static int LinesPerSphereCircle + { + get { return linesPerSphereCircle; } + set + { + if ((value == 64) || (value == 32) || (value == 16) || (value == 8)) + { + linesPerSphereCircle = value; + } + else + { + Debug.LogError("It is not supported to set 'LinesPerSphereAndCapsuleCircle' to anything other than 64, 32, 16 or 8."); + } + } + } + + /// 使用四元数旋转,绘制指定边数的正多边形 + public static int RegularPolygon(int corners, Vector3 centerPosition, float hullRadius = 0.5f, Color color = default(Color), Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return RegularPolygon(corners, centerPosition, hullRadius, color, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制指定边数的正多边形 + public static int RegularPolygon(int corners, Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insidePolygonPlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(hullRadius, "hullRadius")) { return 0; } + return UtilitiesDXXL_Shapes.DrawFlatPolygon(0.0f, corners, centerPosition, Mathf.Abs(hullRadius), normal, up_insidePolygonPlane, color, lineWidth, text, durationInSec, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, hiddenByNearerObjects, textBlockAboveLine, false); + } + + /// 使用四元数旋转,绘制三角形 + public static int Triangle(Vector3 centerPosition, float hullRadius = 0.5f, Color color = default(Color), Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return Triangle(centerPosition, hullRadius, color, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制三角形 + public static int Triangle(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insideTrianglePlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Triangle(centerPosition, hullRadius, color, normal, up_insideTrianglePlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false); + } + + /// 使用四元数旋转,绘制正方形 + public static int Square(Vector3 centerPosition, float sideLength = 1.0f, Color color = default(Color), Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return Square(centerPosition, sideLength, color, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制正方形 + public static int Square(Vector3 centerPosition, float sideLength, Color color, Vector3 normal, Vector3 up_insideSquarePlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Square(centerPosition, sideLength, color, normal, up_insideSquarePlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false); + } + + /// 使用四元数旋转,绘制五边形 + public static int Pentagon(Vector3 centerPosition, float hullRadius = 0.5f, Color color = default(Color), Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return Pentagon(centerPosition, hullRadius, color, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制五边形 + public static int Pentagon(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insidePentagonPlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Pentagon(centerPosition, hullRadius, color, normal, up_insidePentagonPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false); + } + + /// 使用四元数旋转,绘制六边形 + public static int Hexagon(Vector3 centerPosition, float hullRadius = 0.5f, Color color = default(Color), Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return Hexagon(centerPosition, hullRadius, color, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制六边形 + public static int Hexagon(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insideHexagonPlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Hexagon(centerPosition, hullRadius, color, normal, up_insideHexagonPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false); + } + + /// 使用四元数旋转,绘制七边形 + public static int Septagon(Vector3 centerPosition, float hullRadius = 0.5f, Color color = default(Color), Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return Septagon(centerPosition, hullRadius, color, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制七边形 + public static int Septagon(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insideSeptagonPlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Septagon(centerPosition, hullRadius, color, normal, up_insideSeptagonPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false); + } + + /// 使用四元数旋转,绘制八边形 + public static int Octagon(Vector3 centerPosition, float hullRadius = 0.5f, Color color = default(Color), Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return Octagon(centerPosition, hullRadius, color, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制八边形 + public static int Octagon(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insideOctagonPlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Octagon(centerPosition, hullRadius, color, normal, up_insideOctagonPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false); + } + + /// 使用四元数旋转,绘制十边形 + public static int Decagon(Vector3 centerPosition, float hullRadius = 0.5f, Color color = default(Color), Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return Decagon(centerPosition, hullRadius, color, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制十边形 + public static int Decagon(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insideDecagonPlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Decagon(centerPosition, hullRadius, color, normal, up_insideDecagonPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false); + } + + /// 使用四元数旋转,绘制圆形 + public static int Circle(Vector3 centerPosition, float radius = 0.5f, Color color = default(Color), Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return Circle(centerPosition, radius, color, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制圆形 + public static int Circle(Vector3 centerPosition, float radius, Color color, Vector3 normal, Vector3 up_insideCirclePlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Circle(centerPosition, radius, color, normal, up_insideCirclePlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false); + } + + /// 使用四元数旋转,绘制椭圆 + public static int Ellipse(Vector3 centerPosition, float radiusSideward = 0.25f, float radiusUpward = 0.5f, Color color = default(Color), Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return Ellipse(centerPosition, radiusSideward, radiusUpward, color, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制椭圆 + public static int Ellipse(Vector3 centerPosition, float radiusSideward, float radiusUpward, Color color, Vector3 normal, Vector3 up_insideEllipsePlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Ellipse(centerPosition, radiusSideward, radiusUpward, color, normal, up_insideEllipsePlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false); + } + + /// 使用四元数旋转,绘制星形 + public static int Star(Vector3 centerPosition, float outerRadius = 0.5f, Color color = default(Color), int corners = 5, float innerRadiusFactor = 0.5f, Quaternion rotation = default(Quaternion), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return Star(centerPosition, outerRadius, color, corners, innerRadiusFactor, normal, up_insideFlatPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制星形 + public static int Star(Vector3 centerPosition, float outerRadius, Color color, int corners, float innerRadiusFactor, Vector3 normal, Vector3 up_insideStarPlane = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Star(centerPosition, outerRadius, color, corners, innerRadiusFactor, normal, up_insideStarPlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false); + } + + /// 指定两个圆心位置,绘制平面胶囊形状 + public static int FlatCapsule(Vector3 posOfCircle1, Vector3 posOfCircle2, float radius = 0.5f, Color color = default(Color), Vector3 normal = default(Vector3), float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.FlatCapsule(posOfCircle1, posOfCircle2, radius, color, normal, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 使用四元数旋转,绘制平面胶囊形状 + public static int FlatCapsule(Vector3 centerPosition, float width = 0.5f, float height = 1.0f, Color color = default(Color), Quaternion rotation = default(Quaternion), CapsuleDirection2D direction = CapsuleDirection2D.Vertical, float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return FlatCapsule(centerPosition, width, height, color, normal, up_insideFlatPlane, direction, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定法线方向,绘制平面胶囊形状 + public static int FlatCapsule(Vector3 centerPosition, float width, float height, Color color, Vector3 normal, Vector3 upAlongVert_insideCapsulePlane = default(Vector3), CapsuleDirection2D direction = CapsuleDirection2D.Vertical, float lineWidth = 0.0f, string text = null, DrawBasics.LineStyle outlineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.FlatCapsule(centerPosition, width, height, color, normal, upAlongVert_insideCapsulePlane, direction, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 通过 Transform 组件绘制平面 + public static void Plane(Transform planeTransform, PlaneNormalFromTransform normal = PlaneNormalFromTransform.up, Vector3 planeAreaExtentionPosition = default(Vector3), Color color = default(Color), float widthFactor = 10.0f, float lengthFactor = 10.0f, float linesWidth = 0.0f, string text = null, float subSegments_signFlipsInterpretation = 10.0f, bool pointer_as_textAttachStyle = false, float anchorVisualizationSize = 0.0f, bool drawPlumbLine_fromExtentionPosition = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(planeTransform, "planeTransform")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(widthFactor, "widthFactor")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lengthFactor, "lengthFactor")) { return; } + + Vector3 normal_asV3 = UtilitiesDXXL_Shapes.GetPlaneNormalFromTransformEnum(planeTransform, normal); + Vector3 forward_insidePlane = UtilitiesDXXL_Shapes.Get_forwardInsidePlane_FromPlameTransformEnum(planeTransform, normal); + float width = widthFactor * UtilitiesDXXL_Shapes.Get_width_FromPlameTransformEnum(planeTransform, normal); + float length = lengthFactor * UtilitiesDXXL_Shapes.Get_length_FromPlameTransformEnum(planeTransform, normal); + Plane(planeTransform.position, normal_asV3, planeAreaExtentionPosition, color, width, length, forward_insidePlane, linesWidth, text, subSegments_signFlipsInterpretation, pointer_as_textAttachStyle, anchorVisualizationSize, drawPlumbLine_fromExtentionPosition, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 通过 Unity Plane 结构体绘制平面 + public static void Plane(Plane plane, Vector3 drawPositionApproximately, Color color = default(Color), float width = 10.0f, float length = 10.0f, Vector3 forward_insidePlane = default(Vector3), float linesWidth = 0.0f, string text = null, float subSegments_signFlipsInterpretation = 10.0f, bool pointer_as_textAttachStyle = false, bool drawPlumbLine_fromApproximateDrawPosition = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(drawPositionApproximately, "drawPositionApproximately")) { return; } + + Vector3 closestPointOnPlane = plane.ClosestPointOnPlane(drawPositionApproximately); + float anchorVisualizationSize = 0.0f; //-> this overload doesn't need the "anchorVisualization", since there is no "planeAreaExtentionPosition" that could vary the plane extent. "drawPlumbLine_fromApproximateDrawPosition" already shows the mounting point. + Plane(closestPointOnPlane, plane.normal, drawPositionApproximately, color, width, length, forward_insidePlane, linesWidth, text, subSegments_signFlipsInterpretation, pointer_as_textAttachStyle, anchorVisualizationSize, drawPlumbLine_fromApproximateDrawPosition, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + static InternalDXXL_Plane plane_toDraw = new InternalDXXL_Plane(); + /// 通过挂载点和法线绘制平面 + public static void Plane(Vector3 planeMountingPoint, Vector3 normal = default(Vector3), Vector3 planeAreaExtentionPosition = default(Vector3), Color color = default(Color), float width = 10.0f, float length = 10.0f, Vector3 forward_insidePlane = default(Vector3), float linesWidth = 0.0f, string text = null, float subSegments_signFlipsInterpretation = 10.0f, bool pointer_as_textAttachStyle = false, float anchorVisualizationSize = 0.0f, bool drawPlumbLine_fromExtentionPosition = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(planeMountingPoint, "planeMountingPoint")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(planeAreaExtentionPosition, "planeAreaExtentionPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal, "normal")) { return; } + + if (UtilitiesDXXL_Math.IsDefaultVector(planeAreaExtentionPosition)) + { + UtilitiesDXXL_Shapes.Plane(planeMountingPoint, default(Vector3), normal, color, width, length, forward_insidePlane, linesWidth, text, subSegments_signFlipsInterpretation, pointer_as_textAttachStyle, anchorVisualizationSize, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + else + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(length, "length")) { return; } + + normal = UtilitiesDXXL_Math.OverwriteDefaultVectors(normal, Vector3.up); + plane_toDraw.Recreate(planeMountingPoint, normal); + Vector3 closestPointOnPlane = plane_toDraw.Get_perpProjectionOfPointOnPlane(planeAreaExtentionPosition); + + if (drawPlumbLine_fromExtentionPosition) + { + float sphereSize = 0.005f * Mathf.Min(width, length); + Color plumbColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.4f); + Sphere(closestPointOnPlane, sphereSize, plumbColor, normal, forward_insidePlane, 0.0f, null, 2, false, lineStyle, stylePatternScaleFactor, false, false, durationInSec, hiddenByNearerObjects); + Sphere(planeAreaExtentionPosition, sphereSize, plumbColor, normal, forward_insidePlane, 0.0f, null, 2, false, lineStyle, stylePatternScaleFactor, false, false, durationInSec, hiddenByNearerObjects); + Line_fadeableAnimSpeed.InternalDraw(planeAreaExtentionPosition, closestPointOnPlane, plumbColor, 0.0f, null, DrawBasics.LineStyle.dashedLong, 3.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + UtilitiesDXXL_Shapes.Plane(planeMountingPoint, closestPointOnPlane, normal, color, width, length, forward_insidePlane, linesWidth, text, subSegments_signFlipsInterpretation, pointer_as_textAttachStyle, anchorVisualizationSize, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + /// 以中心位置绘制菱形 + public static void RhombusAroundCenter(Vector3 centerPosition, Vector3 firstEdge, Vector3 secondEdge, Color color = default(Color), float linesWidth = 0.0f, string text = null, int subSegments = 10, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerPosition, "centerPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(firstEdge, "firstEdge")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(secondEdge, "secondEdge")) { return; } + + Vector3 startCornerPosition = centerPosition - 0.5f * firstEdge - 0.5f * secondEdge; + Rhombus(startCornerPosition, firstEdge, secondEdge, color, linesWidth, text, subSegments, lineStyle, stylePatternScaleFactor, durationInSec, hiddenByNearerObjects); + } + + /// 以起始角位置绘制菱形 + public static void Rhombus(Vector3 startCornerPosition, Vector3 firstEdge, Vector3 secondEdge, Color color = default(Color), float linesWidth = 0.0f, string text = null, int subSegments = 10, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Shapes.Rhombus(startCornerPosition, firstEdge, secondEdge, color, linesWidth, text, subSegments, lineStyle, stylePatternScaleFactor, durationInSec, hiddenByNearerObjects); + } + + /// 通过 Transform 组件绘制立方体线框 + public static int Cube(Transform transform, Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform, "transform")) { return 0; } + return Cube(transform.position, transform.lossyScale, color, transform.up, transform.forward, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 使用四元数旋转,绘制立方体线框 + public static int Cube(Vector3 position, Vector3 scale, Color color = default(Color), Quaternion rotation = default(Quaternion), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + return UtilitiesDXXL_Shapes.Cube(position, scale, color, color, rotation * Vector3.up, rotation * Vector3.forward, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false, null); + } + /// 指定朝上和朝前方向,绘制立方体线框 + public static int Cube(Vector3 position, Vector3 scale, Color color, Vector3 up, Vector3 forward, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Cube(position, scale, color, color, up, forward, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects, false, null); + } + + /// 通过 Transform 组件绘制填充立方体(含内部网格线) + public static void CubeFilled(Transform transform, Color color = default(Color), float alphaFactor_forInnerLines = 0.3f, float linesWidthOfEdges = 0.0f, int segmentsPerSide = 6, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(alphaFactor_forInnerLines, "alphaFactor_forInnerLines")) { return; } + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + Color colorOfInnerFrames = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaFactor_forInnerLines); + CubeFilled(transform, colorOfInnerFrames, 0.0f, segmentsPerSide, text, lineStyle, color, linesWidthOfEdges, stylePatternScaleFactor, true, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 使用四元数旋转,绘制填充立方体(含内部网格线) + public static void CubeFilled(Vector3 position, Vector3 scale, Color color = default(Color), float alphaFactor_forInnerLines = 0.3f, Quaternion rotation = default(Quaternion), float linesWidthOfEdges = 0.0f, int segmentsPerSide = 6, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(alphaFactor_forInnerLines, "alphaFactor_forInnerLines")) { return; } + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + Color colorOfInnerFrames = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaFactor_forInnerLines); + CubeFilled(position, scale, colorOfInnerFrames, rotation, 0.0f, segmentsPerSide, text, lineStyle, color, linesWidthOfEdges, stylePatternScaleFactor, true, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定朝上和朝前方向,绘制填充立方体(含内部网格线) + public static void CubeFilled(Vector3 position, Vector3 scale, Color color, float alphaFactor_forInnerLines, Vector3 up, Vector3 forward, float linesWidthOfEdges = 0.0f, int segmentsPerSide = 6, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(alphaFactor_forInnerLines, "alphaFactor_forInnerLines")) { return; } + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + Color colorOfInnerFrames = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaFactor_forInnerLines); + CubeFilled(position, scale, colorOfInnerFrames, up, forward, 0.0f, segmentsPerSide, text, lineStyle, color, linesWidthOfEdges, stylePatternScaleFactor, true, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 通过 Transform 绘制填充立方体(可自定义边框颜色和线宽) + public static void CubeFilled(Transform transform, Color color, float linesWidth, int segmentsPerSide, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, Color colorOfEdges = default(Color), float linesWidthOfEdges = 0.01f, float stylePatternScaleFactor = 1.0f, bool useEdgesColorAsTextColor_ifAvailable = true, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform, "transform")) { return; } + CubeFilled(transform.position, transform.lossyScale, color, transform.up, transform.forward, linesWidth, segmentsPerSide, text, lineStyle, colorOfEdges, linesWidthOfEdges, stylePatternScaleFactor, useEdgesColorAsTextColor_ifAvailable, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 使用四元数旋转,绘制填充立方体(可自定义边框颜色和线宽) + public static void CubeFilled(Vector3 position, Vector3 scale, Color color, Quaternion rotation, float linesWidth = 0.0f, int segmentsPerSide = 6, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, Color colorOfEdges = default(Color), float linesWidthOfEdges = 0.01f, float stylePatternScaleFactor = 1.0f, bool useEdgesColorAsTextColor_ifAvailable = true, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + CubeFilled(position, scale, color, rotation * Vector3.up, rotation * Vector3.forward, linesWidth, segmentsPerSide, text, lineStyle, colorOfEdges, linesWidthOfEdges, stylePatternScaleFactor, useEdgesColorAsTextColor_ifAvailable, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定朝上和朝前方向,绘制填充立方体(可自定义边框颜色和线宽) + public static void CubeFilled(Vector3 position, Vector3 scale, Color color, Vector3 up, Vector3 forward, float linesWidth = 0.0f, int segmentsPerSide = 6, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, Color colorOfEdges = default(Color), float linesWidthOfEdges = 0.01f, float stylePatternScaleFactor = 1.0f, bool useEdgesColorAsTextColor_ifAvailable = true, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Shapes.CubeFilled(position, scale, color, up, forward, linesWidth, segmentsPerSide, text, lineStyle, colorOfEdges, linesWidthOfEdges, stylePatternScaleFactor, useEdgesColorAsTextColor_ifAvailable, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 通过 Transform 组件绘制球体线框 + public static int Sphere(Transform transform, Color color = default(Color), float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalf = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool skipDrawingEquator = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform, "transform")) { return 0; } + return Sphere(transform.position, 0.5f * UtilitiesDXXL_Math.GetBiggestAbsComponent(transform.lossyScale), color, transform.rotation * Vector3.up, transform.rotation * Vector3.forward, linesWidth, text, struts, onlyUpperHalf, lineStyle, stylePatternScaleFactor, skipDrawingEquator, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 使用四元数旋转,绘制球体线框 + public static int Sphere(Vector3 position, float radius = 0.5f, Color color = default(Color), Quaternion rotation = default(Quaternion), float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalf = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool skipDrawingEquator = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + return Sphere(position, radius, color, rotation * Vector3.up, rotation * Vector3.forward, linesWidth, text, struts, onlyUpperHalf, lineStyle, stylePatternScaleFactor, skipDrawingEquator, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定朝上和朝前方向,绘制球体线框 + public static int Sphere(Vector3 position, float radius, Color color, Vector3 up, Vector3 forward, float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalf = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool skipDrawingEquator = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Sphere(position, radius, color, up, forward, linesWidth, text, struts, onlyUpperHalf, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects, skipDrawingEquator); + } + + /// 通过 Transform 组件绘制椭球体线框 + public static int Ellipsoid(Transform transform, Color color = default(Color), float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalf = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool skipDrawingEquator = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform, "transform")) { return 0; } + return Ellipsoid(transform.position, transform.lossyScale, color, transform.rotation * Vector3.up, transform.rotation * Vector3.forward, linesWidth, text, struts, onlyUpperHalf, lineStyle, stylePatternScaleFactor, skipDrawingEquator, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 使用四元数旋转,绘制椭球体线框 + public static int Ellipsoid(Vector3 position, Vector3 radius, Color color = default(Color), Quaternion rotation = default(Quaternion), float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalf = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool skipDrawingEquator = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + return Ellipsoid(position, radius, color, rotation * Vector3.up, rotation * Vector3.forward, linesWidth, text, struts, onlyUpperHalf, lineStyle, stylePatternScaleFactor, skipDrawingEquator, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定朝上和朝前方向,绘制椭球体线框 + public static int Ellipsoid(Vector3 position, Vector3 radius, Color color, Vector3 up, Vector3 forward, float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalf = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool skipDrawingEquator = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.Ellipsoid(position, radius, color, up, forward, linesWidth, text, struts, onlyUpperHalf, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects, skipDrawingEquator); + } + + /// 使用四元数旋转,绘制非均匀椭球体线框(上下半轴可分别指定) + public static void EllipsoidNonUniform(Vector3 position, float radius_x, float radius_y_upward, float radius_y_downward, float radius_z, Color color = default(Color), Quaternion rotation = default(Quaternion), float linesWidth = 0.0f, string text = null, int struts = 2, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool skipDrawingEquator = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + EllipsoidNonUniform(position, radius_x, radius_y_upward, radius_y_downward, radius_z, color, rotation * Vector3.up, rotation * Vector3.forward, linesWidth, text, struts, lineStyle, stylePatternScaleFactor, skipDrawingEquator, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定朝上和朝前方向,绘制非均匀椭球体线框(上下半轴可分别指定) + public static void EllipsoidNonUniform(Vector3 position, float radius_x, float radius_y_upward, float radius_y_downward, float radius_z, Color color, Vector3 up, Vector3 forward, float linesWidth = 0.0f, string text = null, int struts = 2, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool skipDrawingEquator = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_x, "radius_x")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_y_upward, "radius_y_upward")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_y_downward, "radius_y_downward")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_z, "radius_z")) { return; } + if (UtilitiesDXXL_Math.ApproximatelyZero(radius_x) && UtilitiesDXXL_Math.ApproximatelyZero(radius_y_upward) && UtilitiesDXXL_Math.ApproximatelyZero(radius_y_downward) && UtilitiesDXXL_Math.ApproximatelyZero(radius_z)) + { + //-> already outside of "UtilitiesDXXL_Shapes.Ellipsoid()", because otherwise the message would already be displayed if only one halfShell is zero: + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + + UtilitiesDXXL_DrawBasics.PointFallback(position, "[ Ellipsoid with extent of 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + + if ((UtilitiesDXXL_Math.ApproximatelyZero(radius_x) == false) || (UtilitiesDXXL_Math.ApproximatelyZero(radius_y_upward) == false) || (UtilitiesDXXL_Math.ApproximatelyZero(radius_z) == false)) + { + Vector3 radius_ofUpperHalfShell = new Vector3(radius_x, radius_y_upward, radius_z); + UtilitiesDXXL_Shapes.Ellipsoid(position, radius_ofUpperHalfShell, color, up, forward, linesWidth, text, struts, true, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects, skipDrawingEquator); + } + + if ((UtilitiesDXXL_Math.ApproximatelyZero(radius_x) == false) || (UtilitiesDXXL_Math.ApproximatelyZero(radius_y_downward) == false) || (UtilitiesDXXL_Math.ApproximatelyZero(radius_z) == false)) + { + Vector3 radius_ofLowerHalfShell = new Vector3(radius_x, -radius_y_downward, radius_z); + UtilitiesDXXL_Shapes.Ellipsoid(position, radius_ofLowerHalfShell, color, up, forward, linesWidth, null, struts, true, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects, true); + } + } + + /// 指定两个球心位置,绘制胶囊体线框 + public static void Capsule(Vector3 posOfCapsuleSphere1, Vector3 posOfCapsuleSphere2, float radius, Color color = default(Color), Vector3 forward_insideCrosssectionPlane = default(Vector3), float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalfSphere = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(posOfCapsuleSphere1, "posOfCapsuleSphere1")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(posOfCapsuleSphere2, "posOfCapsuleSphere2")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward_insideCrosssectionPlane, "forward_insideCrosssectionPlane")) { return; } + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(posOfCapsuleSphere1, posOfCapsuleSphere2)) + { + Vector3 up = default(Vector3); + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up, ref forward_insideCrosssectionPlane, false); + Sphere(posOfCapsuleSphere1, radius, color, up, forward_insideCrosssectionPlane, linesWidth, text, struts, onlyUpperHalfSphere, lineStyle, stylePatternScaleFactor, false, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + else + { + Vector3 up = posOfCapsuleSphere2 - posOfCapsuleSphere1; + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up, ref forward_insideCrosssectionPlane, true); + Vector3 centerPos = 0.5f * (posOfCapsuleSphere2 + posOfCapsuleSphere1); + Vector3 startToEndSphere = posOfCapsuleSphere2 - posOfCapsuleSphere1; + float height = startToEndSphere.magnitude + 2.0f * radius; + Capsule(centerPos, radius, height, color, up, forward_insideCrosssectionPlane, linesWidth, text, struts, onlyUpperHalfSphere, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + /// 通过 Transform 组件绘制胶囊体线框 + public static void Capsule(Transform transform, Color color = default(Color), float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalfSphere = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(transform, "transform")) { return; } + Capsule(transform.position, transform.lossyScale, color, transform.rotation * Vector3.up, transform.rotation * Vector3.forward, linesWidth, text, struts, onlyUpperHalfSphere, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 使用四元数旋转,绘制胶囊体线框(通过 Scale 指定尺寸) + public static void Capsule(Vector3 position, Vector3 scale, Color color = default(Color), Quaternion rotation = default(Quaternion), float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalfSphere = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Capsule(position, scale, color, rotation * Vector3.up, rotation * Vector3.forward, linesWidth, text, struts, onlyUpperHalfSphere, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定朝上和朝前方向,绘制胶囊体线框(通过 Scale 指定尺寸) + public static void Capsule(Vector3 position, Vector3 scale, Color color, Vector3 up, Vector3 forward_insideCrosssectionPlane = default(Vector3), float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalfSphere = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float absBiggestNonYDim = Mathf.Max(Mathf.Abs(scale.x), Mathf.Abs(scale.z)); + float absDiameter = absBiggestNonYDim; + float absRadius = 0.5f * absDiameter; + float heightInclBothCaps = 2.0f * scale.y; + if (Mathf.Abs(heightInclBothCaps) < absDiameter) + { + heightInclBothCaps = Mathf.Sign(scale.y) * absDiameter; + } + UtilitiesDXXL_Shapes.Capsule(position, color, absRadius, heightInclBothCaps, up, forward_insideCrosssectionPlane, linesWidth, text, struts, onlyUpperHalfSphere, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 使用四元数旋转,绘制胶囊体线框(通过半径和高度指定尺寸) + public static void Capsule(Vector3 position, float radius = 0.5f, float height = 1.0f, Color color = default(Color), Quaternion rotation = default(Quaternion), float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalfSphere = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Capsule(position, radius, height, color, rotation * Vector3.up, rotation * Vector3.forward, linesWidth, text, struts, onlyUpperHalfSphere, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定朝上和朝前方向,绘制胶囊体线框(通过半径和高度指定尺寸) + public static void Capsule(Vector3 position, float radius, float height, Color color, Vector3 up, Vector3 forward_insideCrosssectionPlane = default(Vector3), float linesWidth = 0.0f, string text = null, int struts = 2, bool onlyUpperHalfSphere = false, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height, "height")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up, "up")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward_insideCrosssectionPlane, "forward_insideCrosssectionPlane")) { return; } + + float absRadius = Mathf.Abs(radius); + float absDiameter = 2.0f * absRadius; + Vector3 shiftedPosition = position; + float heightInclBothCaps = height; + + if (onlyUpperHalfSphere == false) + { + if (Mathf.Abs(height) < absDiameter) + { + heightInclBothCaps = Mathf.Sign(height) * absDiameter; + } + } + else + { + if (Mathf.Abs(height) < absRadius) + { + heightInclBothCaps = Mathf.Sign(height) * absDiameter; + } + else + { + heightInclBothCaps = height + Mathf.Sign(height) * absRadius; + if (Mathf.Abs(height) < absDiameter) + { + float heightExclBothCaps = heightInclBothCaps - Mathf.Sign(height) * absDiameter; + shiftedPosition = position - UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(up) * heightExclBothCaps * 0.5f; + } + else + { + shiftedPosition = position - Mathf.Sign(height) * UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(up) * absRadius * 0.5f; + } + } + } + + UtilitiesDXXL_Shapes.Capsule(shiftedPosition, color, absRadius, heightInclBothCaps, up, forward_insideCrosssectionPlane, linesWidth, text, struts, onlyUpperHalfSphere, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,从顶点位置绘制棱锥体 + public static void Pyramid(Vector3 apexPosition, float height, Quaternion rotation = default(Quaternion), float angleDeg_inVertDir = 90.0f, float angleDeg_inHorizDir = 90.0f, Color color = default(Color), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Pyramid(apexPosition, height, rotation * Vector3.forward, rotation * Vector3.up, angleDeg_inVertDir, angleDeg_inHorizDir, color, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定朝前和朝上方向,从顶点位置绘制棱锥体 + public static void Pyramid(Vector3 apexPosition, float height, Vector3 forward_fromApexTowardsBase, Vector3 up_insideBasePlane = default(Vector3), float angleDeg_inVertDir = 90.0f, float angleDeg_inHorizDir = 90.0f, Color color = default(Color), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height, "height")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(angleDeg_inVertDir, "angleDeg_inVertDir")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(angleDeg_inHorizDir, "angleDeg_inHorizDir")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(apexPosition, "apexPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward_fromApexTowardsBase, "forward_fromApexTowardsBase")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideBasePlane, "up_insideBasePlane")) { return; } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up_insideBasePlane, ref forward_fromApexTowardsBase, false); + Vector3 forwardNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(forward_fromApexTowardsBase); + Vector3 baseCenterPosition = apexPosition + forwardNormalized * height; + angleDeg_inVertDir = Mathf.Clamp(angleDeg_inVertDir, 0.0f, 179.99f); + float tanOfHalfVertFieldOfView = Mathf.Tan(0.5f * angleDeg_inVertDir * Mathf.Deg2Rad); + float heightOfBaseRect = 2.0f * height * tanOfHalfVertFieldOfView; + angleDeg_inHorizDir = Mathf.Clamp(angleDeg_inHorizDir, 0.0f, 179.99f); + float tanOfHalfHorizFieldOfView = Mathf.Tan(0.5f * angleDeg_inHorizDir * Mathf.Deg2Rad); + float widthOfBaseRect = 2.0f * height * tanOfHalfHorizFieldOfView; + Pyramid(baseCenterPosition, height, widthOfBaseRect, heightOfBaseRect, color, (-forward_fromApexTowardsBase), up_insideBasePlane, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和四元数旋转,绘制棱锥体 + public static void Pyramid(Rect baseRect, float zPos_ofBaseRectCenter, float height, Quaternion rotation = default(Quaternion), Color color = default(Color), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zPos_ofBaseRectCenter, "zPos_ofBaseRectCenter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height, "height")) { return; } + + Vector3 baseCenterPosition = new Vector3(baseRect.center.x, baseRect.center.y, zPos_ofBaseRectCenter); + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Pyramid(baseCenterPosition, height, baseRect.width, baseRect.height, color, rotation * Vector3.forward, rotation * Vector3.up, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和法线方向,绘制棱锥体 + public static void Pyramid(Rect baseRect, float zPos_ofBaseRectCenter, float height, Vector3 normal_ofBaseTowardsApex, Vector3 up_insideBaseRectPlane = default(Vector3), Color color = default(Color), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zPos_ofBaseRectCenter, "zPos_ofBaseRectCenter")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideBaseRectPlane, "up_insideBaseRectPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal_ofBaseTowardsApex, "normal_ofBaseTowardsApex")) { return; } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up_insideBaseRectPlane, ref normal_ofBaseTowardsApex, false); + Vector3 baseCenterPosition = new Vector3(baseRect.center.x, baseRect.center.y, zPos_ofBaseRectCenter); + Pyramid(baseCenterPosition, height, baseRect.width, baseRect.height, color, normal_ofBaseTowardsApex, up_insideBaseRectPlane, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 通过 Hull 体积中心和缩放,绘制棱锥体 + public static void Pyramid(Vector3 center_ofPyramidHullVolume, Vector3 scale_ofPyramidHullVolume, Quaternion rotation = default(Quaternion), Color color = default(Color), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(center_ofPyramidHullVolume, "center_ofPyramidHullVolume")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(scale_ofPyramidHullVolume, "scale_ofPyramidHullVolume")) { return; } + + //scale = OverwriteDefaultVectors(scale, new Vector3(1.0f, 1.0f, 1.0f)); + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Vector3 vectorUpNormalized = rotation * Vector3.up; + Vector3 baseCenterPosition = center_ofPyramidHullVolume - 0.5f * vectorUpNormalized * scale_ofPyramidHullVolume.y; + Pyramid(baseCenterPosition, scale_ofPyramidHullVolume.y, scale_ofPyramidHullVolume.x, scale_ofPyramidHullVolume.z, color, vectorUpNormalized, rotation * Vector3.forward, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,通过底面中心绘制棱锥体 + public static void Pyramid(Vector3 center_ofBasePlane, float height, float width_ofBase, float length_ofBase, Color color = default(Color), Quaternion rotation = default(Quaternion), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Pyramid(center_ofBasePlane, height, width_ofBase, length_ofBase, color, rotation * Vector3.up, rotation * Vector3.forward, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定法线和朝上方向,通过底面中心绘制棱锥体 + public static void Pyramid(Vector3 center_ofBasePlane, float height, float width_ofBase, float length_ofBase, Color color, Vector3 normal_ofBaseTowardsApex, Vector3 up_insideBasePlane = default(Vector3), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Shapes.Pyramid(center_ofBasePlane, height, width_ofBase, length_ofBase, color, normal_ofBaseTowardsApex, up_insideBasePlane, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,从顶点位置绘制圆锥体 + public static void Cone(Vector3 apexPosition, float height, Quaternion rotation = default(Quaternion), float angleDeg_inVertDir = 90.0f, float angleDeg_inHorizDir = 90.0f, Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Cone(apexPosition, height, rotation * Vector3.forward, rotation * Vector3.up, angleDeg_inVertDir, angleDeg_inHorizDir, color, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定朝前和朝上方向,从顶点位置绘制圆锥体 + public static void Cone(Vector3 apexPosition, float height, Vector3 forward_fromApexTowardsBase, Vector3 up_insideBaseCircle = default(Vector3), float angleDeg_inVertDir = 90.0f, float angleDeg_inHorizDir = 90.0f, Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Pyramid(apexPosition, height, forward_fromApexTowardsBase, up_insideBaseCircle, angleDeg_inVertDir, angleDeg_inHorizDir, color, Shape2DType.circle4struts, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 通过 Hull 体积中心和缩放,绘制圆锥体 + public static void Cone(Vector3 center_ofConeHullVolume, Vector3 scale_ofConeHullVolume, Quaternion rotation = default(Quaternion), Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Pyramid(center_ofConeHullVolume, scale_ofConeHullVolume, rotation, color, Shape2DType.circle4struts, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,通过底面中心绘制圆锥体 + public static void Cone(Vector3 center_ofBaseCircle, float height, float width_ofBaseCircle, float length_ofBaseCircle, Color color = default(Color), Quaternion rotation = default(Quaternion), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Cone(center_ofBaseCircle, height, width_ofBaseCircle, length_ofBaseCircle, color, rotation * Vector3.up, rotation * Vector3.forward, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定法线和朝上方向,通过底面中心绘制圆锥体 + public static void Cone(Vector3 center_ofBaseCircle, float height, float width_ofBaseCircle, float length_ofBaseCircle, Color color, Vector3 normal_ofBaseCircleTowardsApex, Vector3 up_insideBaseCircle = default(Vector3), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Pyramid(center_ofBaseCircle, height, width_ofBaseCircle, length_ofBaseCircle, color, normal_ofBaseCircleTowardsApex, up_insideBaseCircle, Shape2DType.circle4struts, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,从顶点位置绘制填充圆锥体 + public static void ConeFilled(Vector3 apexPosition, float height, Quaternion rotation = default(Quaternion), float angleDeg_inVertDir = 90.0f, float angleDeg_inHorizDir = 90.0f, Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + ConeFilled(apexPosition, height, rotation * Vector3.forward, rotation * Vector3.up, angleDeg_inVertDir, angleDeg_inHorizDir, color, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定朝前和朝上方向,从顶点位置绘制填充圆锥体 + public static void ConeFilled(Vector3 apexPosition, float height, Vector3 forward_fromApexTowardsBase, Vector3 up_insideBaseCircle = default(Vector3), float angleDeg_inVertDir = 90.0f, float angleDeg_inHorizDir = 90.0f, Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Pyramid(apexPosition, height, forward_fromApexTowardsBase, up_insideBaseCircle, angleDeg_inVertDir, angleDeg_inHorizDir, color, Shape2DType.circle, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 通过 Hull 体积中心和缩放,绘制填充圆锥体 + public static void ConeFilled(Vector3 center_ofConeHullVolume, Vector3 scale_ofConeHullVolume, Quaternion rotation = default(Quaternion), Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Pyramid(center_ofConeHullVolume, scale_ofConeHullVolume, rotation, color, Shape2DType.circle, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,通过底面中心绘制填充圆锥体 + public static void ConeFilled(Vector3 center_ofBaseCircle, float height, float width_ofBaseCircle, float length_ofBaseCircle, Color color = default(Color), Quaternion rotation = default(Quaternion), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + ConeFilled(center_ofBaseCircle, height, width_ofBaseCircle, length_ofBaseCircle, color, rotation * Vector3.up, rotation * Vector3.forward, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定法线和朝上方向,通过底面中心绘制填充圆锥体 + public static void ConeFilled(Vector3 center_ofBaseCircle, float height, float width_ofBaseCircle, float length_ofBaseCircle, Color color, Vector3 normal_ofBaseCircleTowardsApex, Vector3 up_insideBaseCircle = default(Vector3), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Pyramid(center_ofBaseCircle, height, width_ofBaseCircle, length_ofBaseCircle, color, normal_ofBaseCircleTowardsApex, up_insideBaseCircle, Shape2DType.circle, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和四元数旋转,绘制双棱锥体 + public static void Bipyramid(Rect baseRect, float zPos_ofBaseRectCenter, float heightUp, float heightDown, Quaternion rotation = default(Quaternion), Color color = default(Color), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zPos_ofBaseRectCenter, "zPos_ofBaseRectCenter")) { return; } + + Vector3 baseCenterPosition = new Vector3(baseRect.center.x, baseRect.center.y, zPos_ofBaseRectCenter); + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Bipyramid(baseCenterPosition, heightUp, heightDown, baseRect.width, baseRect.height, color, rotation * Vector3.forward, rotation * Vector3.up, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和法线方向,绘制双棱锥体 + public static void Bipyramid(Rect baseRect, float zPos_ofBaseRectCenter, float heightUp, float heightDown, Vector3 normal_ofBaseTowardsUpperApex, Vector3 up_insideBaseRectPlane = default(Vector3), Color color = default(Color), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zPos_ofBaseRectCenter, "zPos_ofBaseRectCenter")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideBaseRectPlane, "up_insideBaseRectPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal_ofBaseTowardsUpperApex, "normal_ofBaseTowardsUpperApex")) { return; } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up_insideBaseRectPlane, ref normal_ofBaseTowardsUpperApex, false); + Vector3 baseCenterPosition = new Vector3(baseRect.center.x, baseRect.center.y, zPos_ofBaseRectCenter); + Bipyramid(baseCenterPosition, heightUp, heightDown, baseRect.width, baseRect.height, color, normal_ofBaseTowardsUpperApex, up_insideBaseRectPlane, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 通过 Hull 体积中心和缩放,绘制双棱锥体 + public static void Bipyramid(Vector3 center_ofBasePlane, Vector3 scale_ofBipyramidHullVolume, Quaternion rotation = default(Quaternion), Color color = default(Color), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(scale_ofBipyramidHullVolume, "scale_ofBipyramidHullVolume")) { return; } + + //scale = OverwriteDefaultVectors(scale, new Vector3(1.0f, 1.0f, 1.0f)); + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Bipyramid(center_ofBasePlane, 0.5f * scale_ofBipyramidHullVolume.y, -0.5f * scale_ofBipyramidHullVolume.y, scale_ofBipyramidHullVolume.x, scale_ofBipyramidHullVolume.z, color, rotation * Vector3.up, rotation * Vector3.forward, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,通过底面中心绘制双棱锥体 + public static void Bipyramid(Vector3 center_ofBasePlane, float heightUp, float heightDown, float width_ofBase, float length_ofBase, Color color = default(Color), Quaternion rotation = default(Quaternion), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Bipyramid(center_ofBasePlane, heightUp, heightDown, width_ofBase, length_ofBase, color, rotation * Vector3.up, rotation * Vector3.forward, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定法线和朝上方向,通过底面中心绘制双棱锥体 + public static void Bipyramid(Vector3 center_ofBasePlane, float heightUp, float heightDown, float width_ofBase, float length_ofBase, Color color, Vector3 normal_ofBaseTowardsUpperApex, Vector3 up_insideBasePlane = default(Vector3), Shape2DType baseShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Shapes.Bipyramid(center_ofBasePlane, heightUp, heightDown, width_ofBase, length_ofBase, color, normal_ofBaseTowardsUpperApex, up_insideBasePlane, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和四元数旋转,绘制圆柱体 + public static void Cylinder(Rect crossSectionHullRect, float zPos_ofHullRectCenter, float height, Quaternion rotation = default(Quaternion), Color color = default(Color), Shape2DType baseShape = Shape2DType.circle4struts, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 baseCenterPosition = new Vector3(crossSectionHullRect.center.x, crossSectionHullRect.center.y, zPos_ofHullRectCenter); + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Cylinder(baseCenterPosition, height, crossSectionHullRect.width, crossSectionHullRect.height, color, rotation * Vector3.forward, rotation * Vector3.up, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和挤出方向,绘制圆柱体 + public static void Cylinder(Rect crossSectionHullRect, float zPos_ofHullRectCenter, float height, Vector3 extrusionDirection, Vector3 up_insideCrossSectionPlane = default(Vector3), Color color = default(Color), Shape2DType baseShape = Shape2DType.circle4struts, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideCrossSectionPlane, "up_insideCrossSectionPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(extrusionDirection, "extrusionDirection")) { return; } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up_insideCrossSectionPlane, ref extrusionDirection, false); + Vector3 baseCenterPosition = new Vector3(crossSectionHullRect.center.x, crossSectionHullRect.center.y, zPos_ofHullRectCenter); + Cylinder(baseCenterPosition, height, crossSectionHullRect.width, crossSectionHullRect.height, color, extrusionDirection, up_insideCrossSectionPlane, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 通过 Hull 体积中心和缩放,绘制圆柱体 + public static void Cylinder(Vector3 center_ofCylinderHullVolume, Vector3 scale_ofCylinderHullVolume, Quaternion rotation = default(Quaternion), Color color = default(Color), Shape2DType baseShape = Shape2DType.circle4struts, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(scale_ofCylinderHullVolume, "scale_ofCylinderHullVolume")) { return; } + + //scale = OverwriteDefaultVectors(scale, new Vector3(1.0f, 1.0f, 1.0f)); + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Cylinder(center_ofCylinderHullVolume, scale_ofCylinderHullVolume.y, scale_ofCylinderHullVolume.x, scale_ofCylinderHullVolume.z, color, rotation * Vector3.up, rotation * Vector3.forward, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,通过底面尺寸绘制圆柱体 + public static void Cylinder(Vector3 center_ofCylinderHullVolume, float height, float width_ofBase, float length_ofBase, Color color = default(Color), Quaternion rotation = default(Quaternion), Shape2DType baseShape = Shape2DType.circle4struts, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Cylinder(center_ofCylinderHullVolume, height, width_ofBase, length_ofBase, color, rotation * Vector3.up, rotation * Vector3.forward, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定挤出方向,通过底面尺寸绘制圆柱体 + public static void Cylinder(Vector3 center_ofCylinderHullVolume, float height, float width_ofBase, float length_ofBase, Color color, Vector3 extrusionDirection, Vector3 up_insideCrossSectionPlane = default(Vector3), Shape2DType baseShape = Shape2DType.circle4struts, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Shapes.Cylinder(center_ofCylinderHullVolume, height, width_ofBase, length_ofBase, color, extrusionDirection, up_insideCrossSectionPlane, baseShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和四元数旋转,绘制挤出体 + public static void Extrusion(Rect hullRect_ofExtrudedCrosssection, float zPos_ofExtrudedRect, float extrusionDistanceForward, float extrusionDistanceBackward, Quaternion rotation = default(Quaternion), Color color = default(Color), Shape2DType extrusionShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zPos_ofExtrudedRect, "zPos_ofExtrudedRect")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(extrusionDistanceForward, "extrusionDistanceForward")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(extrusionDistanceBackward, "extrusionDistanceBackward")) { return; } + + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Vector3 forwardNormalized = rotation * Vector3.forward; + float cumulatedExtrusionHeight = extrusionDistanceForward - extrusionDistanceBackward; + Vector3 rectCenterPosition = new Vector3(hullRect_ofExtrudedCrosssection.center.x, hullRect_ofExtrudedCrosssection.center.y, zPos_ofExtrudedRect); + Vector3 negativeEndOfExtrusionCylinder = rectCenterPosition + forwardNormalized * extrusionDistanceBackward; + Vector3 cylinderCenterPos = negativeEndOfExtrusionCylinder + forwardNormalized * (0.5f * cumulatedExtrusionHeight); + Cylinder(cylinderCenterPos, cumulatedExtrusionHeight, hullRect_ofExtrudedCrosssection.width, hullRect_ofExtrudedCrosssection.height, color, rotation * Vector3.forward, rotation * Vector3.up, extrusionShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和挤出方向,绘制挤出体 + public static void Extrusion(Rect hullRect_ofExtrudedCrosssection, float zPos_ofExtrudedRect, float extrusionDistanceForward, float extrusionDistanceBackward, Vector3 extrusionDirection, Vector3 up_insideCrosssectionPlane = default(Vector3), Color color = default(Color), Shape2DType extrusionShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zPos_ofExtrudedRect, "zPos_ofExtrudedRect")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(extrusionDistanceForward, "extrusionDistanceForward")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(extrusionDistanceBackward, "extrusionDistanceBackward")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideCrosssectionPlane, "up_insideCrosssectionPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(extrusionDirection, "extrusionDirection")) { return; } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up_insideCrosssectionPlane, ref extrusionDirection, false); + Vector3 forwardNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(extrusionDirection); + float cumulatedExtrusionHeight = extrusionDistanceForward - extrusionDistanceBackward; + Vector3 rectCenterPosition = new Vector3(hullRect_ofExtrudedCrosssection.center.x, hullRect_ofExtrudedCrosssection.center.y, zPos_ofExtrudedRect); + Vector3 negativeEndOfExtrusionCylinder = rectCenterPosition + forwardNormalized * extrusionDistanceBackward; + Vector3 cylinderCenterPos = negativeEndOfExtrusionCylinder + forwardNormalized * (0.5f * cumulatedExtrusionHeight); + Cylinder(cylinderCenterPos, cumulatedExtrusionHeight, hullRect_ofExtrudedCrosssection.width, hullRect_ofExtrudedCrosssection.height, color, extrusionDirection, up_insideCrosssectionPlane, extrusionShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,通过基底位置绘制挤出体 + public static void Extrusion(Vector3 centerPos_ofExtrusionBase, float extrusionHeightUp, float extrusionHeightDown, float width_ofExtrudedCrosssection, float length_ofExtrudedCrosssection, Color color = default(Color), Quaternion rotation = default(Quaternion), Shape2DType extrusionShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Extrusion(centerPos_ofExtrusionBase, extrusionHeightUp, extrusionHeightDown, width_ofExtrudedCrosssection, length_ofExtrudedCrosssection, color, rotation * Vector3.up, rotation * Vector3.forward, extrusionShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定挤出方向,通过基底位置绘制挤出体 + public static void Extrusion(Vector3 centerPos_ofExtrusionBase, float extrusionHeightUp, float extrusionHeightDown, float width_ofExtrudedCrosssection, float length_ofExtrudedCrosssection, Color color, Vector3 extrusionDirection, Vector3 up_insideCrossSectionPlane = default(Vector3), Shape2DType extrusionShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(extrusionHeightUp, "extrusionHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(extrusionHeightDown, "extrusionHeightDown")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerPos_ofExtrusionBase, "centerPos_ofExtrusionBase")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(extrusionDirection, "extrusionDirection")) { return; } + + extrusionDirection = UtilitiesDXXL_Math.OverwriteDefaultVectors(extrusionDirection, Vector3.up); + Vector3 extrusionDirNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(extrusionDirection); + float cumulatedExtrusionHeight = extrusionHeightUp - extrusionHeightDown; + Vector3 negativeEndOfExtrusionCylinder = centerPos_ofExtrusionBase + extrusionDirNormalized * extrusionHeightDown; + Vector3 cylinderCenterPos = negativeEndOfExtrusionCylinder + extrusionDirNormalized * (0.5f * cumulatedExtrusionHeight); + Cylinder(cylinderCenterPos, cumulatedExtrusionHeight, width_ofExtrudedCrosssection, length_ofExtrudedCrosssection, color, extrusionDirection, up_insideCrossSectionPlane, extrusionShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 通过 Camera 组件绘制视锥体裁剪面 + public static void Frustum(Camera camera, Color color = default(Color), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + Frustum(camera.transform.position, camera.transform.forward, camera.transform.up, camera.fieldOfView, camera.aspect, camera.nearClipPlane, camera.farClipPlane, color, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,通过相机参数绘制视锥体裁剪面 + public static void Frustum(Vector3 cameraPosition_frustumApex, Quaternion cameraRotation, float angleDeg_verticalFieldOfView = 60.0f, float aspectRatio = (16.0f / 9.0f), float distanceApexToNearPlane = 0.5f, float distanceApexToFarPlane = 1.0f, Color color = default(Color), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + cameraRotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(cameraRotation); + Vector3 cameraForward = cameraRotation * Vector3.forward; + Vector3 cameraUp = cameraRotation * Vector3.up; + Frustum(cameraPosition_frustumApex, cameraForward, cameraUp, angleDeg_verticalFieldOfView, aspectRatio, distanceApexToNearPlane, distanceApexToFarPlane, color, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 指定朝前和朝上方向,通过相机参数绘制视锥体裁剪面 + public static void Frustum(Vector3 cameraPosition_frustumApex, Vector3 cameraForward, Vector3 cameraUp, float angleDeg_verticalFieldOfView = 60.0f, float aspectRatio = (16.0f / 9.0f), float distanceApexToNearPlane = 0.5f, float distanceApexToFarPlane = 1.0f, Color color = default(Color), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(angleDeg_verticalFieldOfView, "angleDeg_verticalFieldOfView")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(aspectRatio, "aspectRatio")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceApexToNearPlane, "distanceApexToNearPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceApexToFarPlane, "distanceApexToFarPlane")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(cameraPosition_frustumApex, "cameraPosition_frustumApex")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(cameraForward, "cameraForward")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(cameraUp, "cameraUp")) { return; } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref cameraUp, ref cameraForward, false); + Vector3 forwardNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(cameraForward); + Vector3 bigPlaneCenterPos = cameraPosition_frustumApex + forwardNormalized * distanceApexToFarPlane; + Vector3 smallPlaneCenterPos = cameraPosition_frustumApex + forwardNormalized * distanceApexToNearPlane; + angleDeg_verticalFieldOfView = Mathf.Clamp(angleDeg_verticalFieldOfView, 0.0f, 179.99f); + float tanOfHalfFieldOfView = Mathf.Tan(0.5f * angleDeg_verticalFieldOfView * Mathf.Deg2Rad); + float heightAtFarPlane = 2.0f * distanceApexToFarPlane * tanOfHalfFieldOfView; + float heightAtNearPlane = 2.0f * distanceApexToNearPlane * tanOfHalfFieldOfView; + Frustum(bigPlaneCenterPos, smallPlaneCenterPos, heightAtFarPlane * aspectRatio, heightAtFarPlane, heightAtNearPlane * aspectRatio, heightAtNearPlane, color, cameraUp, cameraForward, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和四元数旋转,绘制视锥体裁剪面 + public static void Frustum(Rect bigClipPlaneRect, float zPos_ofBigClipPlaneCenter, float distanceBetweenClipPlanes, float scalingFactor_forSmallClipPlane, Quaternion rotation = default(Quaternion), Color color = default(Color), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zPos_ofBigClipPlaneCenter, "zPos_ofBigClipPlaneCenter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceBetweenClipPlanes, "distanceBetweenClipPlanes")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(scalingFactor_forSmallClipPlane, "scalingFactor_forSmallClipPlane")) { return; } + + Vector3 baseCenterPosition = new Vector3(bigClipPlaneRect.center.x, bigClipPlaneRect.center.y, zPos_ofBigClipPlaneCenter); + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Vector3 forwardNormalized = rotation * Vector3.forward; + Vector3 smallPlaneCenterPos = baseCenterPosition + forwardNormalized * distanceBetweenClipPlanes; + Frustum(baseCenterPosition, smallPlaneCenterPos, bigClipPlaneRect.width, bigClipPlaneRect.height, scalingFactor_forSmallClipPlane * bigClipPlaneRect.width, scalingFactor_forSmallClipPlane * bigClipPlaneRect.height, color, rotation * Vector3.up, forwardNormalized, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和法线方向,绘制视锥体裁剪面 + public static void Frustum(Rect bigClipPlaneRect, float zPos_ofBigClipPlaneCenter, float distanceBetweenClipPlanes, float scalingFactor_forSmallClipPlane, Vector3 normal_ofClipPlaneRects_towardsApex, Vector3 up_insideClippedRects = default(Vector3), Color color = default(Color), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zPos_ofBigClipPlaneCenter, "zPos_ofBigClipPlaneCenter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceBetweenClipPlanes, "distanceBetweenClipPlanes")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(scalingFactor_forSmallClipPlane, "scalingFactor_forSmallClipPlane")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideClippedRects, "up_insideClippedRects")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal_ofClipPlaneRects_towardsApex, "normal_ofClipPlaneRects_towardsApex")) { return; } + + Vector3 baseCenterPosition = new Vector3(bigClipPlaneRect.center.x, bigClipPlaneRect.center.y, zPos_ofBigClipPlaneCenter); + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up_insideClippedRects, ref normal_ofClipPlaneRects_towardsApex, false); + Vector3 forwardNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(normal_ofClipPlaneRects_towardsApex); + Vector3 smallPlaneCenterPos = baseCenterPosition + forwardNormalized * distanceBetweenClipPlanes; + Frustum(baseCenterPosition, smallPlaneCenterPos, bigClipPlaneRect.width, bigClipPlaneRect.height, scalingFactor_forSmallClipPlane * bigClipPlaneRect.width, scalingFactor_forSmallClipPlane * bigClipPlaneRect.height, color, up_insideClippedRects, forwardNormalized, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 通过 Hull 体积中心和缩放,绘制视锥体裁剪面 + public static void Frustum(Vector3 center_ofFrustumHullVolume, Vector3 scale_ofFrustumHullVolume, Quaternion rotation, float scalingFactor_forSmallClipPlane = 0.5f, Color color = default(Color), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(scalingFactor_forSmallClipPlane, "scalingFactor_forSmallClipPlane")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(center_ofFrustumHullVolume, "center_ofFrustumHullVolume")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(scale_ofFrustumHullVolume, "scale_ofFrustumHullVolume")) { return; } + + //scale = OverwriteDefaultVectors(scale, new Vector3(1.0f, 1.0f, 1.0f)); + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Vector3 upNormalized = rotation * Vector3.up; + Vector3 bigPlaneCenterPos = center_ofFrustumHullVolume - upNormalized * 0.5f * scale_ofFrustumHullVolume.y; + Vector3 smallPlaneCenterPos = center_ofFrustumHullVolume + upNormalized * 0.5f * scale_ofFrustumHullVolume.y; + Frustum(bigPlaneCenterPos, smallPlaneCenterPos, scale_ofFrustumHullVolume.x, scale_ofFrustumHullVolume.z, scalingFactor_forSmallClipPlane * scale_ofFrustumHullVolume.x, scalingFactor_forSmallClipPlane * scale_ofFrustumHullVolume.z, color, rotation * Vector3.forward, upNormalized, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,通过裁剪面距离和尺寸绘制视锥体裁剪面 + public static void Frustum(float distance_bigClipPlaneToApex, float distanceBetweenClipPlanes, Vector3 center_ofBigClipPlane, Quaternion rotation = default(Quaternion), float width_ofBigClipPlane = 1.0f, float height_ofBigClipPlane = 1.0f, Color color = default(Color), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Vector3 normal_ofClipPlanes_towardsApex = rotation * Vector3.up; + Vector3 up_insideClippedPlanes = rotation * Vector3.forward; + Frustum(distance_bigClipPlaneToApex, distanceBetweenClipPlanes, center_ofBigClipPlane, normal_ofClipPlanes_towardsApex, up_insideClippedPlanes, width_ofBigClipPlane, height_ofBigClipPlane, color, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定法线方向,通过裁剪面距离和尺寸绘制视锥体裁剪面 + public static void Frustum(float distance_bigClipPlaneToApex, float distanceBetweenClipPlanes, Vector3 center_ofBigClipPlane, Vector3 normal_ofClipPlanes_towardsApex, Vector3 up_insideClippedPlanes = default(Vector3), float width_ofBigClipPlane = 1.0f, float height_ofBigClipPlane = 1.0f, Color color = default(Color), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_ofBigClipPlane, "width_ofBigClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height_ofBigClipPlane, "height_ofBigClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceBetweenClipPlanes, "distanceBetweenClipPlanes")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distance_bigClipPlaneToApex, "distance_bigClipPlaneToApex")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(center_ofBigClipPlane, "center_ofBigClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal_ofClipPlanes_towardsApex, "normal_ofClipPlanes_towardsApex")) { return; } + + float smallPlaneScaleFactor = (distance_bigClipPlaneToApex - distanceBetweenClipPlanes) / distance_bigClipPlaneToApex; + Frustum(center_ofBigClipPlane, center_ofBigClipPlane + UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(normal_ofClipPlanes_towardsApex) * distanceBetweenClipPlanes, width_ofBigClipPlane, height_ofBigClipPlane, width_ofBigClipPlane * smallPlaneScaleFactor, height_ofBigClipPlane * smallPlaneScaleFactor, color, up_insideClippedPlanes, normal_ofClipPlanes_towardsApex, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用四元数旋转,通过裁剪面距离和缩放因子绘制视锥体裁剪面 + public static void Frustum(Vector3 center_ofBigClipPlane, float distanceBetweenClipPlanes, float scalingFactor_forSmallClipPlane, Quaternion rotation = default(Quaternion), float width_ofBigClipPlane = 1.0f, float height_ofBigClipPlane = 1.0f, Color color = default(Color), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + rotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation); + Vector3 normal_ofClipPlanes_towardsApex = rotation * Vector3.up; + Vector3 up_insideClippedPlanes = rotation * Vector3.forward; + Frustum(center_ofBigClipPlane, distanceBetweenClipPlanes, scalingFactor_forSmallClipPlane, normal_ofClipPlanes_towardsApex, up_insideClippedPlanes, width_ofBigClipPlane, height_ofBigClipPlane, color, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定法线方向,通过裁剪面距离和缩放因子绘制视锥体裁剪面 + public static void Frustum(Vector3 center_ofBigClipPlane, float distanceBetweenClipPlanes, float scalingFactor_forSmallClipPlane, Vector3 normal_ofClipPlanes_towardsApex, Vector3 up_insideClippedPlanes = default(Vector3), float width_ofBigClipPlane = 1.0f, float height_ofBigClipPlane = 1.0f, Color color = default(Color), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_ofBigClipPlane, "width_ofBigClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height_ofBigClipPlane, "height_ofBigClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceBetweenClipPlanes, "distanceBetweenClipPlanes")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(scalingFactor_forSmallClipPlane, "scalingFactor_forSmallClipPlane")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(center_ofBigClipPlane, "center_ofBigClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal_ofClipPlanes_towardsApex, "normal_ofClipPlanes_towardsApex")) { return; } + + Frustum(center_ofBigClipPlane, center_ofBigClipPlane + UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(normal_ofClipPlanes_towardsApex) * distanceBetweenClipPlanes, width_ofBigClipPlane, height_ofBigClipPlane, scalingFactor_forSmallClipPlane * width_ofBigClipPlane, scalingFactor_forSmallClipPlane * height_ofBigClipPlane, color, up_insideClippedPlanes, normal_ofClipPlanes_towardsApex, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定远裁剪面和近裁剪面的中心位置和尺寸,绘制视锥体裁剪面 + public static void Frustum(Vector3 center_ofBigClipPlane, Vector3 center_ofSmallClipPlane, float width_ofBigClipPlane, float height_ofBigClipPlane, float width_ofSmallClipPlane, float height_ofSmallClipPlane, Color color = default(Color), Vector3 up_insideClippedPlanes = default(Vector3), Vector3 fallback_for_normalOfClipPlanesTowardsApex = default(Vector3), Shape2DType clipPlanesShape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Shapes.Frustum(center_ofBigClipPlane, center_ofSmallClipPlane, width_ofBigClipPlane, height_ofBigClipPlane, width_ofSmallClipPlane, height_ofSmallClipPlane, color, up_insideClippedPlanes, fallback_for_normalOfClipPlanesTowardsApex, clipPlanesShape, linesWidth, text, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和四元数旋转,绘制二维平面形状 + public static int FlatShape(Rect hullRect, Shape2DType shapeType = Shape2DType.square, float zPos_ofRectCenter = 0.0f, Quaternion rotation = default(Quaternion), Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool flattenRoundLines_intoShapePlane = true, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zPos_ofRectCenter, "zPos_ofRectCenter")) { return 0; } + + Vector3 baseCenterPosition = new Vector3(hullRect.center.x, hullRect.center.y, zPos_ofRectCenter); + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return FlatShape(baseCenterPosition, shapeType, hullRect.width, hullRect.height, color, normal, up_insideFlatPlane, linesWidth, text, lineStyle, stylePatternScaleFactor, flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和法线方向,绘制二维平面形状 + public static int FlatShape(Rect hullRect, Shape2DType shapeType, float zPos_ofRectCenter, Vector3 normal, Vector3 up_insideShapePlane = default(Vector3), Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool flattenRoundLines_intoShapePlane = true, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zPos_ofRectCenter, "zPos_ofRectCenter")) { return 0; } + + Vector3 baseCenterPosition = new Vector3(hullRect.center.x, hullRect.center.y, zPos_ofRectCenter); + return FlatShape(baseCenterPosition, shapeType, hullRect.width, hullRect.height, color, normal, up_insideShapePlane, linesWidth, text, lineStyle, stylePatternScaleFactor, flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用中心位置、尺寸和四元数旋转,绘制二维平面形状 + public static int FlatShape(Vector3 centerPosition, Shape2DType shapeType = Shape2DType.square, float width = 1.0f, float height = 1.0f, Color color = default(Color), Quaternion rotation = default(Quaternion), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool flattenRoundLines_intoShapePlane = true, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + UtilitiesDXXL_Shapes.ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, rotation); + return FlatShape(centerPosition, shapeType, width, height, color, normal, up_insideFlatPlane, linesWidth, text, lineStyle, stylePatternScaleFactor, flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定法线和朝上方向,绘制二维平面形状 + public static int FlatShape(Vector3 centerPosition, Shape2DType shapeType, float width, float height, Color color, Vector3 normal, Vector3 up_insideShapePlane = default(Vector3), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool flattenRoundLines_intoShapePlane = true, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + return UtilitiesDXXL_Shapes.FlatShape(centerPosition, width, height, color, normal, up_insideShapePlane, shapeType, linesWidth, text, lineStyle, stylePatternScaleFactor, flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和四元数旋转,绘制矩形 + public static void Rectangle(Rect rect, float zPos_ofRectCenter = 0.0f, Quaternion rotation = default(Quaternion), Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool flattenRoundLines_intoShapePlane = true, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + FlatShape(rect, Shape2DType.square, zPos_ofRectCenter, rotation, color, linesWidth, text, lineStyle, stylePatternScaleFactor, flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 和法线方向,绘制矩形 + public static void Rectangle(Rect rect, float zPos_ofRectCenter, Vector3 normal, Vector3 up_insideRectPlane = default(Vector3), Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool flattenRoundLines_intoShapePlane = true, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + FlatShape(rect, Shape2DType.square, zPos_ofRectCenter, normal, up_insideRectPlane, color, linesWidth, text, lineStyle, stylePatternScaleFactor, flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用中心位置、尺寸和四元数旋转,绘制矩形 + public static void Rectangle(Vector3 centerPosition, Vector2 size, Quaternion rotation = default(Quaternion), Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool flattenRoundLines_intoShapePlane = true, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + FlatShape(centerPosition, Shape2DType.square, size.x, size.y, color, rotation, linesWidth, text, lineStyle, stylePatternScaleFactor, flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定法线和朝上方向,绘制矩形 + public static void Rectangle(Vector3 centerPosition, Vector2 size, Vector3 normal, Vector3 up_insideBoxPlane = default(Vector3), Color color = default(Color), float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, bool flattenRoundLines_intoShapePlane = true, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + FlatShape(centerPosition, Shape2DType.square, size.x, size.y, color, normal, up_insideBoxPlane, linesWidth, text, lineStyle, stylePatternScaleFactor, flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 绘制二维矩形框 + public static void Box2D(Rect boxRect, Color color = default(Color), float zPos = 0.0f, float angleDegCC = 0.0f, Shape2DType shape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //-> not documented, because it creates confusion with "DrawBasics2D.Box". + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Box2D(boxRect.center, boxRect.size, color, zPos, angleDegCC, shape, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用中心位置和尺寸绘制二维矩形框 + public static void Box2D(Vector2 centerPosition, Vector2 size, Color color = default(Color), float zPos = 0.0f, float angleDegCC = 0.0f, Shape2DType shape = Shape2DType.square, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //-> not documented, because it creates confusion with "DrawBasics2D.Box". + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(angleDegCC, "angleDeg")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(size, "size")) { return; } + + Vector3 up_insideBoxPlane = UtilitiesDXXL_Math.ApproximatelyZero(angleDegCC) ? Vector3.up : Quaternion.AngleAxis(angleDegCC, Vector3.forward) * Vector3.up; + Vector3 positionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(centerPosition, zPos); + lineStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(lineStyle); + fillStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(fillStyle); + UtilitiesDXXL_Shapes.FlatShape(positionV3, size.x, size.y, color, Vector3.forward, up_insideBoxPlane, shape, linesWidth, text, lineStyle, stylePatternScaleFactor, true, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用 Rect 绘制二维圆形 + public static void Circle2D(Rect hullRect, Color color = default(Color), float zPos = 0.0f, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //-> not documented, because it creates confusion with "DrawBasics2D.Circle". + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Box2D(hullRect.center, hullRect.size, color, zPos, 0.0f, Shape2DType.circle, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 使用中心位置和半径绘制二维圆形 + public static void Circle2D(Vector2 centerPosition, float radius = 0.5f, Color color = default(Color), float zPos = 0.0f, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //-> not documented, because it creates confusion with "DrawBasics2D.Circle". + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + + float diameter = 2.0f * radius; + Box2D(centerPosition, new Vector2(diameter, diameter), color, zPos, 0.0f, Shape2DType.circle, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + /// 指定两个圆心位置,绘制二维胶囊体 + public static void Capsule2D(Vector2 posOfCircle1, Vector2 posOfCircle2, float radius = 0.5f, Color color = default(Color), float zPos = 0.0f, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //-> not documented, because it creates confusion with "DrawBasics2D.Capsule". + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 posOfCircle1_asV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(posOfCircle1, zPos); + Vector3 posOfCircle2_asV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(posOfCircle2, zPos); + lineStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(lineStyle); + fillStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(fillStyle); + FlatCapsule(posOfCircle1_asV3, posOfCircle2_asV3, radius, color, Vector3.forward, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 使用 Rect 绘制二维胶囊体 + public static void Capsule2D(Rect hullRect, Color color = default(Color), float zPos = 0.0f, CapsuleDirection2D capsuleDirection = CapsuleDirection2D.Vertical, float angleDegCC = 0.0f, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //-> not documented, because it creates confusion with "DrawBasics2D.Capsule". + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Capsule2D(hullRect.center, hullRect.size, color, zPos, capsuleDirection, angleDegCC, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + /// 使用中心位置和尺寸绘制二维胶囊体 + public static void Capsule2D(Vector2 centerPosition, Vector2 size, Color color = default(Color), float zPos = 0.0f, CapsuleDirection2D capsuleDirection = CapsuleDirection2D.Vertical, float angleDegCC = 0.0f, float linesWidth = 0.0f, string text = null, DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid, float stylePatternScaleFactor = 1.0f, DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible, bool filledWithSpokes = false, bool textBlockAboveLine = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //-> not documented, because it creates confusion with "DrawBasics2D.Capsule". + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(angleDegCC, "angleDeg")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(size, "size")) { return; } + + Vector3 upAlongVert_insideCapsulePlane = UtilitiesDXXL_Math.ApproximatelyZero(angleDegCC) ? Vector3.up : Quaternion.AngleAxis(angleDegCC, Vector3.forward) * Vector3.up; + Vector3 positionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(centerPosition, zPos); + lineStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(lineStyle); + fillStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(fillStyle); + FlatCapsule(positionV3, size.x, size.y, color, Vector3.forward, upAlongVert_insideCapsulePlane, capsuleDirection, linesWidth, text, lineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + } + +} + + + + + diff --git a/Runtime/DrawDebugLibrary/DrawShapes.cs.meta b/Runtime/DrawDebugLibrary/DrawShapes.cs.meta new file mode 100644 index 0000000..fb65d69 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawShapes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aeeafc67d666379449eca4d735475afd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/DrawText.cs b/Runtime/DrawDebugLibrary/DrawText.cs new file mode 100644 index 0000000..50463e9 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawText.cs @@ -0,0 +1,1802 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class DrawText + { + public enum TextAnchorDXXL { UpperLeft, UpperCenter, UpperRight, MiddleLeft, MiddleCenter, MiddleRight, LowerLeft, LowerCenter, LowerRight, LowerLeftOfFirstLine, LowerCenterOfFirstLine, LowerRightOfFirstLine } + public enum TextAnchorCircledDXXL + { + LowerLeftOfFirstLine, + LowerLeftOfWholeTextBlock + } + + public enum AutomaticTextOrientation + { + screen, + screen_butVerticalInWorldSpace, + xyPlane, + xzPlane, + zyPlane + } + public static AutomaticTextOrientation automaticTextOrientation = AutomaticTextOrientation.screen; + + public static ParsedTextSpecs parsedTextSpecs = new ParsedTextSpecs(); //is filled with the values of the most recently called WriteText-function. + public static ParsedTextOnCircleSpecs parsedTextOnCircleSpecs = new ParsedTextOnCircleSpecs(); //is filled with the values of the most recently called WriteTextCircled-function. + + /// 在屏幕空间中绘制 3D 文本标签,使用 3D 世界坐标和方向向量指定文本位置与方向 + public static void WriteScreenspace(string text, Vector3 position_in3DWorldspace, Color color, float size_relToViewportHeight, Vector2 textDirection, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteScreenspace") == false) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam.Add(new TextScreenspace_3Dpos_dirViaVec_cam(automaticallyFoundCamera, text, position_in3DWorldspace, color, size_relToViewportHeight, textDirection, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteScreenspace(text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + + /// 在屏幕空间中绘制 3D 文本标签,使用指定摄像机和 3D 世界坐标与方向向量 + public static void WriteScreenspace(Camera screenCamera, string text, Vector3 position_in3DWorldspace, Color color, float size_relToViewportHeight, Vector2 textDirection, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam.Add(new TextScreenspace_3Dpos_dirViaVec_cam(screenCamera, text, position_in3DWorldspace, color, size_relToViewportHeight, textDirection, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteScreenspace(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + + /// 在屏幕空间中绘制文本标签,使用视口坐标和方向向量指定位置与方向 + public static void WriteScreenspace(string text, Vector2 position_in2DViewportSpace, Color color, float size_relToViewportHeight, Vector2 textDirection, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteScreenspace") == false) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam.Add(new TextScreenspace_2Dpos_dirViaVec_cam(automaticallyFoundCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + WriteScreenspace(automaticallyFoundCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + + /// 在屏幕空间中绘制文本标签,使用指定摄像机、视口坐标和方向向量 + public static void WriteScreenspace(Camera screenCamera, string text, Vector2 position_in2DViewportSpace, Color color, float size_relToViewportHeight, Vector2 textDirection, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam.Add(new TextScreenspace_2Dpos_dirViaVec_cam(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + WriteScreenspaceFramed(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + + public static void WriteScreenspaceFramed(string text, Vector3 position_in3DWorldspace, Color color, float size_relToViewportHeight, Vector2 textDirection, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteScreenspaceFramed") == false) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam.Add(new TextScreenspaceFramed_3Dpos_dirViaVec_cam(automaticallyFoundCamera, text, position_in3DWorldspace, color, size_relToViewportHeight, textDirection, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteScreenspaceFramed(text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + public static void WriteScreenspaceFramed(Camera screenCamera, string text, Vector3 position_in3DWorldspace, Color color, float size_relToViewportHeight, Vector2 textDirection, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam.Add(new TextScreenspaceFramed_3Dpos_dirViaVec_cam(screenCamera, text, position_in3DWorldspace, color, size_relToViewportHeight, textDirection, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteScreenspaceFramed(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + + public static void WriteScreenspaceFramed(string text, Vector2 position_in2DViewportSpace, Color color, float size_relToViewportHeight, Vector2 textDirection, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteScreenspaceFramed") == false) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam.Add(new TextScreenspaceFramed_2Dpos_dirViaVec_cam(automaticallyFoundCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + WriteScreenspaceFramed(automaticallyFoundCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + public static void WriteScreenspaceFramed(Camera screenCamera, string text, Vector2 position_in2DViewportSpace, Color color, float size_relToViewportHeight, Vector2 textDirection, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(screenCamera, "screenCamera")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam.Add(new TextScreenspaceFramed_2Dpos_dirViaVec_cam(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + bool skipDraw = false; //-> The corresponding method in "TextUtilitiesDXXL" has the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + UtilitiesDXXL_Text.WriteScreenSpace(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, textDirection, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec, skipDraw); + } + + public static void WriteScreenspace(string text, Vector3 position_in3DWorldspace, Color color = default(Color), float size_relToViewportHeight = 0.025f, float zRotationDegCC = 0.0f, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteScreenspace") == false) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam.Add(new TextScreenspace_3Dpos_dirViaAngle_cam(automaticallyFoundCamera, text, position_in3DWorldspace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteScreenspace(text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + public static void WriteScreenspace(Camera screenCamera, string text, Vector3 position_in3DWorldspace, Color color = default(Color), float size_relToViewportHeight = 0.025f, float zRotationDegCC = 0.0f, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam.Add(new TextScreenspace_3Dpos_dirViaAngle_cam(screenCamera, text, position_in3DWorldspace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteScreenspace(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + + public static void WriteScreenspace(string text, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), float size_relToViewportHeight = 0.025f, float zRotationDegCC = 0.0f, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteScreenspace") == false) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam.Add(new TextScreenspace_2Dpos_dirViaAngle_cam(automaticallyFoundCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + WriteScreenspace(automaticallyFoundCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + public static void WriteScreenspace(Camera screenCamera, string text, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), float size_relToViewportHeight = 0.025f, float zRotationDegCC = 0.0f, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam.Add(new TextScreenspace_2Dpos_dirViaAngle_cam(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + WriteScreenspaceFramed(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + + public static void WriteScreenspaceFramed(string text, Vector3 position_in3DWorldspace, Color color = default(Color), float size_relToViewportHeight = 0.025f, float zRotationDegCC = 0.0f, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteScreenspaceFramed") == false) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam.Add(new TextScreenspaceFramed_3Dpos_dirViaAngle_cam(automaticallyFoundCamera, text, position_in3DWorldspace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteScreenspaceFramed(text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + public static void WriteScreenspaceFramed(Camera screenCamera, string text, Vector3 position_in3DWorldspace, Color color = default(Color), float size_relToViewportHeight = 0.025f, float zRotationDegCC = 0.0f, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam.Add(new TextScreenspaceFramed_3Dpos_dirViaAngle_cam(screenCamera, text, position_in3DWorldspace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteScreenspaceFramed(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + + public static void WriteScreenspaceFramed(string text, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), float size_relToViewportHeight = 0.025f, float zRotationDegCC = 0.0f, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteScreenspaceFramed") == false) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam.Add(new TextScreenspaceFramed_2Dpos_dirViaAngle_cam(automaticallyFoundCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + WriteScreenspaceFramed(automaticallyFoundCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec); + } + public static void WriteScreenspaceFramed(Camera screenCamera, string text, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), float size_relToViewportHeight = 0.025f, float zRotationDegCC = 0.0f, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = 0.0f, bool autoLineBreakAtViewportBorder = true, float autoLineBreakWidth_relToViewportWidth = 0.0f, bool autoFlipTextToPreventUpsideDown = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(screenCamera, "screenCamera")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam.Add(new TextScreenspaceFramed_2Dpos_dirViaAngle_cam(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec)); + return; + } + + bool skipDraw = false; //-> The corresponding method in "TextUtilitiesDXXL" has the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + UtilitiesDXXL_Text.WriteScreenspace(screenCamera, text, position_in2DViewportSpace, color, size_relToViewportHeight, zRotationDegCC, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtViewportBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec, skipDraw); + } + + public static void Write2D(string text, Vector2 position, Color color = default(Color), float size = 0.1f, Vector2 textDirection = default(Vector2), TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float custom_zPos = float.PositiveInfinity, float forceTextBlockEnlargementToThisMinWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth = 0.0f, float autoLineBreakWidth = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Write2DFramed(text, position, color, size, textDirection, textAnchor, custom_zPos, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects); + } + + public static void Write2DFramed(string text, Vector2 position, Color color = default(Color), float size = 0.1f, Vector2 textDirection = default(Vector2), TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float custom_zPos = float.PositiveInfinity, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth = 0.0f, float autoLineBreakWidth = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Text.Write2DFramed(text, position, color, size, textDirection, textAnchor, custom_zPos, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects); + } + + public static void Write2D(string text, Vector2 position, Color color, float size, float zRotationDegCC, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float custom_zPos = float.PositiveInfinity, float forceTextBlockEnlargementToThisMinWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth = 0.0f, float autoLineBreakWidth = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Write2DFramed(text, position, color, size, zRotationDegCC, textAnchor, custom_zPos, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects); + } + + public static void Write2DFramed(string text, Vector2 position, Color color, float size, float zRotationDegCC, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float custom_zPos = float.PositiveInfinity, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth = 0.0f, float autoLineBreakWidth = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Text.Write2DFramed(text, position, color, size, zRotationDegCC, textAnchor, custom_zPos, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects); + } + + public static void Write(string text, Vector3 position, Color color, float size, Quaternion rotation, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float forceTextBlockEnlargementToThisMinWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth = 0.0f, float autoLineBreakWidth = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + WriteFramed(text, position, color, size, rotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects); + } + + public static void WriteFramed(string text, Vector3 position, Color color, float size, Quaternion rotation, TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth = 0.0f, float autoLineBreakWidth = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Text.WriteFramed(text, position, color, size, rotation, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects); + } + + public static void Write(string text, Vector3 position, Color color = default(Color), float size = 0.1f, Vector3 textDirection = default(Vector3), Vector3 textUp = default(Vector3), TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, float forceTextBlockEnlargementToThisMinWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth = 0.0f, float autoLineBreakWidth = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + WriteFramed(text, position, color, size, textDirection, textUp, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects); + } + public static void WriteFramed(string text, Vector3 position, Color color = default(Color), float size = 0.1f, Vector3 textDirection = default(Vector3), Vector3 textUp = default(Vector3), TextAnchorDXXL textAnchor = TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.solid, float enclosingBox_lineWidth_relToTextSize = 0.0f, float enclosingBox_paddingSize_relToTextSize = 0.0f, float forceTextBlockEnlargementToThisMinWidth = 0.0f, float forceRestrictTextBlockSizeToThisMaxTextWidth = 0.0f, float autoLineBreakWidth = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + UtilitiesDXXL_Text.WriteFramed(text, position, color, size, textDirection, textUp, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects); + } + + public static void WriteOnCircleScreenspace(string text, Vector2 textStartPos, Vector2 circleCenterPosition, Color color = default(Color), float size_relToViewportHeight = 0.025f, TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteOnCircleScreenspace") == false) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam.Add(new TextOnCircleScreenspace_viaStartPos_cam(automaticallyFoundCamera, text, textStartPos, circleCenterPosition, color, size_relToViewportHeight, textAnchor, autoLineBreakAngleDeg, durationInSec)); + return; + } + + WriteOnCircleScreenspace(automaticallyFoundCamera, text, textStartPos, circleCenterPosition, color, size_relToViewportHeight, textAnchor, autoLineBreakAngleDeg, durationInSec); + } + + public static void WriteOnCircleScreenspace(Camera screenCamera, string text, Vector2 textStartPos, Vector2 circleCenterPosition, Color color = default(Color), float size_relToViewportHeight = 0.025f, TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textStartPos, "textStartPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenterPosition, "circleCenterPosition")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam.Add(new TextOnCircleScreenspace_viaStartPos_cam(screenCamera, text, textStartPos, circleCenterPosition, color, size_relToViewportHeight, textAnchor, autoLineBreakAngleDeg, durationInSec)); + return; + } + + Vector2 textStartPos_inWarpedViewportSpace = textStartPos; + Vector2 circleCenterPosition_inWarpedViewportSpace = circleCenterPosition; + Vector2 textsInitialUp_inWarpedViewportSpace = textStartPos_inWarpedViewportSpace - circleCenterPosition_inWarpedViewportSpace; + Vector2 textsInitialUp_inUniformSpace = DrawScreenspace.DirectionInUnitsOfWarpedSpace_to_sameLookingDirectionInUnitsOfUnwarpedSpace(textsInitialUp_inWarpedViewportSpace, screenCamera); + float radius_inUniformSpace = textsInitialUp_inUniformSpace.magnitude; + float radius_relToViewportHeight = radius_inUniformSpace; //-> this is equal, because the convention of "DrawScreenspace.DirectionInUnitsOfWarpedSpace_to_sameLookingDirectionInUnitsOfUnwarpedSpace()" is, that the screenHeight is 1 unit in the uniform space. + + bool skipDraw = false; //-> The corresponding method in "TextUtilitiesDXXL" has the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + UtilitiesDXXL_Text.WriteOnCircleScreenspace(screenCamera, text, circleCenterPosition, radius_relToViewportHeight, color, size_relToViewportHeight, textsInitialUp_inUniformSpace, textAnchor, autoLineBreakAngleDeg, durationInSec, skipDraw); + } + + public static void WriteOnCircleScreenspace(string text, Vector2 circleCenterPosition, float radius_relToViewportHeight, Color color, float size_relToViewportHeight, Vector2 textsInitialUp, TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteOnCircleScreenspace") == false) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam.Add(new TextOnCircleScreenspace_dirViaVecUp_cam(automaticallyFoundCamera, text, circleCenterPosition, radius_relToViewportHeight, color, size_relToViewportHeight, textsInitialUp, textAnchor, autoLineBreakAngleDeg, durationInSec)); + return; + } + + WriteOnCircleScreenspace(automaticallyFoundCamera, text, circleCenterPosition, radius_relToViewportHeight, color, size_relToViewportHeight, textsInitialUp, textAnchor, autoLineBreakAngleDeg, durationInSec); + } + public static void WriteOnCircleScreenspace(Camera screenCamera, string text, Vector2 circleCenterPosition, float radius_relToViewportHeight, Color color, float size_relToViewportHeight, Vector2 textsInitialUp, TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(screenCamera, "screenCamera")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam.Add(new TextOnCircleScreenspace_dirViaVecUp_cam(screenCamera, text, circleCenterPosition, radius_relToViewportHeight, color, size_relToViewportHeight, textsInitialUp, textAnchor, autoLineBreakAngleDeg, durationInSec)); + return; + } + + bool skipDraw = false; //-> The corresponding method in "TextUtilitiesDXXL" has the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + UtilitiesDXXL_Text.WriteOnCircleScreenspace(screenCamera, text, circleCenterPosition, radius_relToViewportHeight, color, size_relToViewportHeight, textsInitialUp, textAnchor, autoLineBreakAngleDeg, durationInSec, skipDraw); + } + + public static void WriteOnCircleScreenspace(string text, Vector2 circleCenterPosition, float radius_relToViewportHeight, Color color = default(Color), float size_relToViewportHeight = 0.025f, float initialTextDirection_as_zRotationDegCCfromCamUp = 0.0f, TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteOnCircleScreenspace") == false) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam.Add(new TextOnCircleScreenspace_dirViaAngle_cam(automaticallyFoundCamera, text, circleCenterPosition, radius_relToViewportHeight, color, size_relToViewportHeight, initialTextDirection_as_zRotationDegCCfromCamUp, textAnchor, autoLineBreakAngleDeg, durationInSec)); + return; + } + + WriteOnCircleScreenspace(automaticallyFoundCamera, text, circleCenterPosition, radius_relToViewportHeight, color, size_relToViewportHeight, initialTextDirection_as_zRotationDegCCfromCamUp, textAnchor, autoLineBreakAngleDeg, durationInSec); + } + public static void WriteOnCircleScreenspace(Camera screenCamera, string text, Vector2 circleCenterPosition, float radius_relToViewportHeight, Color color = default(Color), float size_relToViewportHeight = 0.025f, float initialTextDirection_as_zRotationDegCCfromCamUp = 0.0f, TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(screenCamera, "screenCamera")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam.Add(new TextOnCircleScreenspace_dirViaAngle_cam(screenCamera, text, circleCenterPosition, radius_relToViewportHeight, color, size_relToViewportHeight, initialTextDirection_as_zRotationDegCCfromCamUp, textAnchor, autoLineBreakAngleDeg, durationInSec)); + return; + } + + bool skipDraw = false; //-> The corresponding method in "TextUtilitiesDXXL" has the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + UtilitiesDXXL_Text.WriteOnCircleScreenspace(screenCamera, text, circleCenterPosition, radius_relToViewportHeight, color, size_relToViewportHeight, initialTextDirection_as_zRotationDegCCfromCamUp, textAnchor, autoLineBreakAngleDeg, durationInSec, skipDraw); + } + + public static void WriteOnCircle2D(string text, Vector2 textStartPos, Vector2 circleCenterPosition, Color color = default(Color), float size = 0.1f, float custom_zPos = float.PositiveInfinity, TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textStartPos, "textStartPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenterPosition, "circleCenterPosition")) { return; } + + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector2 textStartPosV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(textStartPos, zPos); + Vector2 circleCenterPositionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenterPosition, zPos); + + Vector3 textsInitialUp = textStartPosV3 - circleCenterPositionV3; + Vector3 textsInitialUp_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(textsInitialUp, out float radius); //-> normalizing is actually not necessary here, but is also no problem, since length/magnitude is needed for the radius anyway + Vector3 textsInitialDir = Vector3.Cross(textsInitialUp_normalized, Vector3.forward); + textsInitialDir = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(textsInitialDir); + + bool skipDraw = false; //-> The corresponding method in "TextUtilitiesDXXL" has the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + UtilitiesDXXL_Text.WriteOnCircle(text, circleCenterPosition, radius, color, size, textsInitialDir, textsInitialUp, textAnchor, autoLineBreakAngleDeg, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, skipDraw, true, false); + } + + public static void WriteOnCircle2D(string text, Vector2 circleCenterPosition, float radius, Color color, float size, Vector2 textsInitialUp, float custom_zPos = float.PositiveInfinity, TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 circleCenterPositionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenterPosition, zPos); + Vector3 textsInitialUpV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(textsInitialUp); + textsInitialUpV3 = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(textsInitialUpV3); + Vector3 textsInitialDirV3 = Vector3.Cross(textsInitialUpV3, Vector3.forward); + + bool skipDraw = false; //-> The method in "TextUtilitiesDXXL" has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + UtilitiesDXXL_Text.WriteOnCircle(text, circleCenterPositionV3, radius, color, size, textsInitialDirV3, textsInitialUpV3, textAnchor, autoLineBreakAngleDeg, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, skipDraw, true, false); + } + + public static void WriteOnCircle2D(string text, Vector2 circleCenterPosition, float radius, Color color = default(Color), float size = 0.1f, float initialTextDirection_as_zRotationDegCCfromV3Right = 0.0f, float custom_zPos = float.PositiveInfinity, TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 circleCenterPositionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(circleCenterPosition, zPos); + Quaternion rotation = UtilitiesDXXL_DrawBasics2D.QuaternionFromAngle(initialTextDirection_as_zRotationDegCCfromV3Right); + Vector3 textsInitialDirV3 = rotation * Vector3.right; + Vector3 textsInitialUpV3 = Vector3.Cross(Vector3.forward, textsInitialDirV3); + + bool skipDraw = false; //-> The method in "TextUtilitiesDXXL" has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + UtilitiesDXXL_Text.WriteOnCircle(text, circleCenterPositionV3, radius, color, size, textsInitialDirV3, textsInitialUpV3, textAnchor, autoLineBreakAngleDeg, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, skipDraw, true, true); + } + + public static void WriteOnCircle(string text, Vector3 textStartPos, Vector3 circleCenterPosition, Vector3 turnAxis_direction = default(Vector3), Color color = default(Color), float size = 0.1f, TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + UtilitiesDXXL_Text.WriteOnCircle(text, textStartPos, circleCenterPosition, turnAxis_direction, color, size, textAnchor, autoLineBreakAngleDeg, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects); + } + + public static void WriteOnCircle(string text, Vector3 circleCenterPosition, float radius, Color color = default(Color), float size = 0.1f, Quaternion orientation = default(Quaternion), TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + bool rotationIsValid = UtilitiesDXXL_TextDirAndUpCalculation.ConvertQuaternionToTextDirAndUpVectors(out Vector3 textsInitialDir, out Vector3 textsInitialUp, orientation); + bool skipDraw = false; //-> The corresponding method in "TextUtilitiesDXXL" has the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + UtilitiesDXXL_Text.WriteOnCircle(text, circleCenterPosition, radius, color, size, textsInitialDir, textsInitialUp, textAnchor, autoLineBreakAngleDeg, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, skipDraw, false, rotationIsValid); + } + + public static void WriteOnCircle(string text, Vector3 circleCenterPosition, float radius, Color color = default(Color), float size = 0.1f, Vector3 textsInitialDir = default(Vector3), Vector3 textsInitialUp = default(Vector3), TextAnchorCircledDXXL textAnchor = TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + bool skipDraw = false; //-> The corresponding method in "TextUtilitiesDXXL" has the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + UtilitiesDXXL_Text.WriteOnCircle(text, circleCenterPosition, radius, color, size, textsInitialDir, textsInitialUp, textAnchor, autoLineBreakAngleDeg, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, skipDraw, false, false); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentFromBoolArray_preAllocated = UtilitiesDXXL_DrawCollections.GetBoolAsStringFromArray; + public static void WriteArray(bool[] boolArray, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(boolArray, "boolArray")) { return; } + + string titleFallback = "Array"; + bool collectionRepresentsBools = true; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(boolArray, boolArray.Length, GetContentFromBoolArray_preAllocated, null, null, null, "bool", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArray2D(bool[] boolArray, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(boolArray, "boolArray")) { return; } + + string titleFallback = "Array"; + bool collectionRepresentsBools = true; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(boolArray, boolArray.Length, GetContentFromBoolArray_preAllocated, null, null, null, "bool", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArrayScreenspace(bool[] boolArray, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfBool_screenspace_3Dpos.Add(new ArrayOfBool_screenspace_3Dpos(boolArray, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(boolArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, bool[] boolArray, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam.Add(new ArrayOfBool_screenspace_3Dpos_cam(screenCamera, boolArray, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(screenCamera, boolArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(bool[] boolArray, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfBool_screenspace_2Dpos.Add(new ArrayOfBool_screenspace_2Dpos(boolArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + WriteArrayScreenspace(automaticallyFoundCamera, boolArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, bool[] boolArray, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(boolArray, "boolArray")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam.Add(new ArrayOfBool_screenspace_2Dpos_cam(screenCamera, boolArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "Array"; + bool collectionRepresentsBools = true; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, boolArray, boolArray.Length, GetContentFromBoolArray_preAllocated, null, null, null, "bool", null, null, null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentFromBoolList_preAllocated = UtilitiesDXXL_DrawCollections.GetBoolAsStringFromList; + public static void WriteList(List boolList, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(boolList, "boolList")) { return; } + + string titleFallback = "List"; + bool collectionRepresentsBools = true; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(boolList, boolList.Count, GetContentFromBoolList_preAllocated, null, null, null, "bool", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteList2D(List boolList, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(boolList, "boolList")) { return; } + + string titleFallback = "List"; + bool collectionRepresentsBools = true; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(boolList, boolList.Count, GetContentFromBoolList_preAllocated, null, null, null, "bool", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteListScreenspace(List boolList, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfBool_screenspace_3Dpos.Add(new ListOfBool_screenspace_3Dpos(boolList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteListScreenspace(boolList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List boolList, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfBool_screenspace_3Dpos_cam.Add(new ListOfBool_screenspace_3Dpos_cam(screenCamera, boolList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteListScreenspace(screenCamera, boolList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(List boolList, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfBool_screenspace_2Dpos.Add(new ListOfBool_screenspace_2Dpos(boolList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + WriteListScreenspace(automaticallyFoundCamera, boolList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List boolList, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(boolList, "boolList")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfBool_screenspace_2Dpos_cam.Add(new ListOfBool_screenspace_2Dpos_cam(screenCamera, boolList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "List"; + bool collectionRepresentsBools = true; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, boolList, boolList.Count, GetContentFromBoolList_preAllocated, null, null, null, "bool", null, null, null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentFromIntArray_preAllocated = UtilitiesDXXL_DrawCollections.GetIntAsStringFromArray; + public static void WriteArray(int[] intArray, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(intArray, "intArray")) { return; } + + string titleFallback = "Array"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(intArray, intArray.Length, GetContentFromIntArray_preAllocated, null, null, null, "int", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArray2D(int[] intArray, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(intArray, "intArray")) { return; } + + string titleFallback = "Array"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(intArray, intArray.Length, GetContentFromIntArray_preAllocated, null, null, null, "int", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArrayScreenspace(int[] intArray, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfInt_screenspace_3Dpos.Add(new ArrayOfInt_screenspace_3Dpos(intArray, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(intArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, int[] intArray, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam.Add(new ArrayOfInt_screenspace_3Dpos_cam(screenCamera, intArray, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(screenCamera, intArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(int[] intArray, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfInt_screenspace_2Dpos.Add(new ArrayOfInt_screenspace_2Dpos(intArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + WriteArrayScreenspace(automaticallyFoundCamera, intArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, int[] intArray, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(intArray, "intArray")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam.Add(new ArrayOfInt_screenspace_2Dpos_cam(screenCamera, intArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "Array"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, intArray, intArray.Length, GetContentFromIntArray_preAllocated, null, null, null, "int", null, null, null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentFromIntList_preAllocated = UtilitiesDXXL_DrawCollections.GetIntAsStringFromList; + public static void WriteList(List intList, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(intList, "intList")) { return; } + + string titleFallback = "List"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(intList, intList.Count, GetContentFromIntList_preAllocated, null, null, null, "int", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteList2D(List intList, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(intList, "intList")) { return; } + + string titleFallback = "List"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(intList, intList.Count, GetContentFromIntList_preAllocated, null, null, null, "int", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteListScreenspace(List intList, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfInt_screenspace_3Dpos.Add(new ListOfInt_screenspace_3Dpos(intList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteListScreenspace(intList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List intList, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfInt_screenspace_3Dpos_cam.Add(new ListOfInt_screenspace_3Dpos_cam(screenCamera, intList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteListScreenspace(screenCamera, intList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(List intList, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfInt_screenspace_2Dpos.Add(new ListOfInt_screenspace_2Dpos(intList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + WriteListScreenspace(automaticallyFoundCamera, intList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List intList, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(intList, "intList")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfInt_screenspace_2Dpos_cam.Add(new ListOfInt_screenspace_2Dpos_cam(screenCamera, intList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "List"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, intList, intList.Count, GetContentFromIntList_preAllocated, null, null, null, "int", null, null, null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentFromFloatArray_preAllocated = UtilitiesDXXL_DrawCollections.GetFloatAsStringFromArray; + public static void WriteArray(float[] floatArray, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(floatArray, "floatArray")) { return; } + + string titleFallback = "Array"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(floatArray, floatArray.Length, GetContentFromFloatArray_preAllocated, null, null, null, "float", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArray2D(float[] floatArray, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(floatArray, "floatArray")) { return; } + + string titleFallback = "Array"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(floatArray, floatArray.Length, GetContentFromFloatArray_preAllocated, null, null, null, "float", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArrayScreenspace(float[] floatArray, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfFloat_screenspace_3Dpos.Add(new ArrayOfFloat_screenspace_3Dpos(floatArray, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(floatArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, float[] floatArray, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam.Add(new ArrayOfFloat_screenspace_3Dpos_cam(screenCamera, floatArray, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(screenCamera, floatArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(float[] floatArray, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfFloat_screenspace_2Dpos.Add(new ArrayOfFloat_screenspace_2Dpos(floatArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + WriteArrayScreenspace(automaticallyFoundCamera, floatArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, float[] floatArray, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(floatArray, "floatArray")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam.Add(new ArrayOfFloat_screenspace_2Dpos_cam(screenCamera, floatArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "Array"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, floatArray, floatArray.Length, GetContentFromFloatArray_preAllocated, null, null, null, "float", null, null, null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentFromFloatList_preAllocated = UtilitiesDXXL_DrawCollections.GetFloatAsStringFromList; + public static void WriteList(List floatList, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(floatList, "floatList")) { return; } + + string titleFallback = "List"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(floatList, floatList.Count, GetContentFromFloatList_preAllocated, null, null, null, "float", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteList2D(List floatList, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(floatList, "floatList")) { return; } + + string titleFallback = "List"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(floatList, floatList.Count, GetContentFromFloatList_preAllocated, null, null, null, "float", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteListScreenspace(List floatList, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfFloat_screenspace_3Dpos.Add(new ListOfFloat_screenspace_3Dpos(floatList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteListScreenspace(floatList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List floatList, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfFloat_screenspace_3Dpos_cam.Add(new ListOfFloat_screenspace_3Dpos_cam(screenCamera, floatList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteListScreenspace(screenCamera, floatList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(List floatList, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfFloat_screenspace_2Dpos.Add(new ListOfFloat_screenspace_2Dpos(floatList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + WriteListScreenspace(automaticallyFoundCamera, floatList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List floatList, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(floatList, "floatList")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfFloat_screenspace_2Dpos_cam.Add(new ListOfFloat_screenspace_2Dpos_cam(screenCamera, floatList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "List"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, floatList, floatList.Count, GetContentFromFloatList_preAllocated, null, null, null, "float", null, null, null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentFromStringArray_preAllocated = UtilitiesDXXL_DrawCollections.GetStringFromArray; + public static void WriteArray(string[] stringArray, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(stringArray, "stringArray")) { return; } + + string titleFallback = "Array"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(stringArray, stringArray.Length, GetContentFromStringArray_preAllocated, null, null, null, "string", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArray2D(string[] stringArray, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(stringArray, "stringArray")) { return; } + + string titleFallback = "Array"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(stringArray, stringArray.Length, GetContentFromStringArray_preAllocated, null, null, null, "string", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArrayScreenspace(string[] stringArray, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfString_screenspace_3Dpos.Add(new ArrayOfString_screenspace_3Dpos(stringArray, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(stringArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, string[] stringArray, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfString_screenspace_3Dpos_cam.Add(new ArrayOfString_screenspace_3Dpos_cam(screenCamera, stringArray, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(screenCamera, stringArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(string[] stringArray, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfString_screenspace_2Dpos.Add(new ArrayOfString_screenspace_2Dpos(stringArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + WriteArrayScreenspace(automaticallyFoundCamera, stringArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, string[] stringArray, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(stringArray, "stringArray")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfString_screenspace_2Dpos_cam.Add(new ArrayOfString_screenspace_2Dpos_cam(screenCamera, stringArray, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "Array"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, stringArray, stringArray.Length, GetContentFromStringArray_preAllocated, null, null, null, "string", null, null, null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentFromStringList_preAllocated = UtilitiesDXXL_DrawCollections.GetStringFromList; + public static void WriteList(List stringList, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(stringList, "stringList")) { return; } + + string titleFallback = "List"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(stringList, stringList.Count, GetContentFromStringList_preAllocated, null, null, null, "string", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteList2D(List stringList, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(stringList, "stringList")) { return; } + + string titleFallback = "List"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(stringList, stringList.Count, GetContentFromStringList_preAllocated, null, null, null, "string", null, null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteListScreenspace(List stringList, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfString_screenspace_3Dpos.Add(new ListOfString_screenspace_3Dpos(stringList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteListScreenspace(stringList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List stringList, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfString_screenspace_3Dpos_cam.Add(new ListOfString_screenspace_3Dpos_cam(screenCamera, stringList, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteListScreenspace(screenCamera, stringList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(List stringList, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfString_screenspace_2Dpos.Add(new ListOfString_screenspace_2Dpos(stringList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + WriteListScreenspace(automaticallyFoundCamera, stringList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List stringList, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(stringList, "stringList")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfString_screenspace_2Dpos_cam.Add(new ListOfString_screenspace_2Dpos_cam(screenCamera, stringList, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "List"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, stringList, stringList.Count, GetContentFromStringList_preAllocated, null, null, null, "string", null, null, null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentXFromVector2Array_preAllocated = UtilitiesDXXL_DrawCollections.GetVector2XAsStringFromArray; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentYFromVector2Array_preAllocated = UtilitiesDXXL_DrawCollections.GetVector2YAsStringFromArray; + public static void WriteArray(Vector2[] vector2Array, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector2Array, "vector2Array")) { return; } + + string titleFallback = "Array of Vector2"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(vector2Array, vector2Array.Length, GetContentXFromVector2Array_preAllocated, GetContentYFromVector2Array_preAllocated, null, null, "X", "Y", null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArray2D(Vector2[] vector2Array, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector2Array, "vector2Array")) { return; } + + string titleFallback = "Array of Vector2"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(vector2Array, vector2Array.Length, GetContentXFromVector2Array_preAllocated, GetContentYFromVector2Array_preAllocated, null, null, "X", "Y", null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArrayScreenspace(Vector2[] vector2Array, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector2_screenspace_3Dpos.Add(new ArrayOfVector2_screenspace_3Dpos(vector2Array, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(vector2Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, Vector2[] vector2Array, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam.Add(new ArrayOfVector2_screenspace_3Dpos_cam(screenCamera, vector2Array, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(screenCamera, vector2Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Vector2[] vector2Array, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector2_screenspace_2Dpos.Add(new ArrayOfVector2_screenspace_2Dpos(vector2Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + WriteArrayScreenspace(automaticallyFoundCamera, vector2Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, Vector2[] vector2Array, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector2Array, "vector2Array")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam.Add(new ArrayOfVector2_screenspace_2Dpos_cam(screenCamera, vector2Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "Array of Vector2"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, vector2Array, vector2Array.Length, GetContentXFromVector2Array_preAllocated, GetContentYFromVector2Array_preAllocated, null, null, "X", "Y", null, null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentXFromVector2List_preAllocated = UtilitiesDXXL_DrawCollections.GetVector2XAsStringFromList; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentYFromVector2List_preAllocated = UtilitiesDXXL_DrawCollections.GetVector2YAsStringFromList; + public static void WriteList(List vector2List, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector2List, "vector2List")) { return; } + + string titleFallback = "List of Vector2"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(vector2List, vector2List.Count, GetContentXFromVector2List_preAllocated, GetContentYFromVector2List_preAllocated, null, null, "X", "Y", null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteList2D(List vector2List, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector2List, "vector2List")) { return; } + + string titleFallback = "List of Vector2"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(vector2List, vector2List.Count, GetContentXFromVector2List_preAllocated, GetContentYFromVector2List_preAllocated, null, null, "X", "Y", null, null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteListScreenspace(List vector2List, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector2_screenspace_3Dpos.Add(new ListOfVector2_screenspace_3Dpos(vector2List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteListScreenspace(vector2List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List vector2List, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector2_screenspace_3Dpos_cam.Add(new ListOfVector2_screenspace_3Dpos_cam(screenCamera, vector2List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteListScreenspace(screenCamera, vector2List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(List vector2List, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector2_screenspace_2Dpos.Add(new ListOfVector2_screenspace_2Dpos(vector2List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + WriteListScreenspace(automaticallyFoundCamera, vector2List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List vector2List, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector2List, "vector2List")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector2_screenspace_2Dpos_cam.Add(new ListOfVector2_screenspace_2Dpos_cam(screenCamera, vector2List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "List of Vector2"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, vector2List, vector2List.Count, GetContentXFromVector2List_preAllocated, GetContentYFromVector2List_preAllocated, null, null, "X", "Y", null, null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentXFromVector3Array_preAllocated = UtilitiesDXXL_DrawCollections.GetVector3XAsStringFromArray; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentYFromVector3Array_preAllocated = UtilitiesDXXL_DrawCollections.GetVector3YAsStringFromArray; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentZFromVector3Array_preAllocated = UtilitiesDXXL_DrawCollections.GetVector3ZAsStringFromArray; + public static void WriteArray(Vector3[] vector3Array, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector3Array, "vector3Array")) { return; } + + string titleFallback = "Array of Vector3"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(vector3Array, vector3Array.Length, GetContentXFromVector3Array_preAllocated, GetContentYFromVector3Array_preAllocated, GetContentZFromVector3Array_preAllocated, null, "X", "Y", "Z", null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArray2D(Vector3[] vector3Array, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector3Array, "vector3Array")) { return; } + + string titleFallback = "Array of Vector3"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(vector3Array, vector3Array.Length, GetContentXFromVector3Array_preAllocated, GetContentYFromVector3Array_preAllocated, GetContentZFromVector3Array_preAllocated, null, "X", "Y", "Z", null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArrayScreenspace(Vector3[] vector3Array, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector3_screenspace_3Dpos.Add(new ArrayOfVector3_screenspace_3Dpos(vector3Array, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(vector3Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, Vector3[] vector3Array, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam.Add(new ArrayOfVector3_screenspace_3Dpos_cam(screenCamera, vector3Array, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(screenCamera, vector3Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Vector3[] vector3Array, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector3_screenspace_2Dpos.Add(new ArrayOfVector3_screenspace_2Dpos(vector3Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + WriteArrayScreenspace(automaticallyFoundCamera, vector3Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, Vector3[] vector3Array, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector3Array, "vector3Array")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam.Add(new ArrayOfVector3_screenspace_2Dpos_cam(screenCamera, vector3Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "Array of Vector3"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, vector3Array, vector3Array.Length, GetContentXFromVector3Array_preAllocated, GetContentYFromVector3Array_preAllocated, GetContentZFromVector3Array_preAllocated, null, "X", "Y", "Z", null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentXFromVector3List_preAllocated = UtilitiesDXXL_DrawCollections.GetVector3XAsStringFromList; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentYFromVector3List_preAllocated = UtilitiesDXXL_DrawCollections.GetVector3YAsStringFromList; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentZFromVector3List_preAllocated = UtilitiesDXXL_DrawCollections.GetVector3ZAsStringFromList; + public static void WriteList(List vector3List, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector3List, "vector3List")) { return; } + + string titleFallback = "List of Vector3"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(vector3List, vector3List.Count, GetContentXFromVector3List_preAllocated, GetContentYFromVector3List_preAllocated, GetContentZFromVector3List_preAllocated, null, "X", "Y", "Z", null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteList2D(List vector3List, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector3List, "vector3List")) { return; } + + string titleFallback = "List of Vector3"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(vector3List, vector3List.Count, GetContentXFromVector3List_preAllocated, GetContentYFromVector3List_preAllocated, GetContentZFromVector3List_preAllocated, null, "X", "Y", "Z", null, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteListScreenspace(List vector3List, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector3_screenspace_3Dpos.Add(new ListOfVector3_screenspace_3Dpos(vector3List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteListScreenspace(vector3List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List vector3List, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector3_screenspace_3Dpos_cam.Add(new ListOfVector3_screenspace_3Dpos_cam(screenCamera, vector3List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteListScreenspace(screenCamera, vector3List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(List vector3List, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector3_screenspace_2Dpos.Add(new ListOfVector3_screenspace_2Dpos(vector3List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + WriteListScreenspace(automaticallyFoundCamera, vector3List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List vector3List, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector3List, "vector3List")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector3_screenspace_2Dpos_cam.Add(new ListOfVector3_screenspace_2Dpos_cam(screenCamera, vector3List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "List of Vector3"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, vector3List, vector3List.Count, GetContentXFromVector3List_preAllocated, GetContentYFromVector3List_preAllocated, GetContentZFromVector3List_preAllocated, null, "X", "Y", "Z", null, position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentXFromVector4Array_preAllocated = UtilitiesDXXL_DrawCollections.GetVector4XAsStringFromArray; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentYFromVector4Array_preAllocated = UtilitiesDXXL_DrawCollections.GetVector4YAsStringFromArray; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentZFromVector4Array_preAllocated = UtilitiesDXXL_DrawCollections.GetVector4ZAsStringFromArray; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString GetContentWFromVector4Array_preAllocated = UtilitiesDXXL_DrawCollections.GetVector4WAsStringFromArray; + public static void WriteArray(Vector4[] vector4Array, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector4Array, "vector4Array")) { return; } + + string titleFallback = "Array of Vector4"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(vector4Array, vector4Array.Length, GetContentXFromVector4Array_preAllocated, GetContentYFromVector4Array_preAllocated, GetContentZFromVector4Array_preAllocated, GetContentWFromVector4Array_preAllocated, "X", "Y", "Z", "W", position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArray2D(Vector4[] vector4Array, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector4Array, "vector4Array")) { return; } + + string titleFallback = "Array of Vector4"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(vector4Array, vector4Array.Length, GetContentXFromVector4Array_preAllocated, GetContentYFromVector4Array_preAllocated, GetContentZFromVector4Array_preAllocated, GetContentWFromVector4Array_preAllocated, "X", "Y", "Z", "W", position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteArrayScreenspace(Vector4[] vector4Array, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector4_screenspace_3Dpos.Add(new ArrayOfVector4_screenspace_3Dpos(vector4Array, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(vector4Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, Vector4[] vector4Array, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam.Add(new ArrayOfVector4_screenspace_3Dpos_cam(screenCamera, vector4Array, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteArrayScreenspace(screenCamera, vector4Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Vector4[] vector4Array, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector4_screenspace_2Dpos.Add(new ArrayOfVector4_screenspace_2Dpos(vector4Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteArrayScreenspace") == false) { return; } + WriteArrayScreenspace(automaticallyFoundCamera, vector4Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteArrayScreenspace(Camera screenCamera, Vector4[] vector4Array, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector4Array, "vector4Array")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam.Add(new ArrayOfVector4_screenspace_2Dpos_cam(screenCamera, vector4Array, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "Array of Vector4"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, vector4Array, vector4Array.Length, GetContentXFromVector4Array_preAllocated, GetContentYFromVector4Array_preAllocated, GetContentZFromVector4Array_preAllocated, GetContentWFromVector4Array_preAllocated, "X", "Y", "Z", "W", position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentXFromVector4List_preAllocated = UtilitiesDXXL_DrawCollections.GetVector4XAsStringFromList; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentYFromVector4List_preAllocated = UtilitiesDXXL_DrawCollections.GetVector4YAsStringFromList; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentZFromVector4List_preAllocated = UtilitiesDXXL_DrawCollections.GetVector4ZAsStringFromList; + static UtilitiesDXXL_DrawCollections.FlexibleGetColumnContentAtIndexAsString> GetContentWFromVector4List_preAllocated = UtilitiesDXXL_DrawCollections.GetVector4WAsStringFromList; + public static void WriteList(List vector4List, Vector3 position = default(Vector3), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, Quaternion rotation = default(Quaternion), bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector4List, "vector4List")) { return; } + + string titleFallback = "List of Vector4"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in3D(vector4List, vector4List.Count, GetContentXFromVector4List_preAllocated, GetContentYFromVector4List_preAllocated, GetContentZFromVector4List_preAllocated, GetContentWFromVector4List_preAllocated, "X", "Y", "Z", "W", position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteList2D(List vector4List, Vector2 position = default(Vector2), Color color = default(Color), string title = null, float textSize = 0.05f, float forceHeightOfWholeTableBox = 0.0f, float custom_zPos = float.PositiveInfinity, bool position_isTopLeft_notLowLeft = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector4List, "vector4List")) { return; } + + string titleFallback = "List of Vector4"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_in2D(vector4List, vector4List.Count, GetContentXFromVector4List_preAllocated, GetContentYFromVector4List_preAllocated, GetContentZFromVector4List_preAllocated, GetContentWFromVector4List_preAllocated, "X", "Y", "Z", "W", position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, color, custom_zPos, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteListScreenspace(List vector4List, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector4_screenspace_3Dpos.Add(new ListOfVector4_screenspace_3Dpos(vector4List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(automaticallyFoundCamera, position_in3DWorldspace, false); + WriteListScreenspace(vector4List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List vector4List, Vector3 position_in3DWorldspace, Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector4_screenspace_3Dpos_cam.Add(new ListOfVector4_screenspace_3Dpos_cam(screenCamera, vector4List, position_in3DWorldspace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + Vector2 position_in2DViewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(screenCamera, position_in3DWorldspace, false); + WriteListScreenspace(screenCamera, vector4List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(List vector4List, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector4_screenspace_2Dpos.Add(new ListOfVector4_screenspace_2Dpos(vector4List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawText.WriteListScreenspace") == false) { return; } + WriteListScreenspace(automaticallyFoundCamera, vector4List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec); + } + + public static void WriteListScreenspace(Camera screenCamera, List vector4List, Vector2 position_in2DViewportSpace = default(Vector2), Color color = default(Color), string title = null, float textSize_relToViewportHeight = 0.025f, float forceHeightOfWholeTableBox_relToViewportHeight = 0.0f, bool position_isTopLeft_notLowLeft = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullSystemObjects(vector4List, "vector4List")) { return; } + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ListOfVector4_screenspace_2Dpos_cam.Add(new ListOfVector4_screenspace_2Dpos_cam(screenCamera, vector4List, position_in2DViewportSpace, color, title, textSize_relToViewportHeight, forceHeightOfWholeTableBox_relToViewportHeight, position_isTopLeft_notLowLeft, durationInSec)); + return; + } + + string titleFallback = "List of Vector4"; + bool collectionRepresentsBools = false; + UtilitiesDXXL_DrawCollections.WriteCollection_inScreenspace(screenCamera, vector4List, vector4List.Count, GetContentXFromVector4List_preAllocated, GetContentYFromVector4List_preAllocated, GetContentZFromVector4List_preAllocated, GetContentWFromVector4List_preAllocated, "X", "Y", "Z", "W", position_in2DViewportSpace, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_relToViewportHeight, textSize_relToViewportHeight, color, title, titleFallback, collectionRepresentsBools, durationInSec); + } + + public static string MarkupBold(string stringToMark) + { + return UtilitiesDXXL_Text.boldStartMarkupString + stringToMark + UtilitiesDXXL_Text.boldEndMarkupString; + } + + public static string MarkupBold(int intToMark) + { + return UtilitiesDXXL_Text.boldStartMarkupString + intToMark + UtilitiesDXXL_Text.boldEndMarkupString; + } + public static string MarkupBoldEscape(string stringToMark) + { + return UtilitiesDXXL_Text.boldEndMarkupString + stringToMark + UtilitiesDXXL_Text.boldStartMarkupString; + } + + public static string MarkupBoldEscape(int intToMark) + { + return UtilitiesDXXL_Text.boldEndMarkupString + intToMark + UtilitiesDXXL_Text.boldStartMarkupString; + } + + public static string MarkupItalic(string stringToMark) + { + return UtilitiesDXXL_Text.italicStartMarkupString + stringToMark + UtilitiesDXXL_Text.italicEndMarkupString; + } + + public static string MarkupItalic(int intToMark) + { + return UtilitiesDXXL_Text.italicStartMarkupString + intToMark + UtilitiesDXXL_Text.italicEndMarkupString; + } + + public static string MarkupItalicEscape(string stringToMark) + { + return UtilitiesDXXL_Text.italicEndMarkupString + stringToMark + UtilitiesDXXL_Text.italicStartMarkupString; + } + + public static string MarkupItalicEscape(int intToMark) + { + return UtilitiesDXXL_Text.italicEndMarkupString + intToMark + UtilitiesDXXL_Text.italicStartMarkupString; + } + + public static string MarkupDeleted(string stringToMark) + { + return UtilitiesDXXL_Text.deletedStartMarkupString + stringToMark + UtilitiesDXXL_Text.deletedEndMarkupString; + } + + public static string MarkupDeleted(int intToMark) + { + return UtilitiesDXXL_Text.deletedStartMarkupString + intToMark + UtilitiesDXXL_Text.deletedEndMarkupString; + } + + public static string MarkupDeletedEscape(string stringToMark) + { + return UtilitiesDXXL_Text.deletedEndMarkupString + stringToMark + UtilitiesDXXL_Text.deletedStartMarkupString; + } + + public static string MarkupDeletedEscape(int intToMark) + { + return UtilitiesDXXL_Text.deletedEndMarkupString + intToMark + UtilitiesDXXL_Text.deletedStartMarkupString; + } + + public static string MarkupUnderlined(string stringToMark) + { + return UtilitiesDXXL_Text.underlinedStartMarkupString + stringToMark + UtilitiesDXXL_Text.underlinedEndMarkupString; + } + + public static string MarkupUnderlined(int intToMark) + { + return UtilitiesDXXL_Text.underlinedStartMarkupString + intToMark + UtilitiesDXXL_Text.underlinedEndMarkupString; + } + + public static string MarkupUnderlinedEscape(string stringToMark) + { + return UtilitiesDXXL_Text.underlinedEndMarkupString + stringToMark + UtilitiesDXXL_Text.underlinedStartMarkupString; + } + + public static string MarkupUnderlinedEscape(int intToMark) + { + return UtilitiesDXXL_Text.underlinedEndMarkupString + intToMark + UtilitiesDXXL_Text.underlinedStartMarkupString; + } + + public static string MarkupStrokeWidth(string stringToMark, int strokeWidth_asPPMofSize) + { + return UtilitiesDXXL_Text.strokeWidthStartMarkupString_preValue + strokeWidth_asPPMofSize + UtilitiesDXXL_Text.valueMarkupString_postValue + stringToMark + UtilitiesDXXL_Text.strokeWidthEndMarkupString; + } + + public static string MarkupSize(string stringToMark, float sizeScaleFactor) + { + int size_asInt = Mathf.RoundToInt(11.0f * sizeScaleFactor); + size_asInt = Mathf.Max(1, size_asInt); + return MarkupSize(stringToMark, size_asInt); + } + + public static string MarkupSize(string stringToMark, int size_relTo_11) + { + return UtilitiesDXXL_Text.sizeStartMarkupString_preValue + size_relTo_11 + UtilitiesDXXL_Text.valueMarkupString_postValue + stringToMark + UtilitiesDXXL_Text.sizeEndMarkupString; + } + + public static string MarkupColor(string stringToMark, Color color) + { + return " 0) + { + if (colorAsHexHTMLString[0] != '#') + { + colorAsHexHTMLString = "#" + colorAsHexHTMLString; + } + } + return UtilitiesDXXL_Text.colorStartMarkupString_preValue + colorAsHexHTMLString + UtilitiesDXXL_Text.valueMarkupString_postValue + stringToMark + UtilitiesDXXL_Text.colorEndMarkupString; + } + + public static string MarkupColor(string stringToMark, bool truthValueThatColorShouldIndicate) + { + if (truthValueThatColorShouldIndicate) + { + return "" + stringToMark + UtilitiesDXXL_Text.colorEndMarkupString; + } + else + { + return "" + stringToMark + UtilitiesDXXL_Text.colorEndMarkupString; + } + } + + public static string MarkupColorFromGameobjectID(string stringToMark, GameObject colorDefiningGameobject, float forceLuminance = 0.0f) + { + Color color = SeededColorGenerator.ColorOfGameobjectID(colorDefiningGameobject, forceLuminance); + return MarkupColor(stringToMark, color); + } + + public static string MarkupColorSeededRandom(string stringToMark, int seed, float alphaOfGeneratedColor = 1.0f, float forceLuminance = 0.0f) + { + Color color = SeededColorGenerator.GetRandomColorSeeded(seed, alphaOfGeneratedColor, forceLuminance); + return MarkupColor(stringToMark, color); + } + + public static string MarkupColorRainbow(string stringToMark, int seed, float alphaOfGeneratedColor = 1.0f, int colorsPerSpectrumPass = 8, float forceLuminance = 0.0f) + { + Color color = SeededColorGenerator.GetRainbowColor(seed, alphaOfGeneratedColor, colorsPerSpectrumPass, forceLuminance); + return MarkupColor(stringToMark, color); + } + + public static string MarkupColorRainbowAroundRed(string stringToMark, int seed, float alphaOfGeneratedColor = 1.0f, int colorsPerSpectrumPass = 5, bool sawToothTransition = false, float forceLuminance = 0.0f) + { + Color color = SeededColorGenerator.GetRainbowColorAroundRed(seed, alphaOfGeneratedColor, colorsPerSpectrumPass, sawToothTransition, forceLuminance); + return MarkupColor(stringToMark, color); + } + + public static string MarkupColorRainbowAroundGreen(string stringToMark, int seed, float alphaOfGeneratedColor = 1.0f, int colorsPerSpectrumPass = 4, bool sawToothTransition = false, float forceLuminance = 0.0f) + { + Color color = SeededColorGenerator.GetRainbowColorAroundGreen(seed, alphaOfGeneratedColor, colorsPerSpectrumPass, sawToothTransition, forceLuminance); + return MarkupColor(stringToMark, color); + } + + public static string MarkupColorRainbowAroundBlue(string stringToMark, int seed, float alphaOfGeneratedColor = 1.0f, int colorsPerSpectrumPass = 5, bool sawToothTransition = false, float forceLuminance = 0.0f) + { + Color color = SeededColorGenerator.GetRainbowColorAroundBlue(seed, alphaOfGeneratedColor, colorsPerSpectrumPass, sawToothTransition, forceLuminance); + return MarkupColor(stringToMark, color); + } + + public static string MarkupIcon(DrawBasics.IconType icon) + { + return UtilitiesDXXL_CharsAndIcons.GetIconAsMarkupString(icon); + } + + public static string MarkupCustomHeightEmptyLine(float vertSize_relToTextSize) + { + int sizeScaler = Mathf.RoundToInt(11.0f * vertSize_relToTextSize); + return MarkupCustomHeightEmptyLine(sizeScaler); + } + + public static string MarkupCustomHeightEmptyLine(int sizeMarkupValue) + { + return "

"; + } + + public static string MarkupBoolDisplayer(string boolName, bool boolValueToDisplay, bool saveDrawnLines = false) + { + if (saveDrawnLines) + { + if (boolValueToDisplay) + { + return boolName + ": "; + } + else + { + return boolName + ": "; + } + } + else + { + if (boolValueToDisplay) + { + return boolName + ": "; + } + else + { + return boolName + ": "; + } + } + } + + public static string MarkupBoolDisplayer(bool boolValueToDisplay, bool saveDrawnLines = false) + { + if (saveDrawnLines) + { + if (boolValueToDisplay) + { + return ""; + } + else + { + return ""; + } + } + else + { + if (boolValueToDisplay) + { + return ""; + } + else + { + return ""; + } + } + } + + public static string MarkupBoolArrow(bool boolValueToDisplay) + { + if (boolValueToDisplay) + { + return ""; //the used color here is the same as "UtilitiesDXXL_Colors.green_boolTrue" + } + else + { + return ""; //the used color here is the same as "UtilitiesDXXL_Colors.red_boolFalse" + } + } + + public static string MarkupLogSymbol(LogType logType) + { + switch (logType) + { + case LogType.Log: + return ""; + + case LogType.Warning: + return ""; + + case LogType.Error: + return ""; + + case LogType.Exception: + return ""; + + case LogType.Assert: + return ""; + + default: + Debug.LogError("logType '" + logType + "' not implemented yet"); + return ""; + } + } + + public static bool ContainsLineBreak(string textToCheckForLineBreaks) + { + int i_startOfLineBreakMarkupString = textToCheckForLineBreaks.IndexOf(UtilitiesDXXL_Text.lineBreakMarkupString, 0); + if (i_startOfLineBreakMarkupString >= 0) + { + return true; + } + + for (int i_char = 0; i_char < textToCheckForLineBreaks.Length; i_char++) + { + //unicode 10 = linefeed + //unicode 13 = carriagereturn + if (10 == (int)textToCheckForLineBreaks[i_char] || 13 == (int)textToCheckForLineBreaks[i_char]) + { + return true; + } + } + return false; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/DrawText.cs.meta b/Runtime/DrawDebugLibrary/DrawText.cs.meta new file mode 100644 index 0000000..7f98b35 --- /dev/null +++ b/Runtime/DrawDebugLibrary/DrawText.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a739add0e49bca943bdb245460ac705b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/README_DXXL_API.md.meta b/Runtime/DrawDebugLibrary/README_DXXL_API.md.meta new file mode 100644 index 0000000..c84a08e --- /dev/null +++ b/Runtime/DrawDebugLibrary/README_DXXL_API.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 692b079a590190240a0661aa88d50021 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/Resources.meta b/Runtime/DrawDebugLibrary/Resources.meta new file mode 100644 index 0000000..4d050b7 --- /dev/null +++ b/Runtime/DrawDebugLibrary/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fa9a8e77b3508be408716f961c9b8475 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines.shader b/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines.shader new file mode 100644 index 0000000..33a62c6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines.shader @@ -0,0 +1,57 @@ +//Reduced code from "Legacy Shaders/Particles/Alpha Blended Premultiply": Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) + +Shader "DrawXXL/meshLines" { +Properties { +} + +Category { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + Blend One OneMinusSrcAlpha + ColorMask RGB + Cull Off + Lighting Off +ZWrite Off + + SubShader { + Pass { + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma target 2.0 + #pragma multi_compile_particles + + #include "UnityCG.cginc" + + struct appdata_t { + float4 vertex : POSITION; + fixed4 color : COLOR; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct v2f { + float4 vertex : SV_POSITION; + fixed4 color : COLOR; + UNITY_VERTEX_OUTPUT_STEREO + }; + + v2f vert (appdata_t v) + { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); + o.color = v.color; + return o; + } + + fixed4 frag (v2f i) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + return i.color * i.color.a; + } + ENDCG + } + } +} +} diff --git a/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines.shader.meta b/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines.shader.meta new file mode 100644 index 0000000..cc28f9e --- /dev/null +++ b/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 04efaffa1a722264287fac6c8fd21f0f +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines_overlay.shader b/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines_overlay.shader new file mode 100644 index 0000000..307978b --- /dev/null +++ b/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines_overlay.shader @@ -0,0 +1,58 @@ +//Reduced code from "Legacy Shaders/Particles/Alpha Blended Premultiply": Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) + +Shader "DrawXXL/meshLines_overlay" { +Properties { +} + +Category { + Tags { "Queue"="Transparent+1" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } + Blend Off + ColorMask RGB + Cull Off + Lighting Off +ZWrite Off +ZTest Off + + SubShader { + Pass { + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma target 2.0 + #pragma multi_compile_particles + + #include "UnityCG.cginc" + + struct appdata_t { + float4 vertex : POSITION; + fixed4 color : COLOR; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct v2f { + float4 vertex : SV_POSITION; + fixed4 color : COLOR; + UNITY_VERTEX_OUTPUT_STEREO + }; + + v2f vert (appdata_t v) + { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + o.vertex = UnityObjectToClipPos(v.vertex); + o.color = v.color; + return o; + } + + fixed4 frag (v2f i) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + return i.color * i.color.a; + } + ENDCG + } + } +} +} diff --git a/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines_overlay.shader.meta b/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines_overlay.shader.meta new file mode 100644 index 0000000..d036048 --- /dev/null +++ b/Runtime/DrawDebugLibrary/Resources/DrawXXL_lines_overlay.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: da4948678567591459a20bd4a74a86c6 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/SeededColorGenerator.cs b/Runtime/DrawDebugLibrary/SeededColorGenerator.cs new file mode 100644 index 0000000..e9d26c0 --- /dev/null +++ b/Runtime/DrawDebugLibrary/SeededColorGenerator.cs @@ -0,0 +1,188 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class SeededColorGenerator + { + public static Color GetRandomColorSeeded(int seed, float alphaOfGeneratedColor = 1.0f, float forceLuminance = 0.0f) + { + //the color variation decreases when using very high seeds + return UtilitiesDXXL_Colors.Get_randomColorSeeded(seed, alphaOfGeneratedColor, forceLuminance); + } + + public static Color ColorOfGameobjectID(GameObject colorDefiningGameobject, float forceLuminance = 0.0f) + { + //the color variation decreases when using very high seeds + return GetRandomColorSeeded(colorDefiningGameobject.GetInstanceID(), 1.0f, forceLuminance); + } + + public static void DrawCatalogueOfRandomColors(int lowestDrawnSeed, int highestDrawnSeed, float forceLuminance = 0.0f, Vector3 position = default(Vector3), float durationInSec = 0.0f) + { + //draws a list of the seeded colors together with their corresponding seed number. You can use this to show a list of available seeded colors where you can choose from by filling in the corresponding number into "Get_randomColorSeeded" + //note that the color variation decreases when using very high seeds + //the number of drawn colors is restricted to 1000 for performance reasons. + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + int maxDrawnColors = 1000; + int numberOfDrawnColors = highestDrawnSeed - lowestDrawnSeed; + + if (numberOfDrawnColors > maxDrawnColors) + { + highestDrawnSeed = lowestDrawnSeed + maxDrawnColors; + Debug.Log("DrawCatalogueOfRandomSeededColors() is restricted to " + maxDrawnColors + ". Drawing of color catalogue stopped after color " + highestDrawnSeed); + } + + float textSize = 0.1f; + for (int i = lowestDrawnSeed; i < highestDrawnSeed; i++) + { + Vector3 currPos = position + new Vector3(0.0f, -textSize * (i - lowestDrawnSeed), 0.0f); + Color currColor = GetRandomColorSeeded(i, 1.0f, forceLuminance); + UtilitiesDXXL_Text.Write("" + i, currPos, currColor, textSize, Vector3.right, Vector3.up, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, false, false, false, true); + } + } + + public static Color GetRainbowColor(int seed, float alphaOfGeneratedColor = 1.0f, int colorsPerSpectrumPass = 8, float forceLuminance = 0.0f) + { + //returns a seeded color while the color moves along a rainbow spectrum for subsequent seeds. + //"colorsPerSpectrumPass" can be used adjust the colorDiffernce between each step... higher numbers mean less differnce from color to color. Minimum is 2. + //higher values of "forceLuminance" lead to less color diversity... + + return UtilitiesDXXL_Colors.GetIteratingRainbowColor(seed, alphaOfGeneratedColor, colorsPerSpectrumPass, 0.0f, 1.0f, true, forceLuminance); + } + + public static Color GetRainbowColorAroundRed(int seed, float alphaOfGeneratedColor = 1.0f, int colorsPerSpectrumPass = 5, bool sawToothTransition = false, float forceLuminance = 0.0f) + { + return UtilitiesDXXL_Colors.GetIteratingRainbowColor(seed, alphaOfGeneratedColor, colorsPerSpectrumPass, -0.14f, 0.1f, sawToothTransition, forceLuminance); + } + + public static Color GetRainbowColorAroundGreen(int seed, float alphaOfGeneratedColor = 1.0f, int colorsPerSpectrumPass = 4, bool sawToothTransition = false, float forceLuminance = 0.0f) + { + return UtilitiesDXXL_Colors.GetIteratingRainbowColor(seed, alphaOfGeneratedColor, colorsPerSpectrumPass, 0.235f, 0.44f, sawToothTransition, forceLuminance); + } + + public static Color GetRainbowColorAroundBlue(int seed, float alphaOfGeneratedColor = 1.0f, int colorsPerSpectrumPass = 5, bool sawToothTransition = false, float forceLuminance = 0.0f) + { + return UtilitiesDXXL_Colors.GetIteratingRainbowColor(seed, alphaOfGeneratedColor, colorsPerSpectrumPass, 0.535f, 0.72f, sawToothTransition, forceLuminance); + } + + public static Color GetColorFromHueAndLuminance_tunedTransitionsSpectrum(float hue, float luminance = 0.5f, float alphaOfGeneratedColor = 1.0f) + { + // is roughly HSL space, with saturation = 1 + + int colorsPerSpectrumPass = 1000000; + int colorInsideSpectrum = (int)(hue * (float)colorsPerSpectrumPass); + return UtilitiesDXXL_Colors.GetIteratingRainbowColor(colorInsideSpectrum, alphaOfGeneratedColor, colorsPerSpectrumPass, 0.0f, 1.0f, true, luminance); + } + + static ChartDrawing chartDisplaying_tunedHLColorSpace; + public static void DrawWholeHueLuminaceSpectrumOfTunedTransitionColorSpace(Vector3 position = default(Vector3), float width_ofDrawnSpectrum = 1.0f, float height_ofDrawnSpectrum = 1.0f, int drawnHueValues = 400, int drawnLuminanceValuesPerHueValue = 60, float durationInSec = 0.0f) + { + if (chartDisplaying_tunedHLColorSpace == null) + { + chartDisplaying_tunedHLColorSpace = new ChartDrawing("Color space with
tuned transitions"); + } + + chartDisplaying_tunedHLColorSpace.Position_worldspace = position; + + + width_ofDrawnSpectrum = Mathf.Max(width_ofDrawnSpectrum, 0.01f); + height_ofDrawnSpectrum = Mathf.Max(height_ofDrawnSpectrum, 0.01f); + chartDisplaying_tunedHLColorSpace.Width_inWorldSpace = width_ofDrawnSpectrum; + chartDisplaying_tunedHLColorSpace.Height_inWorldSpace = height_ofDrawnSpectrum; + drawnHueValues = Mathf.Clamp(drawnHueValues, 3, 10000); + drawnLuminanceValuesPerHueValue = Mathf.Clamp(drawnLuminanceValuesPerHueValue, 3, 10000); + + chartDisplaying_tunedHLColorSpace.xAxis.scaling = ChartAxis.Scaling.fixed_absolute; + chartDisplaying_tunedHLColorSpace.xAxis.fixedLowerEndValueOfScale = -0.05f; + chartDisplaying_tunedHLColorSpace.xAxis.fixedUpperEndValueOfScale = 1.05f; + chartDisplaying_tunedHLColorSpace.xAxis.Name = "Hue"; + chartDisplaying_tunedHLColorSpace.yAxis.scaling = ChartAxis.Scaling.fixed_absolute; + chartDisplaying_tunedHLColorSpace.yAxis.fixedLowerEndValueOfScale = -0.05f; + chartDisplaying_tunedHLColorSpace.yAxis.fixedUpperEndValueOfScale = 1.05f; + chartDisplaying_tunedHLColorSpace.yAxis.Name = "Luminance"; + + chartDisplaying_tunedHLColorSpace.Draw(durationInSec, false); + + int numberOfDrawnHues = drawnHueValues; + int numberOfDrawnLuminancesPerHue = drawnLuminanceValuesPerHueValue; + float luminanceChangePerLine = 1.0f / (float)numberOfDrawnLuminancesPerHue; + float luminanceAtCenterOfLowestLine = 0.5f * luminanceChangePerLine; + Vector2 eachLine_inChartspace = Vector2.up * luminanceChangePerLine; + for (int i_hue = 0; i_hue <= numberOfDrawnHues; i_hue++) + { + float hue_0to1 = (float)i_hue / (float)numberOfDrawnHues; + for (int i_luminanceShiftedColorInsideHue = 0; i_luminanceShiftedColorInsideHue < numberOfDrawnLuminancesPerHue; i_luminanceShiftedColorInsideHue++) + { + float luminance_0to1_atLineStart = luminanceChangePerLine * i_luminanceShiftedColorInsideHue; + float luminance_0to1_atLineCenter = luminance_0to1_atLineStart + luminanceAtCenterOfLowestLine; + Color currColor = GetColorFromHueAndLuminance_tunedTransitionsSpectrum(hue_0to1, luminance_0to1_atLineCenter); + Vector2 startPos_inChartspace = new Vector2(hue_0to1, luminance_0to1_atLineStart); + Vector3 start = chartDisplaying_tunedHLColorSpace.ChartSpace_to_WorldSpace(startPos_inChartspace); + Vector3 end = chartDisplaying_tunedHLColorSpace.ChartSpace_to_WorldSpace(startPos_inChartspace + eachLine_inChartspace); + Line_fadeableAnimSpeed.InternalDraw(start, end, currColor, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, false, false, false); + } + } + } + + public static Color ForceApproxLuminance(Color colorToForce, float targetLuminance) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(targetLuminance)) + { + //forcing disabled: + return colorToForce; + } + else + { + float targetLuminance_0to2 = targetLuminance * 2.0f; + float prevLuminance = GetLuminance(colorToForce); + prevLuminance = Mathf.Max(prevLuminance, 0.0001f); + float changeFactor = targetLuminance_0to2 / prevLuminance; + + Color forcedColor; + Vector3 forcedColor_overshooting1 = (new Vector3(colorToForce.r, colorToForce.g, colorToForce.b) * changeFactor); + float maxForcedComponent_overshooting1 = UtilitiesDXXL_Math.Max(forcedColor_overshooting1.x, forcedColor_overshooting1.y, forcedColor_overshooting1.z); + if (maxForcedComponent_overshooting1 <= 1.0f) + { + forcedColor = new Color(forcedColor_overshooting1.x, forcedColor_overshooting1.y, forcedColor_overshooting1.z, colorToForce.a); + } + else + { + Vector3 colorToForce_liftedZeros = new Vector3(Mathf.Max(colorToForce.r, 0.0001f), Mathf.Max(colorToForce.g, 0.0001f), Mathf.Max(colorToForce.b, 0.0001f)); + float xFactorForReachingForcedLevelButMax1 = Mathf.Min(1.0f, forcedColor_overshooting1.x) / colorToForce_liftedZeros.x; + float yFactorForReachingForcedLevelButMax1 = Mathf.Min(1.0f, forcedColor_overshooting1.y) / colorToForce_liftedZeros.y; + float zFactorForReachingForcedLevelButMax1 = Mathf.Min(1.0f, forcedColor_overshooting1.z) / colorToForce_liftedZeros.z; + Vector3 factorsForReachingForcedLevelButMax1 = new Vector3(xFactorForReachingForcedLevelButMax1, yFactorForReachingForcedLevelButMax1, zFactorForReachingForcedLevelButMax1); + Vector3 portionOver1_of_factors = factorsForReachingForcedLevelButMax1 - Vector3.one; + float portionOver1ofFactorForX_shrinked = portionOver1_of_factors.x * (forcedColor_overshooting1.x / maxForcedComponent_overshooting1); + float portionOver1ofFactorForY_shrinked = portionOver1_of_factors.y * (forcedColor_overshooting1.y / maxForcedComponent_overshooting1); + float portionOver1ofFactorForZ_shrinked = portionOver1_of_factors.z * (forcedColor_overshooting1.z / maxForcedComponent_overshooting1); + Vector3 portionOver1ofFactors_shrinked = new Vector3(portionOver1ofFactorForX_shrinked, portionOver1ofFactorForY_shrinked, portionOver1ofFactorForZ_shrinked); + Vector3 factorsForOriginalColor_thatShrinkButPreserveDifferences = Vector3.one + portionOver1ofFactors_shrinked; + Vector3 forcedColor_cappedToLuminanceOf1 = new Vector3(colorToForce.r * factorsForOriginalColor_thatShrinkButPreserveDifferences.x, colorToForce.g * factorsForOriginalColor_thatShrinkButPreserveDifferences.y, colorToForce.b * factorsForOriginalColor_thatShrinkButPreserveDifferences.z); + if (targetLuminance_0to2 <= 1.0f) + { + forcedColor = new Color(forcedColor_cappedToLuminanceOf1.x, forcedColor_cappedToLuminanceOf1.y, forcedColor_cappedToLuminanceOf1.z, colorToForce.a); + } + else + { + Vector3 spanTill1 = new Vector3(1.0f - forcedColor_cappedToLuminanceOf1.x, 1.0f - forcedColor_cappedToLuminanceOf1.y, 1.0f - forcedColor_cappedToLuminanceOf1.z); + float spanReduceFactor = 2.0f - targetLuminance_0to2; + spanReduceFactor = Mathf.Max(spanReduceFactor, 0.0f); + Vector3 spanTill1_reduced = spanTill1 * spanReduceFactor; + Vector3 forcedColorCapppedToLum1_thenSqueezedFurtherTo1 = new Vector3(1.0f - spanTill1_reduced.x, 1.0f - spanTill1_reduced.y, 1.0f - spanTill1_reduced.z); + forcedColor = new Color(forcedColorCapppedToLum1_thenSqueezedFurtherTo1.x, forcedColorCapppedToLum1_thenSqueezedFurtherTo1.y, forcedColorCapppedToLum1_thenSqueezedFurtherTo1.z, colorToForce.a); + } + } + return forcedColor; + } + } + + public static float GetLuminance(Color colorForWhichToGetTheLuminance) + { + return (0.22f * Mathf.Clamp01(colorForWhichToGetTheLuminance.r) + 0.68f * Mathf.Clamp01(colorForWhichToGetTheLuminance.g) + 0.1f * Mathf.Clamp01(colorForWhichToGetTheLuminance.b)); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/SeededColorGenerator.cs.meta b/Runtime/DrawDebugLibrary/SeededColorGenerator.cs.meta new file mode 100644 index 0000000..7fb91cd --- /dev/null +++ b/Runtime/DrawDebugLibrary/SeededColorGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1659f25ecdfcee49b0e7696c70eb498 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts.meta b/Runtime/DrawDebugLibrary/charts.meta new file mode 100644 index 0000000..4e543e3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8e157ccac315d034488be8895c8e3e3a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts.meta b/Runtime/DrawDebugLibrary/charts/line charts.meta new file mode 100644 index 0000000..ab8f8c8 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4c54010832fc72f4b9268b6b98d10778 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/ChartAxis.cs b/Runtime/DrawDebugLibrary/charts/line charts/ChartAxis.cs new file mode 100644 index 0000000..402e229 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/ChartAxis.cs @@ -0,0 +1,886 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class ChartAxis + { + public enum Scaling + { + dynamic_encapsulateAllValues_includingThoseOutsideOfOtherAxisDisplay, + dynamic_encapsulateAllValues_butOnlyThoseInsideOfOtherAxisDisplay, + fixed_relativeToHighestValue, + fixed_relativeToLowestValue, + fixed_relativeToMostCurrentValue, + fixed_absolute + } + + public enum SourceOfAutomaticValues + { + fixedStepForEachValueAdding, + fixedStep_followingTheManualIncrementFunction, + frameCount, + fixedTime, + fixedUnscaledTime, + realtimeSinceStartup, + time, + timeSinceLevelLoad, + unscaledTime, + editorTimeSinceStartup + } + + + public float lineWidth_relToChartHeight = 0.0f; + ChartDrawing chart_thisAxisIsPartOf; + UtilitiesDXXL_Math.Dimension cartesianDimension; + public ChartAxis theOtherAxis; + private string name = null; + public string Name + { + get { return name; } + set + { + name = value; + nameHasBeenManuallySet = true; + } + } + bool nameHasBeenManuallySet = false; + public float nameText_scaleFactor = 1.0f; + public Scaling scaling = Scaling.dynamic_encapsulateAllValues_butOnlyThoseInsideOfOtherAxisDisplay; + public SourceOfAutomaticValues sourceOfAutomaticValues = SourceOfAutomaticValues.fixedStepForEachValueAdding; + bool allXValuesCameFromAutomaticSource;//only used for x-axis //ignored for y-axis + public float fixedLowerEndValueOfScale = 0.0f; + public float fixedUpperEndValueOfScale = 100.0f; + public float fixedDisplayedSpan_belowAnchorValue = 500.0f; + public float fixedDisplayedSpan_aboveAnchorValue = 100.0f; + float fixedLowerEndValueOfScale_duringInspectionComponentPhases; + float fixedUpperEndValueOfScale_duringInspectionComponentPhases; + public int approxNumberOfGraduationIntervals = 5; //has only effect, when "graduationIntervalSource" is "axisSpanDividedByFixedNumberofIntervals", otherwise ignored. The interval number in the chart may in some cases be some more or less than this number (up to doulbe of this number), so it's just a raw specification + public int ApproxNumberOfGraduationIntervals + { + get { return approxNumberOfGraduationIntervals; } + set { approxNumberOfGraduationIntervals = Mathf.Clamp(value, 2, 10000); } + } + + public float alphaOfGraduationLinesInsideDataArea = 0.2f; //can be used to switch off or accentuate the graduation lines that extend into the data area of the chart. + public float alphaOfGraduationNotation = 1.0f; //can be used to switch off or tone down the numbers notation on the axis graduation marks. default is 1 + public bool graduationTypesetting_isManually = false; //if you set this to true, then you can use "AngleDeg_ofAxisGraduationNotationText" and "GraduationTextSize_relToAxisLength". + float used_angleDeg_ofAxisGraduationNotationText; //only used for xAxis + private float angleDeg_ofAxisGraduationNotationText = 0.0f; + public float AngleDeg_ofAxisGraduationNotationText + { + //only used for the x-axis. Ignored for the y-axis + //can be used to change the direction of the notation text at the graduation marks on the x axis. Positive angles turn the text counter clockwise, negative angles turn it clockwise. Is constrained between -90 and +90. + //has only effect, if "graduationTypesetting_isManually" has been set to "true", otherwise it's ignored + get { return angleDeg_ofAxisGraduationNotationText; } + set + { + angleDeg_ofAxisGraduationNotationText = Mathf.Clamp(value, -90.0f, 90.0f); + if (graduationTypesetting_isManually == false) + { + Debug.LogWarning("Setting 'AngleDeg_ofAxisGraduationNotationText' will only have effect if 'graduationTypesetting_isManually' is 'true' (which is not the case at the moment.)"); + } + } + } + private float graduationTextSize_relToAxisLength = 0.02f; + public float GraduationTextSize_relToAxisLength + { + //has only effect, if "graduationTypesetting_isManually" has been set to "true", otherwise it's ignored + get { return graduationTextSize_relToAxisLength; } + set + { + graduationTextSize_relToAxisLength = Mathf.Clamp(value, 0.001f, 0.3f); + if (graduationTypesetting_isManually == false) + { + Debug.LogWarning("Setting 'GraduationTextSize_relToAxisLength' will only have effect if 'graduationTypesetting_isManually' is 'true' (which is not the case at the moment.)"); + } + } + } + + private float lengthConversionFactor_fromChartScaling_toWorldScaling; + public float LengthConversionFactor_fromChartScaling_toWorldScaling + { + get { return lengthConversionFactor_fromChartScaling_toWorldScaling; } + set { Debug.LogError("Setting 'LengthConversionFactor_fromChartScaling_toWorldScaling' manually is not supported."); } + } + private float valueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace; + public float ValueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace + { + get { return valueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace; } + set { Debug.LogError("Setting 'ValueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace' manually is not supported."); } + } + + Vector3 unrotated_axisVector_normalized_inWorldSpace; + private Vector3 axisVector_inWorldSpace; + public Vector3 AxisVector_inWorldSpace + { + get { return axisVector_inWorldSpace; } + set + { + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + Debug.LogError("Setting 'xAxis.AxisVector_inWorldSpace' manually is not supported. Use 'chartDrawing.Rotation' and 'chartDrawing.Width_inWorldSpace' instead."); + } + else + { + Debug.LogError("Setting 'yAxis.AxisVector_inWorldSpace' manually is not supported. Use 'chartDrawing.Rotation' and 'chartDrawing.Height_inWorldSpace' instead."); + } + } + } + + private Vector3 axisVector_normalized_inWorldSpace; + public Vector3 AxisVector_normalized_inWorldSpace + { + get { return axisVector_normalized_inWorldSpace; } + set { Debug.LogError("Setting 'chartAxis.AxisVector_normalized_inWorldSpace' manually is not supported. Use 'chartDrawing.Rotation' instead."); } + } + + private float valueMarkingLowerEndOfTheAxis; + private float valueMarkingUpperEndOfTheAxis; + public float ValueMarkingLowerEndOfTheAxis + { + get { return valueMarkingLowerEndOfTheAxis; } + set { Debug.LogError("Setting 'valueMarkingLowerEndOfTheAxis' manually is not supported. You can use 'fixedLowerEndValueOfScale' instead (after setting 'scaling' to 'fixed_absolute')."); } + } + public float ValueMarkingUpperEndOfTheAxis + { + get { return valueMarkingUpperEndOfTheAxis; } + set { Debug.LogError("Setting 'valueMarkingUpperEndOfTheAxis' manually is not supported. You can use 'fixedUpperEndValueOfScale' instead (after setting 'scaling' to 'fixed_absolute')."); } + } + + float lowerEndOfAxisToUpperEnd_inChartUnits; + + private float length_inWorldSpace = 1.0f; + public float Length_inWorldSpace + { + get { return length_inWorldSpace; } + set + { + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + Debug.LogError("Setting 'xAxis.length_inWorldSpace' manually is not supported. You can use 'chartDrawing.Width_inWorldSpace' instead."); + } + else + { + Debug.LogError("Setting 'yAxis.length_inWorldSpace' manually is not supported. You can use 'chartDrawing.Height_inWorldSpace' instead."); + } + } + } + + List posOfGraduationMarks_inChartSpace = new List(); + List graduationMarksTexts = new List(); + public bool drawZeroPositionAsDottedLine; //default is true for the yAxis and false for the xAxis + PointOfInterest pointOfInterest_displayingTheZeroPositionLine; + PointOfInterest pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay; + + public ChartAxis(Vector3 unrotated_axisVector_normalized_inWorldSpace, ChartDrawing chart_thisAxisIsPartOf, UtilitiesDXXL_Math.Dimension cartesianDimension) + { + this.unrotated_axisVector_normalized_inWorldSpace = unrotated_axisVector_normalized_inWorldSpace; + axisVector_inWorldSpace = this.unrotated_axisVector_normalized_inWorldSpace; + axisVector_normalized_inWorldSpace = this.unrotated_axisVector_normalized_inWorldSpace; + this.chart_thisAxisIsPartOf = chart_thisAxisIsPartOf; + this.cartesianDimension = cartesianDimension; + if (this.cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + allXValuesCameFromAutomaticSource = true; + name = GetAxisNameForAutomaticSources(); + drawZeroPositionAsDottedLine = false; + } + else + { + drawZeroPositionAsDottedLine = true; + } + CreatePointsOfInterest_thatDisplaysTheZeroPositionAsDottedLine(out pointOfInterest_displayingTheZeroPositionLine, out pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay); + chart_thisAxisIsPartOf.AddPointOfInterest(pointOfInterest_displayingTheZeroPositionLine); + chart_thisAxisIsPartOf.AddPointOfInterest(pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay); + } + + public void Clear() + { + allXValuesCameFromAutomaticSource = true; + } + + public void RecalcScaling() + { + CalcMinMaxOfAxis(); + lowerEndOfAxisToUpperEnd_inChartUnits = valueMarkingUpperEndOfTheAxis - valueMarkingLowerEndOfTheAxis; + lengthConversionFactor_fromChartScaling_toWorldScaling = length_inWorldSpace / lowerEndOfAxisToUpperEnd_inChartUnits; + valueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace = valueMarkingLowerEndOfTheAxis * lengthConversionFactor_fromChartScaling_toWorldScaling; + SetIf_pointOfInterestDisplayingTheZeroPositionLine_isDisplayed(); + } + + public void Draw(InternalDXXL_Plane chartPlane, float durationInSec, bool hiddenByNearerObjects) + { + //use chartDrawing.Draw() instead. + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = chart_thisAxisIsPartOf; + float fixedConeLength_forBothAxisVectors = Get_fixedConeLength_forBothAxisVectors(); + float lineWidth_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_relToChartHeight) == false) + { + lineWidth_worldSpace = lineWidth_relToChartHeight * chart_thisAxisIsPartOf.Height_inWorldSpace; + } + + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + UtilitiesDXXL_DrawBasics.VectorFrom(chart_thisAxisIsPartOf.Position_worldspace, axisVector_inWorldSpace, chart_thisAxisIsPartOf.color, lineWidth_worldSpace, null, fixedConeLength_forBothAxisVectors, false, true, false, 0.0f, false, durationInSec, hiddenByNearerObjects, chartPlane, false, 0.0f); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + + if (chart_thisAxisIsPartOf.IsEmptyWithNoLinesToDraw == false) + { + DrawAxisGraduation(durationInSec, hiddenByNearerObjects); + DrawChartBoundaryLine_inTheStyleOfAGraduationLine(durationInSec, hiddenByNearerObjects); + } + DrawAxisName(durationInSec, hiddenByNearerObjects); + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = null; + } + + public float Get_fixedConeLength_forBothAxisVectors() + { + return (0.05f * Mathf.Max(length_inWorldSpace, theOtherAxis.length_inWorldSpace)); + } + + void CalcMinMaxOfAxis() + { + //-> lowestValue is guaranteed lower than highestValue after this function + Scaling used_scaling = (chart_thisAxisIsPartOf.chartInspector_component == null) ? scaling : Scaling.fixed_absolute; + switch (used_scaling) + { + case Scaling.dynamic_encapsulateAllValues_includingThoseOutsideOfOtherAxisDisplay: + GetAxisEndsIfAllNonHiddenValuesAreEncapsulated(out valueMarkingLowerEndOfTheAxis, out valueMarkingUpperEndOfTheAxis); + return; + case Scaling.dynamic_encapsulateAllValues_butOnlyThoseInsideOfOtherAxisDisplay: + if (theOtherAxis.HasAFixedScalingType()) + { + GetAxisEndsIfAllNonHiddenValuesInsideOtherAxisSpanAreEncapsulated(out valueMarkingLowerEndOfTheAxis, out valueMarkingUpperEndOfTheAxis); + } + else + { + GetAxisEndsIfAllNonHiddenValuesAreEncapsulated(out valueMarkingLowerEndOfTheAxis, out valueMarkingUpperEndOfTheAxis); + } + return; + case Scaling.fixed_relativeToHighestValue: + float highestValueOfAllLines = GetHighestValueOfAllLines(); + TryExpandInvalidZeroSpanBesideAnchor(); + valueMarkingLowerEndOfTheAxis = GetMinValueBesideAnchor(highestValueOfAllLines); + valueMarkingUpperEndOfTheAxis = GetMaxValueBesideAnchor(highestValueOfAllLines); + return; + case Scaling.fixed_relativeToLowestValue: + float lowestValueOfAllLines = GetLowestValueOfAllLines(); + TryExpandInvalidZeroSpanBesideAnchor(); + valueMarkingLowerEndOfTheAxis = GetMinValueBesideAnchor(lowestValueOfAllLines); + valueMarkingUpperEndOfTheAxis = GetMaxValueBesideAnchor(lowestValueOfAllLines); + return; + case Scaling.fixed_relativeToMostCurrentValue: + float mostCurrentValue = GetMostCurrentValueOfAllLines(); + TryExpandInvalidZeroSpanBesideAnchor(); + valueMarkingLowerEndOfTheAxis = GetMinValueBesideAnchor(mostCurrentValue); + valueMarkingUpperEndOfTheAxis = GetMaxValueBesideAnchor(mostCurrentValue); + return; + case Scaling.fixed_absolute: + float used_fixedLowerEndValueOfScale = (chart_thisAxisIsPartOf.chartInspector_component == null) ? fixedLowerEndValueOfScale : fixedLowerEndValueOfScale_duringInspectionComponentPhases; + float used_fixedUpperEndValueOfScale = (chart_thisAxisIsPartOf.chartInspector_component == null) ? fixedUpperEndValueOfScale : fixedUpperEndValueOfScale_duringInspectionComponentPhases; + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(used_fixedLowerEndValueOfScale, used_fixedUpperEndValueOfScale)) + { + Debug.LogWarning("Chart: Don't set 'fixedLowerEndValueOfScale' and 'fixedUpperEndValueOfScale' to the same value. Both are currently " + used_fixedLowerEndValueOfScale + ". Fallback -> automatic widening."); + float paddingAtEachSide = 1.6f; + valueMarkingLowerEndOfTheAxis = used_fixedLowerEndValueOfScale - paddingAtEachSide; + valueMarkingUpperEndOfTheAxis = used_fixedLowerEndValueOfScale + paddingAtEachSide; + } + else + { + if (used_fixedLowerEndValueOfScale < used_fixedUpperEndValueOfScale) + { + valueMarkingLowerEndOfTheAxis = used_fixedLowerEndValueOfScale; + valueMarkingUpperEndOfTheAxis = used_fixedUpperEndValueOfScale; + } + else + { + valueMarkingLowerEndOfTheAxis = used_fixedUpperEndValueOfScale; + valueMarkingUpperEndOfTheAxis = used_fixedLowerEndValueOfScale; + } + } + return; + default: + valueMarkingLowerEndOfTheAxis = 0.0f; + valueMarkingUpperEndOfTheAxis = 1.0f; + Debug.LogError("ScalingType of " + used_scaling + " not implemented."); + return; + } + } + + public bool HasAFixedScalingType() + { + //-> this function is currently only fit for cases without chart components. + //-> cases with chart components always have a fixed scaling. + + switch (scaling) + { + case Scaling.dynamic_encapsulateAllValues_includingThoseOutsideOfOtherAxisDisplay: + return false; + case Scaling.dynamic_encapsulateAllValues_butOnlyThoseInsideOfOtherAxisDisplay: + return false; + case Scaling.fixed_relativeToHighestValue: + return true; + case Scaling.fixed_relativeToLowestValue: + return true; + case Scaling.fixed_relativeToMostCurrentValue: + return true; + case Scaling.fixed_absolute: + return true; + default: + return true; + } + } + + float GetMostCurrentValueOfAllLines() + { + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + return chart_thisAxisIsPartOf.lines.GetMostCurrentXValueOfAllLines(); + } + else + { + return chart_thisAxisIsPartOf.lines.GetMostCurrentYValueOfAllLines(); + } + } + + float GetLowestValueOfAllLines() + { + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + return chart_thisAxisIsPartOf.lines.GetLowestXValueOfAllLines(); + } + else + { + return chart_thisAxisIsPartOf.lines.GetLowestYValueOfAllLines(); + } + } + + float GetHighestValueOfAllLines() + { + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + return chart_thisAxisIsPartOf.lines.GetHighestXValueOfAllLines(); + } + else + { + return chart_thisAxisIsPartOf.lines.GetHighestYValueOfAllLines(); + } + } + + float GetLowestValueOfAllLines_insideSpanOfOtherAxis() + { + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + return chart_thisAxisIsPartOf.lines.GetLowestXValueOfAllLines_insideRestricedYSpan(theOtherAxis.valueMarkingLowerEndOfTheAxis, theOtherAxis.valueMarkingUpperEndOfTheAxis); + } + else + { + return chart_thisAxisIsPartOf.lines.GetLowestYValueOfAllLines_insideRestricedXSpan(theOtherAxis.valueMarkingLowerEndOfTheAxis, theOtherAxis.valueMarkingUpperEndOfTheAxis); + } + } + + float GetHighestValueOfAllLines_insideSpanOfOtherAxis() + { + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + return chart_thisAxisIsPartOf.lines.GetHighestXValueOfAllLines_insideRestricedYSpan(theOtherAxis.valueMarkingLowerEndOfTheAxis, theOtherAxis.valueMarkingUpperEndOfTheAxis); + } + else + { + return chart_thisAxisIsPartOf.lines.GetHighestYValueOfAllLines_insideRestricedXSpan(theOtherAxis.valueMarkingLowerEndOfTheAxis, theOtherAxis.valueMarkingUpperEndOfTheAxis); + } + } + + void TryExpandInvalidZeroSpanBesideAnchor() + { + if (UtilitiesDXXL_Math.ApproximatelyZero(fixedDisplayedSpan_belowAnchorValue)) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(fixedDisplayedSpan_aboveAnchorValue)) + { + Debug.LogWarning("Chart: Don't set 'displayedSpan_belowAnchorValue' and 'displayedSpan_aboveAnchorValue' both to 0. Fallback -> automatic widening."); + float fallbackSpanForEachSide = 1.6f; + fixedDisplayedSpan_belowAnchorValue = fallbackSpanForEachSide; + fixedDisplayedSpan_aboveAnchorValue = fallbackSpanForEachSide; + } + } + } + + float GetMinValueBesideAnchor(float anchorValue) + { + return (anchorValue - Mathf.Abs(fixedDisplayedSpan_belowAnchorValue)); + } + + float GetMaxValueBesideAnchor(float anchorValue) + { + return (anchorValue + Mathf.Abs(fixedDisplayedSpan_aboveAnchorValue)); + } + + void DrawAxisGraduation(float durationInSec, bool hiddenByNearerObjects) + { + posOfGraduationMarks_inChartSpace.Clear(); + float approxGraduationInterval = lowerEndOfAxisToUpperEnd_inChartUnits / (float)approxNumberOfGraduationIntervals; + bool calculationOf_orderOfMagnitudeWasSuccesful; + float decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval = UtilitiesDXXL_Math.GetDecimalOrderOfMagnitudeAtLowerEnd(approxGraduationInterval, out float inverseOf_decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval, out calculationOf_orderOfMagnitudeWasSuccesful); + if (UtilitiesDXXL_Math.ApproximatelyZero(approxGraduationInterval) || (calculationOf_orderOfMagnitudeWasSuccesful == false)) + { + Debug.LogWarning("Chart: Failed to draw graduation marks. Approximate graduation interval: " + approxGraduationInterval); + } + else + { + float approxGraduationInterval_withShiftedDecimalSeparatorTillItsInside1toExcl10 = approxGraduationInterval * inverseOf_decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval; + float approxGraduationInterval_inside1toExcl10_roundedToInt = Mathf.Floor(approxGraduationInterval_withShiftedDecimalSeparatorTillItsInside1toExcl10); + float graduationInterval_inChartSpaceUnits = approxGraduationInterval_inside1toExcl10_roundedToInt * decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval; + + //lowest mark: + float lowEndOfAxis_butDecimalSeparatorHasBeenShiftedTheNumberOfTimesThatTheIntervalNeededTillItReached1toExcl10 = valueMarkingLowerEndOfTheAxis * inverseOf_decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval; + float lowEndOfAxis_shifted_rounded = Mathf.Floor(lowEndOfAxis_butDecimalSeparatorHasBeenShiftedTheNumberOfTimesThatTheIntervalNeededTillItReached1toExcl10); + float graduationAnchorPos_below_lowEndOfAxis = lowEndOfAxis_shifted_rounded * decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval; + int maxNumberOfGraduationMarks = approxNumberOfGraduationIntervals * 2 + 5; + for (int i = 0; i < maxNumberOfGraduationMarks; i++) + { + float currGraduationMarkPos = graduationAnchorPos_below_lowEndOfAxis + graduationInterval_inChartSpaceUnits * i; + if (currGraduationMarkPos >= valueMarkingLowerEndOfTheAxis && currGraduationMarkPos < valueMarkingUpperEndOfTheAxis) + { + //fixing values like "0.0999999999" to "0.1": + float currGraduationMarkPos_butDecimalSeparatorHasBeenShiftedTheNumberOfTimesThatTheIntervalNeededTillItReached1toExcl10 = currGraduationMarkPos * inverseOf_decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval; + float currGraduationMarkPos_shifted_rounded = Mathf.Round(currGraduationMarkPos_butDecimalSeparatorHasBeenShiftedTheNumberOfTimesThatTheIntervalNeededTillItReached1toExcl10); + decimal currGraduationMarkPos_rounded = (decimal)currGraduationMarkPos_shifted_rounded * (decimal)decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval; + posOfGraduationMarks_inChartSpace.Add((float)currGraduationMarkPos_rounded); + } + + if (currGraduationMarkPos >= valueMarkingUpperEndOfTheAxis) + { + break; + } + } + + if (posOfGraduationMarks_inChartSpace.Count > 0) + { + DrawGraduationMarks(graduationInterval_inChartSpaceUnits, durationInSec, hiddenByNearerObjects); + } + } + } + + float maxTextSize_relToGraduationInterval = 0.45f; + float graduationTextExtent_perpToAxis; + void DrawGraduationMarks(float graduationInterval_inChartSpaceUnits, float durationInSec, bool hiddenByNearerObjects) + { + float lengthOfFullAlphaGraduationLine = 0.03f * length_inWorldSpace; + Color textColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(chart_thisAxisIsPartOf.color, alphaOfGraduationNotation); + Color color_ofLowAlphaGraduationLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(chart_thisAxisIsPartOf.color, alphaOfGraduationLinesInsideDataArea); + Quaternion rotation_fromChartRotation_toSkewedText = default; + float textSize_worldSpace = 0.0f; + bool textIsDrawn = !UtilitiesDXXL_Math.ApproximatelyZero(alphaOfGraduationNotation); + float graduationInterval_inWorldSpaceUnits = graduationInterval_inChartSpaceUnits * lengthConversionFactor_fromChartScaling_toWorldScaling; + bool textDirIsSkewed_inChartsLocalSpace = false; + graduationTextExtent_perpToAxis = 0.0f; + + if (textIsDrawn) + { + if (graduationTypesetting_isManually) + { + textSize_worldSpace = graduationTextSize_relToAxisLength * length_inWorldSpace; + } + else + { + textSize_worldSpace = 0.02f * length_inWorldSpace; + } + + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.y) + { + if (graduationTypesetting_isManually == false) + { + textSize_worldSpace = Mathf.Min(textSize_worldSpace, maxTextSize_relToGraduationInterval * graduationInterval_inWorldSpaceUnits); + } + } + + int numberOfLetters_ofLongestGraduationText = 0; + graduationMarksTexts.Clear(); + for (int i = 0; i < posOfGraduationMarks_inChartSpace.Count; i++) + { + graduationMarksTexts.Add("" + posOfGraduationMarks_inChartSpace[i]); + numberOfLetters_ofLongestGraduationText = Mathf.Max(numberOfLetters_ofLongestGraduationText, graduationMarksTexts[i].Length); + } + float length_ofLongestGraduationText_worldSpace_preFinalTextSizeForce = textSize_worldSpace * numberOfLetters_ofLongestGraduationText; + graduationTextExtent_perpToAxis = length_ofLongestGraduationText_worldSpace_preFinalTextSizeForce; //used by y-axis. x-axis overwrites below + + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + if (graduationTypesetting_isManually) + { + used_angleDeg_ofAxisGraduationNotationText = angleDeg_ofAxisGraduationNotationText; + } + else + { + if (length_ofLongestGraduationText_worldSpace_preFinalTextSizeForce < (0.9f * graduationInterval_inWorldSpaceUnits)) + { + used_angleDeg_ofAxisGraduationNotationText = 0.0f; + } + else + { + if (posOfGraduationMarks_inChartSpace.Count <= 18) + { + used_angleDeg_ofAxisGraduationNotationText = -45.0f; + textSize_worldSpace = Mathf.Min(textSize_worldSpace, 0.8f * maxTextSize_relToGraduationInterval * graduationInterval_inWorldSpaceUnits); + } + else + { + used_angleDeg_ofAxisGraduationNotationText = -90.0f; + textSize_worldSpace = Mathf.Min(textSize_worldSpace, maxTextSize_relToGraduationInterval * graduationInterval_inWorldSpaceUnits); + } + } + } + + textDirIsSkewed_inChartsLocalSpace = !UtilitiesDXXL_Math.ApproximatelyZero(used_angleDeg_ofAxisGraduationNotationText); + if (textDirIsSkewed_inChartsLocalSpace) + { + rotation_fromChartRotation_toSkewedText = Quaternion.AngleAxis(used_angleDeg_ofAxisGraduationNotationText, Vector3.forward); + float length_ofLongestGraduationText_worldSpace_postFinalTextSizeForce = textSize_worldSpace * numberOfLetters_ofLongestGraduationText; + float absSine = Mathf.Sin(Mathf.Deg2Rad * Mathf.Abs(used_angleDeg_ofAxisGraduationNotationText)); + graduationTextExtent_perpToAxis = textSize_worldSpace + length_ofLongestGraduationText_worldSpace_postFinalTextSizeForce * absSine; + } + else + { + graduationTextExtent_perpToAxis = textSize_worldSpace * UtilitiesDXXL_Text.relLineDistance; + } + } + } + + for (int i = 0; i < posOfGraduationMarks_inChartSpace.Count; i++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + DrawGraduationMark(i, posOfGraduationMarks_inChartSpace[i], textIsDrawn, textSize_worldSpace, lengthOfFullAlphaGraduationLine, color_ofLowAlphaGraduationLine, textColor, textDirIsSkewed_inChartsLocalSpace, rotation_fromChartRotation_toSkewedText, durationInSec, hiddenByNearerObjects); + } + } + + + void DrawGraduationMark(int i_graduationMark, float graduationMarkPosition_chartSpace, bool textIsDrawn, float textSize_worldSpace, float lengthOfFullAlphaGraduationLine, Color color_ofLowAlphaGraduationLine, Color textColor, bool textDirIsSkewed_inChartsLocalSpace, Quaternion rotation_fromChartRotation_toSkewedText, float durationInSec, bool hiddenByNearerObjects) + { + Vector2 start_ofFullAlphaGraduationLine_chartSpace; + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + start_ofFullAlphaGraduationLine_chartSpace = new Vector2(graduationMarkPosition_chartSpace, theOtherAxis.ValueMarkingLowerEndOfTheAxis); + } + else + { + start_ofFullAlphaGraduationLine_chartSpace = new Vector2(theOtherAxis.ValueMarkingLowerEndOfTheAxis, graduationMarkPosition_chartSpace); + } + + Vector3 start_ofFullAlphaGraduationLine_worldSpace = chart_thisAxisIsPartOf.ChartSpace_to_WorldSpace(start_ofFullAlphaGraduationLine_chartSpace); + Vector3 end_ofFullAlphaGraduationLine_worldSpace = start_ofFullAlphaGraduationLine_worldSpace - lengthOfFullAlphaGraduationLine * theOtherAxis.AxisVector_normalized_inWorldSpace; + Vector3 end_ofLowAlphaGraduationLine_worldSpace = start_ofFullAlphaGraduationLine_worldSpace + theOtherAxis.axisVector_inWorldSpace; + + Line_fadeableAnimSpeed.InternalDraw(start_ofFullAlphaGraduationLine_worldSpace, end_ofFullAlphaGraduationLine_worldSpace, chart_thisAxisIsPartOf.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); + if (alphaOfGraduationLinesInsideDataArea > 0.0f) + { + Vector3 start_ofLowAlphaGraduationLine_worldSpace = start_ofFullAlphaGraduationLine_worldSpace; + Line_fadeableAnimSpeed.InternalDraw(start_ofLowAlphaGraduationLine_worldSpace, end_ofLowAlphaGraduationLine_worldSpace, color_ofLowAlphaGraduationLine, 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 (textIsDrawn) + { + DrawTextAtGraduationMark(i_graduationMark, textSize_worldSpace, textColor, textDirIsSkewed_inChartsLocalSpace, end_ofFullAlphaGraduationLine_worldSpace, rotation_fromChartRotation_toSkewedText, durationInSec, hiddenByNearerObjects); + } + } + + void DrawTextAtGraduationMark(int i_graduationMark, float textSize_worldSpace, Color textColor, bool textDirIsSkewed_inChartsLocalSpace, Vector3 end_ofFullAlphaGraduationLine_worldSpace, Quaternion rotation_fromChartRotation_toSkewedText, float durationInSec, bool hiddenByNearerObjects) + { + string notationText = graduationMarksTexts[i_graduationMark]; + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + Vector3 textPosition = end_ofFullAlphaGraduationLine_worldSpace; + Quaternion textRotation; + DrawText.TextAnchorDXXL textAnchor; + if (textDirIsSkewed_inChartsLocalSpace) + { + textRotation = chart_thisAxisIsPartOf.InternalRotation * rotation_fromChartRotation_toSkewedText; + if (used_angleDeg_ofAxisGraduationNotationText < 0.0f) + { + //clockwise rotation: + textAnchor = DrawText.TextAnchorDXXL.MiddleLeft; + } + else + { + //counter clockwise rotation: + textAnchor = DrawText.TextAnchorDXXL.MiddleRight; + } + } + else + { + textRotation = chart_thisAxisIsPartOf.InternalRotation; + textAnchor = DrawText.TextAnchorDXXL.UpperCenter; + } + UtilitiesDXXL_Text.WriteFramed(notationText, textPosition, textColor, textSize_worldSpace, textRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisAxisIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects); + } + else + { + Vector3 textPosition = end_ofFullAlphaGraduationLine_worldSpace - 0.01f * length_inWorldSpace * theOtherAxis.AxisVector_normalized_inWorldSpace; + DrawText.TextAnchorDXXL textAnchor = DrawText.TextAnchorDXXL.MiddleRight; + UtilitiesDXXL_Text.WriteFramed(notationText, textPosition, textColor, textSize_worldSpace, chart_thisAxisIsPartOf.InternalRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisAxisIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects); + } + } + + void DrawChartBoundaryLine_inTheStyleOfAGraduationLine(float durationInSec, bool hiddenByNearerObjects) + { + Color color_ofLowAlphaGraduationLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(chart_thisAxisIsPartOf.color, alphaOfGraduationLinesInsideDataArea); + Vector3 startPos_worldSpace = chart_thisAxisIsPartOf.Position_worldspace + AxisVector_inWorldSpace; + Vector3 endPos_worldSpace = startPos_worldSpace + theOtherAxis.AxisVector_inWorldSpace; + Line_fadeableAnimSpeed.InternalDraw(startPos_worldSpace, endPos_worldSpace, color_ofLowAlphaGraduationLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + void DrawAxisName(float durationInSec, bool hiddenByNearerObjects) + { + string drawnName = null; + if (nameHasBeenManuallySet) + { + drawnName = name; + } + else + { + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + if (allXValuesCameFromAutomaticSource) + { + drawnName = GetAxisNameForAutomaticSources(); + } + else + { + drawnName = "[unknown unit]"; + } + } + } + + if (drawnName != null && drawnName != "") + { + if (UtilitiesDXXL_Math.ApproximatelyZero(nameText_scaleFactor) == false) + { + Vector3 textPosition_worldSpace; + DrawText.TextAnchorDXXL textAnchor; + float autoLineBreakWidth = length_inWorldSpace; + float textSize = Mathf.Abs(nameText_scaleFactor) * 0.03f * length_inWorldSpace; + switch (cartesianDimension) + { + case UtilitiesDXXL_Math.Dimension.x: + textPosition_worldSpace = chart_thisAxisIsPartOf.Position_worldspace + 0.5f * axisVector_inWorldSpace - theOtherAxis.AxisVector_normalized_inWorldSpace * (graduationTextExtent_perpToAxis + 0.05f * length_inWorldSpace); + textAnchor = DrawText.TextAnchorDXXL.UpperCenter; + UtilitiesDXXL_Text.WriteFramed(drawnName, textPosition_worldSpace, chart_thisAxisIsPartOf.color, textSize, chart_thisAxisIsPartOf.InternalRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, chart_thisAxisIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects); + break; + case UtilitiesDXXL_Math.Dimension.y: + textPosition_worldSpace = chart_thisAxisIsPartOf.Position_worldspace + 0.5f * axisVector_inWorldSpace - theOtherAxis.AxisVector_normalized_inWorldSpace * (graduationTextExtent_perpToAxis + 0.07f * length_inWorldSpace); + textAnchor = DrawText.TextAnchorDXXL.LowerCenter; + Quaternion rotationLocalInsideChart = Quaternion.AngleAxis(90.0f, Vector3.forward); + Quaternion textRotation = chart_thisAxisIsPartOf.InternalRotation * rotationLocalInsideChart; + UtilitiesDXXL_Text.WriteFramed(drawnName, textPosition_worldSpace, chart_thisAxisIsPartOf.color, textSize, textRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, chart_thisAxisIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects); + break; + default: + break; + } + } + } + } + + string GetAxisNameForAutomaticSources() + { + switch (sourceOfAutomaticValues) + { + case SourceOfAutomaticValues.fixedStepForEachValueAdding: + return "data points"; + case SourceOfAutomaticValues.fixedStep_followingTheManualIncrementFunction: + return "manually triggered increments"; + case SourceOfAutomaticValues.frameCount: + return "frame count (Update)"; + case SourceOfAutomaticValues.fixedTime: + return "fixed time [seconds]"; + case SourceOfAutomaticValues.fixedUnscaledTime: + return "fixed unscaled time [seconds]"; + case SourceOfAutomaticValues.realtimeSinceStartup: + return "realtime since startup [seconds]"; + case SourceOfAutomaticValues.time: + return "time [seconds]"; + case SourceOfAutomaticValues.timeSinceLevelLoad: + return "time since level load [seconds]"; + case SourceOfAutomaticValues.unscaledTime: + return "unscaled time [seconds]"; + case SourceOfAutomaticValues.editorTimeSinceStartup: + return "Editor time since startup [seconds]"; + default: + return null; + } + } + + public void ReportXValueFromNonAutomaticSource() + { + allXValuesCameFromAutomaticSource = false; + } + + public void ChartUpdatesAxisDirectionVectors(Quaternion newChartRotation) + { + //Don't call this function manually. Use "chartDrawing.Rotation" and "chartDrawing.Width_inWorldSpace" and "chartDrawing.Height_inWorldSpace" instead. + axisVector_normalized_inWorldSpace = newChartRotation * unrotated_axisVector_normalized_inWorldSpace; + axisVector_inWorldSpace = axisVector_normalized_inWorldSpace * length_inWorldSpace; + } + + public void ChartUpdatesAxisLength(float newLength) + { + //Don't call this function manually. Use "chartDrawing.Width_inWorldSpace" and "chartDrawing.Height_inWorldSpace" instead. + axisVector_inWorldSpace = axisVector_normalized_inWorldSpace * newLength; + length_inWorldSpace = newLength; + } + + public bool IsInsideDisplayedSpan(float valueToCheckIfItIsInsideTheDisplayedSpan) + { + //same as in "ChartDrawing.ChartSpace_to_WorldSpace" + //if you want to check both dimensions at once you can use "chartDrawing.IsInsideDrawnChartArea" + + if (valueToCheckIfItIsInsideTheDisplayedSpan >= valueMarkingLowerEndOfTheAxis) + { + if (valueToCheckIfItIsInsideTheDisplayedSpan <= valueMarkingUpperEndOfTheAxis) + { + return true; + } + } + return false; + } + + public bool IsLowerThanDisplayedSpan(float valueToCheckIfItIsLowerThanTheDisplayedSpan) + { + //same as in "ChartDrawing.ChartSpace_to_WorldSpace" + return (valueToCheckIfItIsLowerThanTheDisplayedSpan < valueMarkingLowerEndOfTheAxis); + } + + public bool IsHigherThanDisplayedSpan(float valueToCheckIfItIsHigherThanTheDisplayedSpan) + { + //same as in "ChartDrawing.ChartSpace_to_WorldSpace" + return (valueToCheckIfItIsHigherThanTheDisplayedSpan > valueMarkingUpperEndOfTheAxis); + } + + static DrawBasics.LineStyle lineStyle_forZeroPositionMarker = DrawBasics.LineStyle.dashed; + void CreatePointsOfInterest_thatDisplaysTheZeroPositionAsDottedLine(out PointOfInterest created_pointOfInterest_displayingTheZeroPositionLine, out PointOfInterest created_pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay) + { + created_pointOfInterest_displayingTheZeroPositionLine = CreatePointOfInterest_thatDisplaysTheZeroPositionAsDottedLine(lineStyle_forZeroPositionMarker, 0.40f); + created_pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay = CreatePointOfInterest_thatDisplaysTheZeroPositionAsDottedLine(DrawBasics.LineStyle.solid, 0.15f); + } + + PointOfInterest CreatePointOfInterest_thatDisplaysTheZeroPositionAsDottedLine(DrawBasics.LineStyle lineStyle, float alpha) + { + Color color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(chart_thisAxisIsPartOf.color, alpha); + PointOfInterest created_pointOfInterest = new PointOfInterest(0.0f, 0.0f, color, chart_thisAxisIsPartOf, null, null); + created_pointOfInterest.drawTextBoxIfPointIsOutsideOfChartArea = false; + created_pointOfInterest.isDeletedOnClear = false; + created_pointOfInterest.forceColorOfParent = true; + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + created_pointOfInterest.xValue.lineStyle = lineStyle; + created_pointOfInterest.xValue.linestylePatternScaleFactor = 0.75f; + created_pointOfInterest.xValue.drawCoordinateAsText = true; + created_pointOfInterest.xValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + + created_pointOfInterest.yValue.lineStyle = DrawBasics.LineStyle.invisible; + } + else + { + created_pointOfInterest.yValue.lineStyle = lineStyle; + created_pointOfInterest.yValue.linestylePatternScaleFactor = 0.75f; + created_pointOfInterest.yValue.drawCoordinateAsText = true; + created_pointOfInterest.yValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + + created_pointOfInterest.xValue.lineStyle = DrawBasics.LineStyle.invisible; + } + return created_pointOfInterest; + } + + void SetIf_pointOfInterestDisplayingTheZeroPositionLine_isDisplayed() + { + if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x) + { + if (drawZeroPositionAsDottedLine) + { + pointOfInterest_displayingTheZeroPositionLine.xValue.lineStyle = lineStyle_forZeroPositionMarker; + pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay.xValue.lineStyle = DrawBasics.LineStyle.solid; + } + else + { + pointOfInterest_displayingTheZeroPositionLine.xValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay.xValue.lineStyle = DrawBasics.LineStyle.invisible; + } + } + else + { + if (drawZeroPositionAsDottedLine) + { + pointOfInterest_displayingTheZeroPositionLine.yValue.lineStyle = lineStyle_forZeroPositionMarker; + pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay.yValue.lineStyle = DrawBasics.LineStyle.solid; + } + else + { + pointOfInterest_displayingTheZeroPositionLine.yValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay.yValue.lineStyle = DrawBasics.LineStyle.invisible; + } + } + } + + public void SetAxisScalingDuringInspectionComponentPhases(float fixedLowerEndValueOfScale, float fixedUpperEndValueOfScale) + { + if (UtilitiesDXXL_Math.FloatIsValid(fixedLowerEndValueOfScale)) + { + fixedLowerEndValueOfScale_duringInspectionComponentPhases = fixedLowerEndValueOfScale; + } + else + { + fixedLowerEndValueOfScale_duringInspectionComponentPhases = -100.0f; + } + + if (UtilitiesDXXL_Math.FloatIsValid(fixedUpperEndValueOfScale)) + { + fixedUpperEndValueOfScale_duringInspectionComponentPhases = fixedUpperEndValueOfScale; + } + else + { + fixedUpperEndValueOfScale_duringInspectionComponentPhases = 100.0f; + } + + RecalcScaling(); + } + + public void GetAxisEndsIfAllNonHiddenValuesAreEncapsulated(out float lowEnd, out float upperEnd) + { + float lowestValueOfAllLines = GetLowestValueOfAllLines(); + float highestValueOfAllLines = GetHighestValueOfAllLines(); + GetAxisEndsIfAllValuesAreEncapsulated_inclPadding(out lowEnd, out upperEnd, lowestValueOfAllLines, highestValueOfAllLines); + } + + public void GetAxisEndsIfAllNonHiddenValuesInsideOtherAxisSpanAreEncapsulated(out float lowEnd, out float upperEnd) + { + float lowestValueOfAllLines_insideSpanOfOtherAxis = GetLowestValueOfAllLines_insideSpanOfOtherAxis(); + float highestValueOfAllLines_insideSpanOfOtherAxis = GetHighestValueOfAllLines_insideSpanOfOtherAxis(); + + if (float.IsInfinity(lowestValueOfAllLines_insideSpanOfOtherAxis) || float.IsInfinity(highestValueOfAllLines_insideSpanOfOtherAxis)) + { + //-> no value has been found inside the restricted axis span: + lowestValueOfAllLines_insideSpanOfOtherAxis = 0.0f; + highestValueOfAllLines_insideSpanOfOtherAxis = 0.0f; + } + + GetAxisEndsIfAllValuesAreEncapsulated_inclPadding(out lowEnd, out upperEnd, lowestValueOfAllLines_insideSpanOfOtherAxis, highestValueOfAllLines_insideSpanOfOtherAxis); + } + + public void GetAxisEndsIfAllValuesAreEncapsulated_inclPadding(out float lowEnd, out float upperEnd, float lowestDisplayedValue, float highestDisplayedValue) + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(lowestDisplayedValue, highestDisplayedValue)) + { + float paddingAtEachSide = 1.6f; + lowEnd = lowestDisplayedValue - paddingAtEachSide; + upperEnd = lowestDisplayedValue + paddingAtEachSide; + } + else + { + float span_fromLowestToHighest = highestDisplayedValue - lowestDisplayedValue; + float additionalPadding_atEachside = span_fromLowestToHighest * 0.05f; + lowEnd = lowestDisplayedValue - additionalPadding_atEachside; + upperEnd = highestDisplayedValue + additionalPadding_atEachside; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/ChartAxis.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/ChartAxis.cs.meta new file mode 100644 index 0000000..fd1d073 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/ChartAxis.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c2ce6ec8d412c824d99e259a4e207f39 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/ChartDrawing.cs b/Runtime/DrawDebugLibrary/charts/line charts/ChartDrawing.cs new file mode 100644 index 0000000..45241fc --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/ChartDrawing.cs @@ -0,0 +1,1247 @@ +namespace DrawXXL +{ + using System.Collections.Generic; + using UnityEngine; + + public class ChartDrawing + { + //taking chart data point values from edit mode to play mode #1: + //-> Theoretically it is possible by making the chart and all dependent classes serializable + //-> Though a test resulted in Unity to endlessly compile and finally crash + //-> The reason might be that the serialization system reaches it's limits. There are many lists, and lists of custom classes that again hold lists, and even lists of lists to be serialized, and the contained classes hold references back to the containing classes. Unitys own documentation on the serialization system says: "avoid nested structures and cross references" + //-> The mistake during trying this the last time could have been, that the contained sub-classes like "ChartLine" (and many others) hold a reference back to "chart_thisLineIsPartOf". This field has been tried to be serialized with "[SerializeField]". Does this acutually create endless loops, because the lines are (with intermediate steps) also serialized as members inside "ChartDrawing"? Instead "[SerializeReference]" could have been tried, or probalbly even better an approach as "BezierSplineDrawer" uses it (see notes at "BezierSplineDrawer.cs/listOfControlPointTriplets"), though it may be easier there, because a MonoBehaviour is available there. + + //"Taking values from Edit Mode to Play Mode" #2: + //-> The static charts in the "DrawCharts" class by default reset when you enter playmode, so the charts start empty without any values. In some cases it may be desired to skip this deletion and instead take data values from Edit Mode to Play Mode. You can do so by disabling Domain Reload (see Unity documentation). Though this works only for static charts (like the premade ones in the "DrawCharts" class). It doesn't work for Transform Charts. And it is not possible the other way round: You cannot take values from Playmode back to Edit Mode. + //-> Moreover there is the other case where you want to disable Domain Reload for some other reason but still want a cleared empty chart when you enter Playmode. In such cases you have to manually clear the charts (e.g. in the "Start()" function of a MonoBehaviour) by using the "Clear()" functions of the charts. + + public enum RotationSource + { + screen, + screen_butVerticalInWorldSpace, + userDefinedFixedRotation + } + + public RotationSource rotationSource = RotationSource.screen; + + public Quaternion fixedRotation = Quaternion.identity; + private Quaternion internalRotation = Quaternion.identity; //not documented. Users should use "fixedRotation" + public Quaternion InternalRotation + { + //This is the internally used rotation. "fixedRotation" does nothing but getting filled into this before drawing if "rotationSource=userDefinedFixedRotation" + get { return internalRotation; } + set + { + internalRotation = value; + chartPlane = new InternalDXXL_Plane(Position_worldspace, internalRotation * Vector3.forward); + xAxis.ChartUpdatesAxisDirectionVectors(internalRotation); + yAxis.ChartUpdatesAxisDirectionVectors(internalRotation); + } + } + + private Vector3 position_worldspace = Vector3.zero; + public Vector3 Position_worldspace + { + get + { + if (internal_indexNumberOfPremadeChart == (-1)) + { + return position_worldspace; + } + else + { + return DrawCharts.GetAutoLayoutedPositionOfPremadeLineChart(internal_indexNumberOfPremadeChart); + } + } + set + { + position_worldspace = value; + internal_indexNumberOfPremadeChart = -1; //-> if a user sets the position, then the chart is not affected anymore by the automatic layouting of the premade charts. + } + } + + static float minChartSize = 0.01f; + public float Width_inWorldSpace + { + get { return xAxis.Length_inWorldSpace; } + set { xAxis.ChartUpdatesAxisLength(Mathf.Max(minChartSize, value)); } + } + + public float Height_inWorldSpace + { + get { return yAxis.Length_inWorldSpace; } + set { yAxis.ChartUpdatesAxisLength(Mathf.Max(minChartSize, value)); } + } + + static Vector2 default_position_inCamViewportspace = new Vector2(0.15f, 0.2f); + public Vector2 position_inCamViewportspace = default_position_inCamViewportspace; + private float width_relToCamViewport = 0.7f; + public float Width_relToCamViewport + { + get { return width_relToCamViewport; } + set { width_relToCamViewport = Mathf.Clamp(value, 0.01f, 10.0f); } + } + + private float height_relToCamViewportHeight = 0.6f; + public float Height_relToCamViewportHeight + { + get { return height_relToCamViewportHeight; } + set { height_relToCamViewportHeight = Mathf.Clamp(value, 0.01f, 10.0f); } + } + + public ChartAxis xAxis; + public ChartAxis yAxis; + public ChartLines lines; + public string name = null; + public Color color = DrawBasics.defaultColor; + public bool drawValuesOutsideOfChartArea = false; + + public float LuminanceOfLineColors + { + get { return lines.LuminanceOfLineColors; } + set { lines.LuminanceOfLineColors = value; } + } + + public ChartLine.LineConnectionsType default_lineConnectionsType = ChartLine.LineConnectionsType.straightFromPointToPoint; //is also set by "Set_lineConnectionsType"(link), but there it gets changed also for existing lines. + public ChartLine.DataPointVisualization default_dataPointVisualization = ChartLine.DataPointVisualization.invisible;//is also set by "Set_dataPointVisualization"(link), but there it gets changed also for existing lines. + public ChartLine.NamePosition default_lineNamePosition = ChartLine.NamePosition.dynamicallyMoving_atLineEnd_towardsRight;//is also set by "SetLineNamesPositions"(link), but there it gets changed also for existing lines. + public float default_lineNameText_sizeScaleFactor = 1.0f;//is also set by "SetLineNamesSize"(link), but there it gets changed also for existing lines. + public float default_alpha_ofHighlighterForMostCurrentValue_xDim = 0.3f;//is also set by "Set_alpha_ofHighlighterForMostCurrentValue_xDim"(link), but there it gets changed also for existing lines. + public float default_alpha_ofHighlighterForMostCurrentValue_yDim = 0.3f;//is also set by "Set_alpha_ofHighlighterForMostCurrentValue_yDim"(link), but there it gets changed also for existing lines. + public bool default_displayDeltaAtHighlighterForMostCurrentValue = true;//is also set by "Set_displayDeltaAtHighlighterForMostCurrentValue"(link), but there it gets changed also for existing lines. + public float default_alpha_ofMaxiumumYValueMarker = 0.3f;//is also set by "Set_alpha_ofMaxiumumYValueMarker"(link), but there it gets changed also for existing lines. + public float default_alpha_ofMinimumYValueMarker = 0.3f;//is also set by "Set_alpha_ofMinimumYValueMarker"(link), but there it gets changed also for existing lines. + public bool default_markAllYMaximumTurningPoints = false;//is also set by "Set_markAllYMaximumTurningPoints"(link), but there it gets changed also for existing lines. + public bool default_markAllYMinimumTurningPoints = false;//is also set by "Set_markAllYMinimumTurningPoints"(link), but there it gets changed also for existing lines. + public float default_alpha_ofVerticalAreaFillLines = 0.0f;//is also set by "Set_alpha_ofVerticalAreaFillLines"(link), but there it gets changed also for existing lines. + public float default_SizeOfPoints_relToChartHeight = 0.02f;//is also set by "Set_SizeOfPoints_relToChartHeight"(link), but there it gets changed also for existing lines. + public float default_lineWidth_relToChartHeight = 0.0f;//is also set by "Set_lineWidth_relToChartHeight"(link), but there it gets changed also for existing lines. + public float default_pointVisualisationLineWidth_relToChartHeight = 0.0f;//is also set by "Set_pointVisualisationLineWidth_relToChartHeight"(link), but there it gets changed also for existing lines. + public bool autoFlipAllText_toFitObsererCamera = true; + + public int internal_indexNumberOfPremadeChart = -1; //-> this is used internally for the automatic layout of the premade chart, whose position hasn't been explicitly set by the user. + +#if UNITY_EDITOR + bool theMostCurrentChartDrawing_hasBeenMadeInScreenspace = false; +#endif + Camera cameraUsedByMostCurrentScreenspaceDrawing; + bool theMostCurrentScreenspaceDrawing_definedChartWidth_relToCamWidth = true; + bool theMostCurrentChartDrawing_wasDrawnWithConfigOf_hiddenByNearerObjects = true; + + public DataComponentsThatAreDrawn dataComponentsThatAreDrawn = new DataComponentsThatAreDrawn(); + public bool displayHighlightingOfMostCurrentValues_forLinesFromLists = false; + private bool isEmptyWithNoLinesToDraw; + public bool IsEmptyWithNoLinesToDraw + { + get { return isEmptyWithNoLinesToDraw; } + set { Debug.LogError("Setting 'IsEmptyWithNoLinesToDraw' manually is not supported."); } + } + + private float scaleFactor_forChartNameTextSize = 1.0f; + public float ScaleFactor_forChartNameTextSize + { + get { return scaleFactor_forChartNameTextSize; } + set { scaleFactor_forChartNameTextSize = Mathf.Max(value, 0.02f); } + } + + /// other: + public InternalDXXL_Plane chartPlane = new InternalDXXL_Plane(Vector3.zero, Vector3.forward); + Vector3 posOfOriginOfChartSpace_inWorldSpace; + int xPos_currentManualIncrementValue = 0; + List pointsOfInterest = new List(); + PointOfInterest pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide; + public PointOfInterest pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide; + + private int maxDisplayedPointOfInterestTextBoxesPerSide = 6; + public int MaxDisplayedPointOfInterestTextBoxesPerSide // Some points of interest display a text box with explantion text in the top corners of the chart. In some unforeseen situation, for example if many invalid float values are added as data points, the number of text boxes that notify you of these invalid float values can rapidly grow and as a result slow down the Editor performance. Therefore "MaxDisplayedPointOfInterestTextBoxesPerSide" limits the number of displayed text boxes. If there are more text boxes then one additional text box is displayed which communicates how many text boxes are hidden. + { + get { return maxDisplayedPointOfInterestTextBoxesPerSide; } + set { maxDisplayedPointOfInterestTextBoxesPerSide = Mathf.Max(0, value); } + } + InternalDXXL_ChartToCSVfileWriter chartToCSVfileWriter; + public float overallMinXValue_includingHiddenLines; //not contained in docs //see also "lines.GetLowestXValueOfAllLines()", which is similar, but ignores hidden lines + public float overallMaxXValue_includingHiddenLines; //not contained in docs //see also "lines.GetHighestXValueOfAllLines()", which is similar, but ignores hidden lines + public float overallMinYValue_includingHiddenLines; //not contained in docs //see also "lines.GetLowestYValueOfAllLines()", which is similar, but ignores hidden lines + public float overallMaxYValue_includingHiddenLines; //not contained in docs //see also "lines.GetHighestYValueOfAllLines()", which is similar, but ignores hidden lines + + public bool drawRGBColorUnderlayForColorGraphs = true; //The alpha value may be displayed to high because adjacent color lines overlay each other. + + + public ChartDrawing(string chartName = null) + { + name = chartName; + + xAxis = new ChartAxis(Vector3.right, this, UtilitiesDXXL_Math.Dimension.x); + yAxis = new ChartAxis(Vector3.up, this, UtilitiesDXXL_Math.Dimension.y); + xAxis.theOtherAxis = yAxis; + yAxis.theOtherAxis = xAxis; + ResetOverallMinMaxValues(); + lines = new ChartLines(this); + Create_pointsOfInterest_thatCommunicateTheHiddenPointsOfInterest(); + } + + public void Clear() + { + lines.Clear(); + xPos_currentManualIncrementValue = 0; + xAxis.Clear(); + yAxis.Clear(); + ResetOverallMinMaxValues(); + DeletePointsOfInterestOnClear(); + } + + public void Draw(float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //is ignored as long as a chart inspection gameobject (created via "CreateChartInspectionGameobject()") exists, because the chart inspection component will then take care of the chart drawing by itself. + if (chartInspector_component == null) + { + Internal_Draw(durationInSec, hiddenByNearerObjects); + } + } + + public void Internal_Draw(float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = this; + + ApplyInternalRotation(); //-> "DXXLWrapperForUntiyDebugDraw.CheckIfDrawingIsCurrentlySkipped" uses the here applied rotation already in it's fallback + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + DrawChartName(durationInSec, hiddenByNearerObjects); + isEmptyWithNoLinesToDraw = !lines.HasAtLeastOneDrawnLineWithAtLeastOneValidValue(); + TryDrawFallbackForEmptyChart(durationInSec, hiddenByNearerObjects); + RecalcAxisScaling(); + Vector3 chartAnchorPositionInWorldSpace_shiftedAlongChartsXAxis_toOriginOfChartSpace = Position_worldspace - xAxis.AxisVector_normalized_inWorldSpace * xAxis.ValueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace; + posOfOriginOfChartSpace_inWorldSpace = chartAnchorPositionInWorldSpace_shiftedAlongChartsXAxis_toOriginOfChartSpace - yAxis.AxisVector_normalized_inWorldSpace * yAxis.ValueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace; + xAxis.Draw(chartPlane, durationInSec, hiddenByNearerObjects); + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = this; + yAxis.Draw(chartPlane, durationInSec, hiddenByNearerObjects); + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = this; + TryDrawRGBColorUnderlay(xAxis.ValueMarkingLowerEndOfTheAxis, xAxis.ValueMarkingUpperEndOfTheAxis, yAxis.ValueMarkingLowerEndOfTheAxis, yAxis.ValueMarkingUpperEndOfTheAxis, durationInSec, hiddenByNearerObjects); + lines.Draw(chartPlane, durationInSec, hiddenByNearerObjects); + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = this; + DrawPointsOfInterest(durationInSec, hiddenByNearerObjects); + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = null; +#if UNITY_EDITOR + theMostCurrentChartDrawing_hasBeenMadeInScreenspace = false; +#endif + theMostCurrentChartDrawing_wasDrawnWithConfigOf_hiddenByNearerObjects = hiddenByNearerObjects; + } + + public void DrawScreenspace(bool chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight = true, float durationInSec = 0.0f) + { + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "ChartDrawing.DrawScreenspace") == false) { return; } + DrawScreenspace(automaticallyFoundCamera, chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, durationInSec); + } + + public void DrawScreenspace(Camera targetCamera, bool chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + bool skipScreenspaceSheduling_dueTo_isFirstDrawOfScreenspaceDrawing = Get_skipScreenspaceSheduling_dueTo_isFirstDrawOfScreenspaceDrawing(); + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem && (skipScreenspaceSheduling_dueTo_isFirstDrawOfScreenspaceDrawing == false)) + { + DrawXXL_LinesManager.instance.listOfSheduled_DrawScreenspaceChart.Add(new DrawScreenspaceChart(targetCamera, chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, durationInSec, this)); + return; + } + + if (chartInspector_component == null) + { + Internal_DrawScreenspace(targetCamera, chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, durationInSec); + } + } + + bool Get_skipScreenspaceSheduling_dueTo_isFirstDrawOfScreenspaceDrawing() + { +#if UNITY_EDITOR + //This is for this case: + //-> After a call to "DrawScreenspace()" "CreateChartInspectionGameobject()" is called, which expects a correctly set "theMostCurrentChartDrawing_hasBeenMadeInScreenspace". + //-> The delay from "noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem" prevents "theMostCurrentChartDrawing_hasBeenMadeInScreenspace" (and other fields) from beeing correctly set for the chartInspectorComponent. + //This hack could lead to problems in this case: + //-> Multiple charts are drawn to the scene - some in screenspace and some in worldspace. + //-> The "theMostCurrentChartDrawing_hasBeenMadeInScreenspace" would toggle to and from all the time. + //-> Expected negative side effect: Screenspace charts could ongoingly be drawn with a spacial delay to moving cameras.. + return (theMostCurrentChartDrawing_hasBeenMadeInScreenspace == false); +#else + return false; +#endif + } + + public void Internal_DrawScreenspace(Camera targetCamera, bool chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + + cameraUsedByMostCurrentScreenspaceDrawing = targetCamera; + theMostCurrentScreenspaceDrawing_definedChartWidth_relToCamWidth = chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight; + + Vector3 chartPosition_beforeScreenspaceDrawing = Position_worldspace; + Quaternion fixedChartRotation_beforeScreenspaceDrawing = fixedRotation; + float chartWidthWorldspace_beforeScreenspaceDrawing = Width_inWorldSpace; + float chartHeigthWorldspace_beforeScreenspaceDrawing = Height_inWorldSpace; + RotationSource rotationSource_beforeScreenspaceDrawing = rotationSource; + autoFlipAllText_toFitObsererCamera = false; + + try + { + UtilitiesDXXL_ChartDrawing.SetPosRotScaleOfChart_toScreenspace(this, targetCamera, chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, false); + Internal_Draw(durationInSec, false); + } + catch { } + + Position_worldspace = chartPosition_beforeScreenspaceDrawing; + fixedRotation = fixedChartRotation_beforeScreenspaceDrawing; + Width_inWorldSpace = chartWidthWorldspace_beforeScreenspaceDrawing; + Height_inWorldSpace = chartHeigthWorldspace_beforeScreenspaceDrawing; + rotationSource = rotationSource_beforeScreenspaceDrawing; + autoFlipAllText_toFitObsererCamera = true; +#if UNITY_EDITOR + theMostCurrentChartDrawing_hasBeenMadeInScreenspace = true; +#endif + } + + public void ApplyInternalRotation() + { + Vector3 observerCamForward_normalized; + Vector3 observerCamUp_normalized; + Vector3 observerCamRight_normalized; + Vector3 cam_to_lineCenter; + + switch (rotationSource) + { + case RotationSource.screen: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, Position_worldspace, Vector3.zero, null); + InternalRotation = Quaternion.LookRotation(observerCamForward_normalized, observerCamUp_normalized); + break; + case RotationSource.screen_butVerticalInWorldSpace: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, Position_worldspace, Vector3.zero, null); + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.GetUpAndTextDir_withoutCallerSpecifiedPreference_independentFromTooShortLineDir_alignedVertical(out Vector3 chartUp_normalized, out Vector3 chartRight_normalized, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + Vector3 chartForward_normalized = Vector3.Cross(chartRight_normalized, chartUp_normalized); + InternalRotation = Quaternion.LookRotation(chartForward_normalized, chartUp_normalized); + break; + case RotationSource.userDefinedFixedRotation: + InternalRotation = fixedRotation; + break; + default: + InternalRotation = fixedRotation; + Debug.LogError("rotationSource of '" + rotationSource + "' not implemented."); + break; + } + } + + void RecalcAxisScaling() + { + //-> this order flipping should only concern cases where one axis has "dynamic_encapsulateAllValues_butOnlyThoseInsideOfOtherAxisDisplay" scaling and the other axis has a fixed scaling type, because "dynamic_encapsulateAllValues_butOnlyThoseInsideOfOtherAxisDisplay" needs the axis ends of the fixed axis and therefore depends on being called afterwards. + //-> for other cases it shouldn't make any difference + + if (xAxis.HasAFixedScalingType()) + { + xAxis.RecalcScaling(); + yAxis.RecalcScaling(); + } + else + { + yAxis.RecalcScaling(); + xAxis.RecalcScaling(); + } + } + + public void AddValue(float yValueOfNewDataPoint, string nameOfReceivingLine) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.GetUsermadeLine(nameOfReceivingLine, true).AddValue(yValueOfNewDataPoint); + } + } + + public void AddValue(float yValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_float.AddValue(yValueOfNewDataPoint); + } + } + + public void AddValue(int yValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_int.AddValue((float)yValueOfNewDataPoint); + } + } + + public void AddValue(Vector2 yValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_vector2_x.AddValue(yValueOfNewDataPoint.x); + lines.premadeLine_vector2_y.AddValue(yValueOfNewDataPoint.y); + } + } + + public void AddValue(Vector3 yValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_vector3_x.AddValue(yValueOfNewDataPoint.x); + lines.premadeLine_vector3_y.AddValue(yValueOfNewDataPoint.y); + lines.premadeLine_vector3_z.AddValue(yValueOfNewDataPoint.z); + } + } + + public void AddValue(Vector4 yValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_vector4_x.AddValue(yValueOfNewDataPoint.x); + lines.premadeLine_vector4_y.AddValue(yValueOfNewDataPoint.y); + lines.premadeLine_vector4_z.AddValue(yValueOfNewDataPoint.z); + lines.premadeLine_vector4_w.AddValue(yValueOfNewDataPoint.w); + } + } + + public void AddValue(Color yValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_color_r.AddValue(yValueOfNewDataPoint.r); + lines.premadeLine_color_g.AddValue(yValueOfNewDataPoint.g); + lines.premadeLine_color_b.AddValue(yValueOfNewDataPoint.b); + lines.premadeLine_color_a.AddValue(yValueOfNewDataPoint.a); + } + } + + public void AddValue(Quaternion yValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_rotation_eulerX.AddValue(yValueOfNewDataPoint.eulerAngles.x); + lines.premadeLine_rotation_eulerY.AddValue(yValueOfNewDataPoint.eulerAngles.y); + lines.premadeLine_rotation_eulerZ.AddValue(yValueOfNewDataPoint.eulerAngles.z); + } + } + + public void AddValue(bool yValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_bool.AddValue(yValueOfNewDataPoint); + } + } + + public void AddValue(GameObject yValueOfNewDataPoint) + { + if (yValueOfNewDataPoint == null) + { + Debug.LogError("Chart: Cannot add value, because GameObject is null."); + return; + } + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValue(yValueOfNewDataPoint.transform); + } + } + + public void AddValue(Transform yValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValue(yValueOfNewDataPoint); + } + } + + public void AddXYValue(Vector2 xyValueOfNewDataPoint, string nameOfReceivingLine) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.GetUsermadeLine(nameOfReceivingLine, true).AddXYValue(xyValueOfNewDataPoint); + } + } + + public void AddXYValue(Vector2 xyValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_float.AddXYValue(xyValueOfNewDataPoint); + } + } + + public void AddXYValue(float xValue, float yValue, string nameOfReceivingLine) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.GetUsermadeLine(nameOfReceivingLine, true).AddXYValue(xValue, yValue); + } + } + + public void AddXYValue(float xValue, float yValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_float.AddXYValue(xValue, yValue); + } + } + + public void AddXYValue(float xValue, int yValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_int.AddXYValue(xValue, (float)yValue); + } + } + + public void AddXYValue(float xValue, bool yValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.premadeLine_bool.AddXYValue(xValue, yValue); + } + } + + public void AddValues_eachIndexIsALine(List yValues) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromList_toListWithFloatLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(float[] yValues) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromArray_toListWithFloatLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(List yValues) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromList_toListWithIntLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(int[] yValues) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromArray_toListWithIntLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(List yValues) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because list is null."); + return; + } + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromList_toListWithVector2Lines(yValues); + } + } + + public void AddValues_eachIndexIsALine(Vector2[] yValues) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because array is null."); + return; + } + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromArray_toListWithVector2Lines(yValues); + } + } + + public void AddValues_eachIndexIsALine(List yValues) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because list is null."); + return; + } + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromList_toListWithVector3Lines(yValues); + } + } + + public void AddValues_eachIndexIsALine(Vector3[] yValues) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because array is null."); + return; + } + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromArray_toListWithVector3Lines(yValues); + } + } + + public void AddValues_eachIndexIsALine(List yValues) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because list is null."); + return; + } + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromList_toListWithQuaternionLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(Quaternion[] yValues) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because array is null."); + return; + } + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromArray_toListWithQuaternionLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(List yValues) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromList_toListWithBoolLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(bool[] yValues) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromArray_toListWithBoolLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(List yValues) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because list is null."); + return; + } + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromList_toListWithGameobjectLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(GameObject[] yValues) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because array is null."); + return; + } + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromArray_toListWithGameobjectLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(List yValues) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because list is null."); + return; + } + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromList_toListWithTransformLines(yValues); + } + } + + public void AddValues_eachIndexIsALine(Transform[] yValues) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because array is null."); + return; + } + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + lines.AddValuesFromArray_toListWithTransformLines(yValues); + } + } + + public ChartLine AddLine(string name, Color color = default(Color), bool newLineRepresentsBoolValues = false) + { + ChartLine newlyCreatedLine = lines.AddLine(name, color); + if (newlyCreatedLine != null) { newlyCreatedLine.disableMinMaxYVisualizers_dueTo_lineRepresentsBoolValues = newLineRepresentsBoolValues; } + return newlyCreatedLine; + } + + public ChartLine GetUsermadeLine(string lineName, bool createLineIfItDoesntExist = false) + { + return lines.GetUsermadeLine(lineName, createLineIfItDoesntExist); + } + + public void IncrementXPos(int steps = 1) + { + for (int i = 0; i < steps; i++) + { + xPos_currentManualIncrementValue++; + } + } + + public int GetManuallyIncrementedXPos() + { + return xPos_currentManualIncrementValue; + } + + void TryDrawRGBColorUnderlay(float valueMarkingLowerEndOf_XAxis, float valueMarkingUpperEndOf_XAxis, float valueMarkingLowerEndOf_YAxis, float valueMarkingUpperEndOf_YAxis, float durationInSec, bool hiddenByNearerObjects) + { + if (drawRGBColorUnderlayForColorGraphs) + { + if (lines.premadeLine_color_r.dataPoints.Count != lines.premadeLine_color_g.dataPoints.Count) { ErrorLogForDifferentCountOfRGBAchannels(); return; } + if (lines.premadeLine_color_r.dataPoints.Count != lines.premadeLine_color_b.dataPoints.Count) { ErrorLogForDifferentCountOfRGBAchannels(); return; } + if (lines.premadeLine_color_r.dataPoints.Count != lines.premadeLine_color_a.dataPoints.Count) { ErrorLogForDifferentCountOfRGBAchannels(); return; } + + for (int i = 0; i < lines.premadeLine_color_r.dataPoints.Count; i++) + { + bool allFourColorChannelsAreValid = (lines.premadeLine_color_r.dataPoints[i].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) && (lines.premadeLine_color_g.dataPoints[i].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) && (lines.premadeLine_color_b.dataPoints[i].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) && (lines.premadeLine_color_a.dataPoints[i].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid); + if (allFourColorChannelsAreValid) + { + lines.premadeLine_color_r.dataPoints[i].DetermineIfAndHowPointIsDrawn_forRGBColorUnderlay(valueMarkingLowerEndOf_XAxis, valueMarkingUpperEndOf_XAxis, valueMarkingLowerEndOf_YAxis, valueMarkingUpperEndOf_YAxis); + if (lines.premadeLine_color_r.dataPoints[i].isInsideChartsXSpan || drawValuesOutsideOfChartArea) + { + Color rgbColor = new Color(lines.premadeLine_color_r.dataPoints[i].yValue, lines.premadeLine_color_g.dataPoints[i].yValue, lines.premadeLine_color_b.dataPoints[i].yValue, lines.premadeLine_color_a.dataPoints[i].yValue); + Line_fadeableAnimSpeed.InternalDraw(lines.premadeLine_color_r.dataPoints[i].positionInWorldSpace_atYHeightOfLowerEndOf_rgbColorUnderlay, lines.premadeLine_color_r.dataPoints[i].positionInWorldSpace_atYHeightOfUpperEndOf_rgbColorUnderlay, rgbColor, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + } + } + + void ErrorLogForDifferentCountOfRGBAchannels() + { + Debug.LogError("Chart: Cannot draw rgb color underlay, because the 4 channels have differnet numbers of values. r has " + lines.premadeLine_color_r.dataPoints.Count + ", g has " + lines.premadeLine_color_g.dataPoints.Count + ", b has" + lines.premadeLine_color_b.dataPoints.Count + ", a has " + lines.premadeLine_color_a.dataPoints.Count); + } + + public void SetLineNamesPositions(ChartLine.NamePosition newLineNamesPosition) + { + //overwrites the linePosition for all lines of the chart. If you want to specificy different linename positions for each line you can directly set chartLine.namePosition + lines.SetLineNamesPositions(newLineNamesPosition); + } + + public void SetLineNamesSize(float newLineNamesSizeScaleFactor) + { + //overwrites the NameText_sizeScaleFactor for all lines of the chart. If you want to specificy different NameText_sizeScaleFactor for each line you can directly set chartLine.NameText_sizeScaleFactor + lines.SetLineNamesSize(newLineNamesSizeScaleFactor); + } + + public void Set_lineConnectionsType(ChartLine.LineConnectionsType newLineConnectionsType) + { + //overwrites the lineConnectionsType for all lines of the chart. If you want to specificy different lineConnectionsTypes for each line you can directly set chartLine.lineConnectionsType + lines.Set_lineConnectionsType(newLineConnectionsType); + } + + public void Set_dataPointVisualization(ChartLine.DataPointVisualization newDataPointVisualization) + { + //overwrites the dataPointVisualization for all lines of the chart. If you want to specificy different dataPointVisualization for each line you can directly set chartLine.dataPointVisualization + lines.Set_dataPointVisualization(newDataPointVisualization); + } + + public void Set_alpha_ofVerticalAreaFillLines(float newAlpha) + { + //overwrites the alpha_ofVerticalFillAreaLines for all lines of the chart. If you want to specificy different alpha_ofVerticalFillAreaLines for each line you can directly set chartLine.alpha_ofVerticalFillAreaLines + lines.Set_alpha_ofVerticalAreaFillLines(newAlpha); + } + + public void Set_alpha_ofHighlighterForMostCurrentValue_xDim(float newAlpha) + { + //overwrites the alpha_ofHighlighterForMostCurrentValue_xDim for all lines of the chart. If you want to specificy different alpha_ofHighlighterForMostCurrentValue_xDim for each line you can directly set chartLine.alpha_ofHighlighterForMostCurrentValue_xDim + lines.Set_alpha_ofHighlighterForMostCurrentValue_xDim(newAlpha); + } + + public void Set_alpha_ofHighlighterForMostCurrentValue_yDim(float newAlpha) + { + //overwrites the alpha_ofHighlighterForMostCurrentValue_yDim for all lines of the chart. If you want to specificy different alpha_ofHighlighterForMostCurrentValue_yDim for each line you can directly set chartLine.alpha_ofHighlighterForMostCurrentValue_yDim + lines.Set_alpha_ofHighlighterForMostCurrentValue_yDim(newAlpha); + } + + public void Set_displayDeltaAtHighlighterForMostCurrentValue(bool doDisplay) + { + //overwrites the displayDeltaAtHighlighterForMostCurrentValue for all lines of the chart. If you want to specificy different displayDeltaAtHighlighterForMostCurrentValue for each line you can directly set chartLine.displayDeltaAtHighlighterForMostCurrentValue + lines.Set_displayDeltaAtHighlighterForMostCurrentValue(doDisplay); + } + + public void Set_alpha_ofMaxiumumYValueMarker(float newAlpha) + { + //overwrites the alpha_ofMaxiumumYValueMarker for all lines of the chart. If you want to specificy different alpha_ofMaxiumumYValueMarker for each line you can directly set chartLine.alpha_ofMaxiumumYValueMarker + lines.Set_alpha_ofMaxiumumYValueMarker(newAlpha); + } + + public void Set_alpha_ofMinimumYValueMarker(float newAlpha) + { + //overwrites the alpha_ofMinimumYValueMarker for all lines of the chart. If you want to specificy different alpha_ofMinimumYValueMarker for each line you can directly set chartLine.alpha_ofMinimumYValueMarker + lines.Set_alpha_ofMinimumYValueMarker(newAlpha); + } + + public void Set_markAllYMaximumTurningPoints(bool markEnabled) + { + //overwrites the markAllYMaximumTurningPoints for all lines of the chart. If you want to specificy different markAllYMaximumTurningPoints for each line you can directly set chartLine.markAllYMaximumTurningPoints + lines.Set_markAllYMaximumTurningPoints(markEnabled); + } + + public void Set_markAllYMinimumTurningPoints(bool markEnabled) + { + //overwrites the markAllYMinimumTurningPoints for all lines of the chart. If you want to specificy different markAllYMinimumTurningPoints for each line you can directly set chartLine.markAllYMinimumTurningPoints + lines.Set_markAllYMinimumTurningPoints(markEnabled); + } + + public void Set_SizeOfPoints_relToChartHeight(float newRelSize) + { + //overwrites the SizeOfPoints_relToChartHeight for all lines of the chart. If you want to specificy different SizeOfPoints_relToChartHeight for each line you can directly set chartLine.SizeOfPoints_relToChartHeight + lines.Set_SizeOfPoints_relToChartHeight(newRelSize); + } + + public void Set_lineWidth_relToChartHeight(float newRelSize) + { + //overwrites the lineWidth_relToChartHeight for all lines of the chart. If you want to specificy different lineWidth_relToChartHeight for each line you can directly set chartLine.lineWidth_relToChartHeight + lines.Set_lineWidth_relToChartHeight(newRelSize); + } + + public void Set_pointVisualisationLineWidth_relToChartHeight(float newRelSize) + { + //overwrites the pointVisualisationLineWidth_relToChartHeight for all lines of the chart. If you want to specificy different pointVisualisationLineWidth_relToChartHeight for each line you can directly set chartLine.pointVisualisationLineWidth_relToChartHeight + lines.Set_pointVisualisationLineWidth_relToChartHeight(newRelSize); + } + + public void SetAll_dataComponentsThatAreDrawn(DataComponentsThatAreDrawn newConfig) + { + //easy way of overwriting "dataComponentsThatAreDrawn" from another chart, without fiddling with single bool members. + dataComponentsThatAreDrawn.CopyValueFromOtherConfig(newConfig); + } + + public Vector3 ChartSpace_to_WorldSpace(Vector2 positionInChartSpace) + { + //This is dependent on the axis scaling which can change dynamically. Therefore the returned value fits the axis scaling of the last "chartDrawing.Draw()"(<-link)-Call. If ""ChartDrawing.Draw()"(<-link)" hasn't been called at least once this will return faulty values. + float xPos_inUnwarpedUnscaledChartSpace = positionInChartSpace.x * xAxis.LengthConversionFactor_fromChartScaling_toWorldScaling; + float yPos_inUnwarpedUnscaledChartSpace = positionInChartSpace.y * yAxis.LengthConversionFactor_fromChartScaling_toWorldScaling; + return (posOfOriginOfChartSpace_inWorldSpace + xAxis.AxisVector_normalized_inWorldSpace * xPos_inUnwarpedUnscaledChartSpace + yAxis.AxisVector_normalized_inWorldSpace * yPos_inUnwarpedUnscaledChartSpace); + } + + public bool IsInsideDrawnChartArea(Vector2 posToCheck_inChartUnits) + { + //if you want to check only one dimension you can use xAxis/yAxis.IsInsideDisplayedSpan + return IsInsideDrawnChartArea(posToCheck_inChartUnits.x, posToCheck_inChartUnits.y); + } + + public bool IsInsideDrawnChartArea(float posToCheck_x_inChartUnits, float posToCheck_y_inChartUnits) + { + //if you want to check only one dimension you can use xAxis/yAxis.IsInsideDisplayedSpan + if (xAxis.IsInsideDisplayedSpan(posToCheck_x_inChartUnits)) + { + if (yAxis.IsInsideDisplayedSpan(posToCheck_y_inChartUnits)) + { + return true; + } + } + return false; + } + + void Create_pointsOfInterest_thatCommunicateTheHiddenPointsOfInterest() + { + float position_x = 0.0f; //-> is unused + float position_y = 0.0f; //-> is unused + Color color = default; //-> gets continuously overwritten + string textToDisplay = null; //-> gets continuously overwritten + + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide = new PointOfInterest(position_x, position_y, color, this, null, textToDisplay); + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide.internal_isPOIthatCommunicatesTheHiddenPOIs = true; + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide.isDeletedOnClear = false; + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide.xValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide.yValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide.Internal_Set_isDrawnInNextPass(1); //-> this means: it will ALWAYS be drawn + + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide = new PointOfInterest(position_x, position_y, color, this, null, textToDisplay); + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide.internal_isPOIthatCommunicatesTheHiddenPOIs = true; + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide.isDeletedOnClear = false; + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide.xValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide.yValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide.Internal_Set_isDrawnInNextPass(1); //-> this means: it will ALWAYS be drawn + } + + public void AddPointOfInterest(PointOfInterest newPointOfInterest) + { + newPointOfInterest.chart_thisPointIsPartOf = this; + pointsOfInterest.Add(newPointOfInterest); + } + + public PointOfInterest AddPointOfInterest(Vector2 position, string textToDisplay = null, DrawBasics.LineStyle horizLinestyle = DrawBasics.LineStyle.invisible, DrawBasics.LineStyle vertLinestyle = DrawBasics.LineStyle.invisible, float alphaOfColor_relToChartColor = 1.0f, bool getsDeletedOnClear = true) + { + return AddPointOfInterest(position.x, position.y, textToDisplay, horizLinestyle, vertLinestyle, alphaOfColor_relToChartColor, getsDeletedOnClear); + } + + public PointOfInterest AddPointOfInterest(float position_x, float position_y, string textToDisplay = null, DrawBasics.LineStyle horizLinestyle = DrawBasics.LineStyle.invisible, DrawBasics.LineStyle vertLinestyle = DrawBasics.LineStyle.invisible, float alphaOfColor_relToChartColor = 1.0f, bool getsDeletedOnClear = true) + { + //the function returns the new point of interest, so it can then accessed and be further modified. + //if no text is appointed then invisible horizontal und vertical lines will automatically be forced to solid line (otherwise the point would not be visible.) + + if (textToDisplay == null || textToDisplay == "") + { + if (horizLinestyle == DrawBasics.LineStyle.invisible) { horizLinestyle = DrawBasics.LineStyle.solid; } + if (vertLinestyle == DrawBasics.LineStyle.invisible) { vertLinestyle = DrawBasics.LineStyle.solid; } + } + + Color colorOfPoint = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfColor_relToChartColor); + PointOfInterest newPointOfInterest = new PointOfInterest(position_x, position_y, colorOfPoint, this, null, textToDisplay); + newPointOfInterest.isDeletedOnClear = getsDeletedOnClear; + newPointOfInterest.xValue.lineStyle = vertLinestyle; + newPointOfInterest.yValue.lineStyle = horizLinestyle; + pointsOfInterest.Add(newPointOfInterest); + return newPointOfInterest; + } + + void DeletePointsOfInterestOnClear() + { + for (int i = pointsOfInterest.Count - 1; i >= 0; i--) + { + if (pointsOfInterest[i].isDeletedOnClear) + { + pointsOfInterest.RemoveAt(i); + } + } + } + + int stillAvailableTextBoxes_inUpperLeftCorner_duringPreviousDrawRun = 0; + void DrawPointsOfInterest(float durationInSec, bool hiddenByNearerObjects) + { + if (isEmptyWithNoLinesToDraw == false) + { + float yHeightFacor_forColumnStartPos = 1.05f; + + //Points that are attached to the chart: + UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted = UtilitiesDXXL_Math.SkewedDirection.upLeft; + Vector3 next_lowAnchorPositionOfText_inWorldspace = Position_worldspace + yAxis.AxisVector_inWorldSpace * yHeightFacor_forColumnStartPos + xAxis.AxisVector_inWorldSpace * 0.0f; + + int stillAvailableTextBoxes_inUpperLeftCorner = MaxDisplayedPointOfInterestTextBoxesPerSide; + for (int i = pointsOfInterest.Count - 1; i >= 0; i--) //-> counting DOWNWARD means: only the NEWEST textBoxes get drawn + { + stillAvailableTextBoxes_inUpperLeftCorner = pointsOfInterest[i].Internal_Set_isDrawnInNextPass(stillAvailableTextBoxes_inUpperLeftCorner); + } + + if (stillAvailableTextBoxes_inUpperLeftCorner < 0) + { + //-> draw this "hiddenTextBoxes-communicating-textBox" BEFORE(=BELOW) the other textBoxes, so that it appears as the "oldest" text box: newer text boxes will be drawn higher than this + if (stillAvailableTextBoxes_inUpperLeftCorner != stillAvailableTextBoxes_inUpperLeftCorner_duringPreviousDrawRun) //-> saving GC.alloc by only recreating the text when something changes + { + if (stillAvailableTextBoxes_inUpperLeftCorner == (-1)) + { + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide.text = "...and 1 more hidden older text box.

See also 'ChartDrawing.maxDisplayedPointOfInterestTextBoxesPerSide'."; + } + else + { + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide.text = "...and " + (-stillAvailableTextBoxes_inUpperLeftCorner) + " more hidden older text boxes.

See also 'ChartDrawing.maxDisplayedPointOfInterestTextBoxesPerSide'."; + } + } + stillAvailableTextBoxes_inUpperLeftCorner_duringPreviousDrawRun = stillAvailableTextBoxes_inUpperLeftCorner; + pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide.colorOfPointerTextBox = color; + next_lowAnchorPositionOfText_inWorldspace = pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheLeftSide.TryDraw(next_lowAnchorPositionOfText_inWorldspace, cornerOfChartWhereTextBoxIsMounted, durationInSec, hiddenByNearerObjects); + } + + for (int i = 0; i < pointsOfInterest.Count; i++) //-> counting UPWARD for PointOfInterestBoxes on the upperLeftSide produced less pointer crossings in most cases. Though this has the disadvantage, that the "newest/oldest"-ordering is the other way round than the PointOfInterestBoxes on the upperLeftSide. + { + next_lowAnchorPositionOfText_inWorldspace = pointsOfInterest[i].TryDraw(next_lowAnchorPositionOfText_inWorldspace, cornerOfChartWhereTextBoxIsMounted, durationInSec, hiddenByNearerObjects); + } + + //Points that are attached to single lines: + lines.DrawPointsOfInterest(yHeightFacor_forColumnStartPos, durationInSec, hiddenByNearerObjects); + } + } + + public PointOfInterest AddFixedHorizLine(float yPosition, string textLabel = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.dashed, float alphaOfColor_relToParent = 0.75f) + { + //the function returns the horizontal line as pointOfInterest, so it can then accessed and be further modified. + //if you additionally want to display the intersectionPoints of the line with this horizonal line you can use "__" instead. + + Color colorOfLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfColor_relToParent); + PointOfInterest newPointOfInterest = new PointOfInterest(0.0f, yPosition, colorOfLine, this, null, null); + newPointOfInterest.xValue.lineStyle = DrawBasics.LineStyle.invisible; + newPointOfInterest.yValue.lineStyle = style; + newPointOfInterest.yValue.labelText = textLabel; + newPointOfInterest.yValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + newPointOfInterest.isDeletedOnClear = false; + pointsOfInterest.Add(newPointOfInterest); + return newPointOfInterest; + } + + public PointOfInterest AddFixedHorizLine_withPointer(float yPosition, string textInPointerBox, string textAtLine = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float alphaOfLineColor_relToParent = 0.75f) + { + //the function returns the horizontal line as pointOfInterest , so it can then accessed and be further modified. + //if you additionally want to display the intersectionPoints of the line with this horizonal line you can use "AddHorizontalThresholdLine" instead. + + Color colorOfLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfLineColor_relToParent); + PointOfInterest newPointOfInterest = new PointOfInterest(float.NaN, yPosition, colorOfLine, this, null, textInPointerBox); + newPointOfInterest.colorOfPointerTextBox = color; + newPointOfInterest.drawTextBoxIfPointIsOutsideOfChartArea = true; + newPointOfInterest.xValue.lineStyle = DrawBasics.LineStyle.invisible; + newPointOfInterest.yValue.lineStyle = style; + newPointOfInterest.yValue.labelText = textAtLine; + newPointOfInterest.yValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + newPointOfInterest.isDeletedOnClear = false; + newPointOfInterest.forceColorOfParent = false; + pointsOfInterest.Add(newPointOfInterest); + return newPointOfInterest; + } + + + public PointOfInterest AddFixedVertLine(float xPosition, string textLabel = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.dashed, float alphaOfColor_relToParent = 0.75f) + { + //the function returns the vertical line as pointOfInterest, so it can then accessed and be further modified. + Color colorOfLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfColor_relToParent); + PointOfInterest newPointOfInterest = new PointOfInterest(xPosition, 0.0f, colorOfLine, this, null, null); + newPointOfInterest.xValue.lineStyle = style; + newPointOfInterest.xValue.labelText = textLabel; + newPointOfInterest.xValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + newPointOfInterest.yValue.lineStyle = DrawBasics.LineStyle.invisible; + newPointOfInterest.isDeletedOnClear = false; + pointsOfInterest.Add(newPointOfInterest); + return newPointOfInterest; + } + + public PointOfInterest AddFixedVertLine_withPointer(float xPosition, string textInPointerBox, string textAtLine = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float alphaOfLineColor_relToParent = 0.75f) + { + //the function returns the vertical line as pointOfInterest, so it can then accessed and be further modified. + Color colorOfLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfLineColor_relToParent); + PointOfInterest newPointOfInterest = new PointOfInterest(xPosition, float.NaN, colorOfLine, this, null, textInPointerBox); + newPointOfInterest.colorOfPointerTextBox = color; + newPointOfInterest.drawTextBoxIfPointIsOutsideOfChartArea = true; + newPointOfInterest.xValue.lineStyle = style; + newPointOfInterest.xValue.labelText = textAtLine; + newPointOfInterest.xValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + newPointOfInterest.yValue.lineStyle = DrawBasics.LineStyle.invisible; + newPointOfInterest.isDeletedOnClear = false; + newPointOfInterest.forceColorOfParent = false; + pointsOfInterest.Add(newPointOfInterest); + return newPointOfInterest; + } + + public PointOfInterest AddFixedCrossOFHorizAndVertLine(Vector2 position, string textLabel_onHorizLine = null, string textLabel_onVertLine = null, string textLabel_forPointerBox = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float alphaOfColor_relToParent = 0.75f) + { + //the function returns the line cross as pointOfInterest, so it can then accessed and be further modified. + return AddFixedCrossOFHorizAndVertLine(position.x, position.y, textLabel_onHorizLine, textLabel_onVertLine, textLabel_forPointerBox, style, alphaOfColor_relToParent); + } + + public PointOfInterest AddFixedCrossOFHorizAndVertLine(float xPosition, float yPosition, string textLabel_onHorizLine = null, string textLabel_onVertLine = null, string textLabel_forPointerBox = null, DrawBasics.LineStyle style = DrawBasics.LineStyle.solid, float alphaOfColor_relToParent = 0.75f) + { + //the function returns the line cross as pointOfInterest, so it can then accessed and be further modified. + Color colorOfLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfColor_relToParent); + PointOfInterest newPointOfInterest = new PointOfInterest(xPosition, yPosition, colorOfLine, this, null, textLabel_forPointerBox); + newPointOfInterest.xValue.lineStyle = style; + newPointOfInterest.yValue.lineStyle = style; + newPointOfInterest.xValue.labelText = textLabel_onVertLine; + newPointOfInterest.yValue.labelText = textLabel_onHorizLine; + newPointOfInterest.xValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + newPointOfInterest.yValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + newPointOfInterest.isDeletedOnClear = false; + pointsOfInterest.Add(newPointOfInterest); + return newPointOfInterest; + } + + public void AddHorizontalThresholdLine(float yPosition, bool lineItselfCountsToLowerArea = false, Color colorOfHorizLine = default(Color)) + { + //if you want to add the threshold to only a single line you can use the "AddHorizontalThresholdLine"-version in "chartline" + //If you don't want to see the intersection points and only want to draw a horizontal line that doesn't do anything you can use 'AddFixedHorizLine' instead. + //"colorOfHorizLine": supply this if the color should deviate from the charts color + //"lineItselfCountsToLowerArea" determines if it counts as an intersection if the line doesn't cross the threshold but runs exactly onto it. + + if (UtilitiesDXXL_Math.FloatIsInvalid(yPosition)) + { + Debug.LogError("Cannot create threshold line at " + yPosition); + return; + } + + if (UtilitiesDXXL_Colors.IsDefaultColor(colorOfHorizLine)) + { + colorOfHorizLine = UtilitiesDXXL_Colors.GetSimilarColorWithSlightlyOtherBrightnessValue(color); + } + + PointOfInterest pointOfInterst_visualizingTheHorizThresholdLine = new PointOfInterest(0.0f, yPosition, colorOfHorizLine, this, null, null); + pointOfInterst_visualizingTheHorizThresholdLine.isDeletedOnClear = false; + pointOfInterst_visualizingTheHorizThresholdLine.forceColorOfParent = false; + pointOfInterst_visualizingTheHorizThresholdLine.xValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterst_visualizingTheHorizThresholdLine.yValue.lineStyle = DrawBasics.LineStyle.solid; + pointOfInterst_visualizingTheHorizThresholdLine.yValue.labelText = "Threshold"; + pointOfInterst_visualizingTheHorizThresholdLine.yValue.drawCoordinateAsText = true; + pointOfInterst_visualizingTheHorizThresholdLine.yValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + pointsOfInterest.Add(pointOfInterst_visualizingTheHorizThresholdLine); + + lines.AddHorizontalThresholdToEachLine(yPosition, lineItselfCountsToLowerArea); + } + + void DrawChartName(float durationInSec, bool hiddenByNearerObjects) + { + if (name != null && name != "") + { + float textSize = xAxis.Length_inWorldSpace * 0.04f * scaleFactor_forChartNameTextSize; + Vector3 position = Position_worldspace + 0.5f * xAxis.AxisVector_inWorldSpace + yAxis.AxisVector_normalized_inWorldSpace * (yAxis.Length_inWorldSpace * 1.035f + textSize); + float enclosingBox_paddingSize_relToTextSize = 0.5f; + float autoLineBreakWidth = 0.65f * xAxis.Length_inWorldSpace; + UtilitiesDXXL_Text.WriteFramed(name, position, color, textSize, internalRotation, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.solid, 0.0f, enclosingBox_paddingSize_relToTextSize, 0.0f, 0.0f, autoLineBreakWidth, autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects); + } + } + + void TryDrawFallbackForEmptyChart(float durationInSec, bool hiddenByNearerObjects) + { + if (isEmptyWithNoLinesToDraw) + { + string text = " This chart doesn't contain
any data to draw."; //-> the two spaces are intentional + float textSize = 1.0f; //->not relevant, because textsize gets forced by "forceTextEnlargementToThisMinWidth" respectively "forceRestrictTextSizeToThisMaxTextWidth" + DrawText.TextAnchorDXXL textAnchor = DrawText.TextAnchorDXXL.LowerLeft; + float forceTextEnlargementToThisMinWidth = Width_inWorldSpace; + float forceRestrictTextSizeToThisMaxTextWidth = forceTextEnlargementToThisMinWidth; + UtilitiesDXXL_Text.WriteFramed(text, Position_worldspace, color, textSize, internalRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextEnlargementToThisMinWidth, forceRestrictTextSizeToThisMaxTextWidth, 0.0f, autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects); + } + } + + public void DrawWarningForMaxLinesPerFrame() + { + string warningText = "
Max lines exceeded
(see log)"; + float textSize = 1.0f; //gets forced to fit chart width + float forceTextEnlargementToThisMinWidth = Width_inWorldSpace; + float forceRestrictTextSizeToThisMaxTextWidth = Width_inWorldSpace; + UtilitiesDXXL_Text.WriteFramed(warningText, Position_worldspace, color, textSize, internalRotation, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextEnlargementToThisMinWidth, forceRestrictTextSizeToThisMaxTextWidth, 0.0f, autoFlipAllText_toFitObsererCamera, 0.0f, false); + } + + void ResetOverallMinMaxValues() + { + overallMinXValue_includingHiddenLines = float.NaN; + overallMaxXValue_includingHiddenLines = float.NaN; + overallMinYValue_includingHiddenLines = float.NaN; + overallMaxYValue_includingHiddenLines = float.NaN; + } +#if UNITY_EDITOR + GameObject chartInspector_gameObject = null; +#endif + public DrawXXLChartInspector chartInspector_component = null; + public void CreateChartInspectionGameobject(bool freezeAxesInMomentOfInspectorCreation = false, bool setSceneViewCamToChart = false, bool setChartGameobjectToTheTopOfTheHierarchy = false, bool autoSelectCreatedChartInInspector = false) + { +#if UNITY_EDITOR + if (chartInspector_gameObject == null) + { + Internal_CreateChartInspectionGameobject(freezeAxesInMomentOfInspectorCreation, setSceneViewCamToChart, autoSelectCreatedChartInInspector, setChartGameobjectToTheTopOfTheHierarchy); + } + else + { + if (chartInspector_component == null) + { + DrawXXLChartInspector[] allChartInspectorComponents_thatAreAttachedToTheGameObject = chartInspector_gameObject.GetComponents(); + for (int i = 0; i < allChartInspectorComponents_thatAreAttachedToTheGameObject.Length; i++) + { + if (Application.isPlaying) + { + UnityEngine.Object.Destroy(allChartInspectorComponents_thatAreAttachedToTheGameObject[i]); + } + else + { + UnityEngine.Object.DestroyImmediate(allChartInspectorComponents_thatAreAttachedToTheGameObject[i]); + } + } + Internal_CreateChartInspectionGameobject(freezeAxesInMomentOfInspectorCreation, setSceneViewCamToChart, autoSelectCreatedChartInInspector, setChartGameobjectToTheTopOfTheHierarchy); + } + else + { + //Debug.Log("Calling 'CreateChartInspectionGameobject()' has no effect because there is already a chart inspection component."); + } + } +#endif + } + + void Internal_CreateChartInspectionGameobject(bool freezeAxes, bool setSceneViewCamToChart, bool autoSelectCreatedChartInInspector, bool setChartGameobjectToTheTopOfTheHierarchy) + { +#if UNITY_EDITOR + xAxis.SetAxisScalingDuringInspectionComponentPhases(xAxis.ValueMarkingLowerEndOfTheAxis, xAxis.ValueMarkingUpperEndOfTheAxis); + yAxis.SetAxisScalingDuringInspectionComponentPhases(yAxis.ValueMarkingLowerEndOfTheAxis, yAxis.ValueMarkingUpperEndOfTheAxis); + + string gameobjectName; + if (name == null || name == "") + { + gameobjectName = "Draw XXL Chart Inspector"; + } + else + { + gameobjectName = "Chart: " + name + ""; + } + + if (chartInspector_gameObject == null) + { + chartInspector_gameObject = new GameObject(gameobjectName); + } + + chartInspector_component = chartInspector_gameObject.AddComponent(); + lines.InitInspectionViaComponent(); + + chartInspector_component.hasBeenManuallyCreated = false; + chartInspector_component.hasBeenCreatedOutsidePlaymode = !Application.isPlaying; + chartInspector_component.theChartIsDrawnInScreenspace = theMostCurrentChartDrawing_hasBeenMadeInScreenspace; + chartInspector_component.screenSpaceTargetCamera = cameraUsedByMostCurrentScreenspaceDrawing; + chartInspector_component.chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight = theMostCurrentScreenspaceDrawing_definedChartWidth_relToCamWidth; + chartInspector_component.nonScreenspaceDrawing_happensWith_drawConfigOf_hiddenByNearerObjects = theMostCurrentChartDrawing_wasDrawnWithConfigOf_hiddenByNearerObjects; + chartInspector_component.AssignChart(this); + chartInspector_component.curr_luminanceOfLineColors_accordingToSlider = LuminanceOfLineColors; + chartInspector_component.prev_luminanceOfLineColors_accordingToSlider = LuminanceOfLineColors; + chartInspector_component.prev_luminanceOfLineColors_accordingToChartSetting = LuminanceOfLineColors; + chartInspector_component.lineNamePositions = lines.GetAUsedLineNamePosition(false); + chartInspector_component.lineNames_sizeScaleFactor = lines.GetAUsedLineNameSizeSclaeFactor(false); + + if (setSceneViewCamToChart && (chartInspector_component.theChartIsDrawnInScreenspace == false)) { chartInspector_component.TrySetSceneViewCamToChart_dueToButtonClick(); } + if (autoSelectCreatedChartInInspector) { UnityEditor.Selection.SetActiveObjectWithContext(chartInspector_gameObject, UnityEditor.Selection.activeContext); } + if (setChartGameobjectToTheTopOfTheHierarchy) { chartInspector_gameObject.transform.SetAsFirstSibling(); } + if (freezeAxes == false) { chartInspector_component.alwaysEncapsulateAllValues = true; } +#endif + } + + public void ExportToCSVfile(string fileName = null) + { + if (chartToCSVfileWriter == null) { chartToCSVfileWriter = new InternalDXXL_ChartToCSVfileWriter(); } + chartToCSVfileWriter.ExportToCSVfile(lines, fileName); + } + + public Vector3 GetCenterPos() + { + //returns the center position of the chart (in worldspace) as opposed to the low left origin which "Position_worldspace" returns. + return (Position_worldspace + 0.5f * (xAxis.AxisVector_inWorldSpace + yAxis.AxisVector_inWorldSpace)); + } + + public float GetDiagonalSize() + { + return (xAxis.AxisVector_inWorldSpace + yAxis.AxisVector_inWorldSpace).magnitude; + } + + public Vector3 Get_unified45degAxis_forHandleSliders_normalized() + { + return (-(xAxis.AxisVector_normalized_inWorldSpace + yAxis.AxisVector_normalized_inWorldSpace) * UtilitiesDXXL_Math.inverseSqrtOf2_precalced); + } + + public float Get_unified45degAxis_length() + { + return 3.6f * xAxis.Get_fixedConeLength_forBothAxisVectors(); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/ChartDrawing.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/ChartDrawing.cs.meta new file mode 100644 index 0000000..09c9dc4 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/ChartDrawing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: afc487da656a5634dac1e97c4355dec4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/ChartLine.cs b/Runtime/DrawDebugLibrary/charts/line charts/ChartLine.cs new file mode 100644 index 0000000..f2fcd0d --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/ChartLine.cs @@ -0,0 +1,1444 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class ChartLine + { + public enum LineConnectionsType { straightFromPointToPoint, horizPlateauTillNextPoint, invisible } + public enum DataPointVisualization + { + invisible, + cross, + cross45deg, + square, + squareCrossed, + triangle, + triangleCrossed, + pentagon, + pentagonCrossed, + circle, + circleFilled, + star4corners, + star4CornersCrossed, + star5corners, + star5CornersCrossed, + heart, + customIconSymbol + } + + public enum NamePosition + { + dynamicallyMoving_atLineEnd_towardsRight, + dynamicallyMoving_atLineEnd_towardsLeft, + dynamic_atLowestLinePos, + dynamic_atHighestLinePos, + fixedPosAtRight_outsideOfChart, + fixedPosAtRight_insideChart, + fixedPosAtLeft_insideChart + } + + public InternalDXXL_LineSpecsForChartInspector lineSpecsForInspector; + + public LineConnectionsType lineConnectionsType //if you want to set the lineConnectionsType for all lines of the chart at once you can use chartDrawing.SetLineConnectionsType + { + get { return lineSpecsForInspector.connectionsType; } + set { lineSpecsForInspector.connectionsType = value; } + } + + public DataPointVisualization dataPointVisualization //if you want to set the dataPointVisualization for all lines of the chart at once you can use chartDrawing.SetDataPointVisualization + { + get { return lineSpecsForInspector.dataPointVisualization; } + set { lineSpecsForInspector.dataPointVisualization = value; } + } + + public NamePosition namePosition; //if you want to set the namePosition for all lines of the chart at once you can use chartDrawing.SetLineNamesPosition. + private float nameText_sizeScaleFactor; //default is 1 + public float NameText_sizeScaleFactor + { + get { return nameText_sizeScaleFactor; } + set { nameText_sizeScaleFactor = Mathf.Max(0.01f, value); } + } + + public float alpha_ofHighlighterForMostCurrentValue_xDim;//if you want to set the alpha_ofHighlighterForMostCurrentValue_xDim for all lines of the chart at once you can use chartDrawing.Set_alpha_ofHighlighterForMostCurrentValue_xDim. With this you can set the intensity or toggle on and off the vertical line that highlights the x position of the most current value. 0 disables the highlighting. If the value was added using "AddValues_eachIndexIsALine" then the highlighting lines are only displayed if "chart.displayHighlightingOfMostCurrentValues_forLinesFromLists" has to been set to "true". + public float alpha_ofHighlighterForMostCurrentValue_yDim;//if you want to set the alpha_ofHighlighterForMostCurrentValue_yDim for all lines of the chart at once you can use chartDrawing.Set_alpha_ofHighlighterForMostCurrentValue_yDim. With this you can set the intensity or toggle on and off the horizontal line that highlights the y position of the most current value. 0 disables the highlighting. If the value was added using "AddValues_eachIndexIsALine" then the highlighting lines are only displayed if "chart.displayHighlightingOfMostCurrentValues_forLinesFromLists" has to been set to "true". + public bool displayDeltaAtHighlighterForMostCurrentValue;//if you want to set the displayDeltaAtHighlighterForMostCurrentValue for all lines of the chart at once you can use chartDrawing.Set_displayDeltaAtHighlighterForMostCurrentValue. + public float alpha_ofMaxiumumYValueMarker;//if you want to set the alpha_ofMaxiumumYValueMarker for all lines of the chart at once you can use chartDrawing.Set_alpha_ofMaxiumumYValueMarker. 0 means disabled. default is 0,3. Displays only turning points, so it is not displayed when the first or the most current value is the maximum value. If you want to highlight not just the highest, but all upper turning points you can use "markAllYMaximumTurningPoints". Can be easily set for all lines from lists via "chartDrawing.Set_alphaOfMaxiumumYValueMarker_forLinesFromLists" + public float alpha_ofMinimumYValueMarker;//if you want to set the alpha_ofMinimumYValueMarker for all lines of the chart at once you can use chartDrawing.Set_alpha_ofMinimumYValueMarker. 0 means disabled. default is 0,3. Displays only turning points, so it is not displayed when the first or the most current value is the maximum value. If you want to highlight not just the lowest, but all lower turning points you can use "markAllYMinimumTurningPoints". Can be easily set for all lines from lists via "chartDrawing.Set_alphaOfMinimumYValueMarker_forLinesFromLists" + public bool markAllYMaximumTurningPoints;//if you want to set the markAllYMaximumTurningPoints for all lines of the chart at once you can use chartDrawing.Set_markAllYMaximumTurningPoints. default is false. Displays only turning points, so it is not displayed when the most current value is the maximum value. If you want to highlight only the single highest point of all and not every turning point you can use "alpha_ofMaxiumumYValueMarker". The points are displayed with the alpha specified by "alpha_ofMaximumYValueMarker" and will not be visible if this value is 0. Can be easily set for all lines from lists via "chartDrawing.Set_markAllYMaximumTurningPoints_forLinesFromLists" + public bool markAllYMinimumTurningPoints;//if you want to set the markAllYMinimumTurningPoints for all lines of the chart at once you can use chartDrawing.Set_markAllYMinimumTurningPoints. default is false. Displays only turning points, so it is not displayed when the most current value is the maximum value. If you want to highlight only the single lowest point of all and not every turning point you can use "alpha_ofMinimumYValueMarker". The points are displayed with the alpha specified by "alpha_ofMinimumYValueMarker" and will not be visible if this value is 0. Can be easily set for all lines from lists via "chartDrawing.Set_markAllYMinimumTurningPoints_forLinesFromLists" + public DrawBasics.IconType customIconAsDatapointVisualization = DrawBasics.IconType.car; + + public bool Hide + { + get { return lineSpecsForInspector.currentHideLineState; } + set { lineSpecsForInspector.currentHideLineState = value; } + } + + public Color Color + { + get { return lineSpecsForInspector.lineColor; } + set { lineSpecsForInspector.lineColor = value; } + } + + private string name = null; + public string Name //you can use rich text markups inside the name string, so the line name display can e.g. be bold, magnified in size or contain icons. + { + get { return name; } + set + { + name = value; + lineSpecsForInspector.linesCompoundName = GetNameCompound(InternalDXXL_LineSpecsForChartInspector.lineCompoundNames_haveSpaces_betweenTheNamePartConnectingMinus); + } + } + + private string nameExtraInfo = null; + public string NameExtraInfo + { + get { return nameExtraInfo; } + set + { + nameExtraInfo = value; + lineSpecsForInspector.linesCompoundName = GetNameCompound(InternalDXXL_LineSpecsForChartInspector.lineCompoundNames_haveSpaces_betweenTheNamePartConnectingMinus); + } + } + + public float Alpha_ofVerticalAreaFillLines //This specifies weather the area below the line should be colored. It can be used to resemble the look of a area chart or stacked area chart. It has also the advantage that makes it more obvious where in the line the actual data points are located. 1 Means full alpha and the area of latest line overdraws the area of the previous lines, so the overlapping area is filled with the color of the last drawn line. 0 means disabled. For values in between it can be seen if the area of seperate lines overlap, but the color differences are only sufficient for some color combinations. The value doesn't define the absolute alpha but the alpha relative to the alpha of the line color. If you want to set the alpha_ofVerticalFillAreaLines for all lines of the chart at once you can use chartDrawing.SetAlphaOfVerticalFillAreaLines. + { + get { return lineSpecsForInspector.alpha_ofVertFillLines; } + set { lineSpecsForInspector.alpha_ofVertFillLines = value; } + } + + public float SizeOfPoints_relToChartHeight + { + //if you want to set the SizeOfPoints_relToChartHeight for all lines of the chart at once you can use chartDrawing.Set_SizeOfPoints_relToChartHeight + get { return lineSpecsForInspector.dataPointVisualization_size; } + set + { + float min = 0.001f; + if (value < min) + { + Debug.LogError("Setting 'SizeOfPoints_relToChartHeight' failed. It should be at least " + min + ". If you want to disable the point visualization then set 'dataPointVisualization' to 'invisible'."); + } + else + { + lineSpecsForInspector.dataPointVisualization_size = value; + } + } + } + + public float LineWidth_relToChartHeight //if you want to set the lineWidth_relToChartHeight for all lines of the chart at once you can use chartDrawing.Set_lineWidth_relToChartHeight. default is 0. warning: raising this may consume many linesPerFrame. + { + get { return lineSpecsForInspector.lineWidth; } + set { lineSpecsForInspector.lineWidth = value; } + } + + public float pointVisualisationLineWidth_relToChartHeight;//if you want to set the pointVisualisationLineWidth_relToChartHeight for all lines of the chart at once you can use chartDrawing.Set_pointVisualisationLineWidth_relToChartHeight. default is 0. warning: raising this may consume many linesPerFrame. Maybe a 'filled' DataPointVisualization choice already does the job. + + private GameObject gameobject_thatThisLineCurrentlyRepresents = null; + public GameObject Gameobject_thatThisLineCurrentlyRepresents + { + get { return gameobject_thatThisLineCurrentlyRepresents; } + set { Debug.LogError("Setting 'Gameobject_thatThisLineCurrentlyRepresents' manually is not supported."); } + } + + /// other: + public List dataPoints = new List(); + List pointsOfInterest = new List(); + List pointsOfInterest_fromIntersectionsWithHorizLines = new List(); + List horizontalThresholdLines = new List(); + PointOfInterest pointOfInterest_thatHighlightsTheMostCurrentValue; + public InternalDXXL_TurningPointDetector turningPointDetector; + public bool disableMinMaxYVisualizers_dueTo_lineRepresentsBoolValues = false; //Disables the display of "maximum y value" and "minimum y value", since for bools such a display doesn't have surplus value but only obscures the actual line. + public bool representsValuesFromAddedLists = false; + private bool allXValuesCameFromAutomaticSource; + public bool AllXValuesCameFromAutomaticSource + { + get { return allXValuesCameFromAutomaticSource; } + set { Debug.LogError("Setting 'AllXValuesCameFromAutomaticSource' manually is not supported."); } + } + + private float highestYValue = float.NegativeInfinity; + private float lowestYValue = float.PositiveInfinity; + private float highestXValue = float.NegativeInfinity; + private float lowestXValue = float.PositiveInfinity; + public float HighestYValue + { + get { return highestYValue; } + set { Debug.LogError("Setting 'HighestYValue' manually is not supported. Did you mean 'yAxis.fixedUpperEndValueOfScale' instead? (which by the way works only with 'yAxis.scaling = fixed_absolute')"); } + } + public float LowestYValue + { + get { return lowestYValue; } + set { Debug.LogError("Setting 'LowestYValue' manually is not supported. Did you mean 'yAxis.fixedLowerEndValueOfScale' instead? (which by the way works only with 'yAxis.scaling = fixed_absolute')"); } + } + public float HighestXValue + { + get { return highestXValue; } + set { Debug.LogError("Setting 'HighestXValue' manually is not supported. Did you mean 'xAxis.fixedUpperEndValueOfScale' instead? (which by the way works only with 'xAxis.scaling = fixed_absolute')"); } + } + public float LowestXValue + { + get { return lowestXValue; } + set { Debug.LogError("Setting 'LowestXValue' manually is not supported. Did you mean 'xAxis.fixedLowerEndValueOfScale' instead? (which by the way works only with 'xAxis.scaling = fixed_absolute')"); } + } + + private bool hasAtLeastOneValuePairOfValidData = false; + public bool HasAtLeastOneValuePairOfValidData + { + get { return hasAtLeastOneValuePairOfValidData; } + set { Debug.LogError("Setting 'HasAtLeastOneValuePairOfValidData' manually is not supported."); } + } + + private ChartDrawing chart_thisLineIsPartOf; + public ChartDrawing Chart_thisLineIsPartOf + { + get { return chart_thisLineIsPartOf; } + set { Debug.LogError("Setting 'Chart_thisLineIsPartOf' manually is not supported."); } + } + + UtilitiesDXXL_ChartLine.IsDrawnBecause_theSingleComponentOfMulticomponentData_thisLineRepresents_isEnabledChecker IsDrawnBecause_theSingleComponentOfMulticomponentData_thisLineRepresents_isEnabled = UtilitiesDXXL_ChartLine.DoDrawBecauseLineDoesntRepresentMultiComponentData; + float mostCurrentValidYValue = float.NaN; + float mostCurrentValidXValue = float.NaN; + + public ChartLine(Color lineColor, ChartDrawing chart_thisLineIsPartOf) + { + this.chart_thisLineIsPartOf = chart_thisLineIsPartOf; + + lineSpecsForInspector = new InternalDXXL_LineSpecsForChartInspector(); + lineSpecsForInspector.lineColor = lineColor; + lineSpecsForInspector.line_theseSpecsBelongTo = this; + lineSpecsForInspector.currentHideLineState = false; + lineSpecsForInspector.connectionsType = chart_thisLineIsPartOf.default_lineConnectionsType; + lineSpecsForInspector.dataPointVisualization = chart_thisLineIsPartOf.default_dataPointVisualization; + lineSpecsForInspector.dataPointVisualization_size = chart_thisLineIsPartOf.default_SizeOfPoints_relToChartHeight; + lineSpecsForInspector.alpha_ofVertFillLines = chart_thisLineIsPartOf.default_alpha_ofVerticalAreaFillLines; + lineSpecsForInspector.lineWidth = chart_thisLineIsPartOf.default_lineWidth_relToChartHeight; + + namePosition = chart_thisLineIsPartOf.default_lineNamePosition; + nameText_sizeScaleFactor = chart_thisLineIsPartOf.default_lineNameText_sizeScaleFactor; + alpha_ofHighlighterForMostCurrentValue_xDim = chart_thisLineIsPartOf.default_alpha_ofHighlighterForMostCurrentValue_xDim; + alpha_ofHighlighterForMostCurrentValue_yDim = chart_thisLineIsPartOf.default_alpha_ofHighlighterForMostCurrentValue_yDim; + displayDeltaAtHighlighterForMostCurrentValue = chart_thisLineIsPartOf.default_displayDeltaAtHighlighterForMostCurrentValue; + alpha_ofMaxiumumYValueMarker = chart_thisLineIsPartOf.default_alpha_ofMaxiumumYValueMarker; + alpha_ofMinimumYValueMarker = chart_thisLineIsPartOf.default_alpha_ofMinimumYValueMarker; + markAllYMaximumTurningPoints = chart_thisLineIsPartOf.default_markAllYMaximumTurningPoints; + markAllYMinimumTurningPoints = chart_thisLineIsPartOf.default_markAllYMinimumTurningPoints; + pointVisualisationLineWidth_relToChartHeight = chart_thisLineIsPartOf.default_pointVisualisationLineWidth_relToChartHeight; + + allXValuesCameFromAutomaticSource = true; + pointOfInterest_thatHighlightsTheMostCurrentValue = CreatePointOfInterestThatHighlightsTheMostCurrentValue(); + pointOfInterest_thatHighlightsTheMostCurrentValue.xValue.placeTextTowardsOutsideOfChart = true; + pointOfInterest_thatHighlightsTheMostCurrentValue.yValue.placeTextTowardsOutsideOfChart = true; + AddPointOfInterest(pointOfInterest_thatHighlightsTheMostCurrentValue); + turningPointDetector = new InternalDXXL_TurningPointDetector(this); + if (chart_thisLineIsPartOf.chartInspector_component != null) { InitInspectionViaComponent(); } + } + + public void Clear() + { + //use ChartDrawing.Clear() instead + allXValuesCameFromAutomaticSource = true; + hasAtLeastOneValuePairOfValidData = false; + dataPoints.Clear(); + highestYValue = float.NegativeInfinity; + lowestYValue = float.PositiveInfinity; + highestXValue = float.NegativeInfinity; + lowestXValue = float.PositiveInfinity; + mostCurrentValidYValue = float.NaN; + mostCurrentValidXValue = float.NaN; + gameobject_thatThisLineCurrentlyRepresents = null; + markNextNewlyCreatedPointWithEmphasizingCircle = false; + forceUpcomingNextCreatedConnectionLine_toLowAlpha = false; + DeletePointsOfInterestOnClear(); + } + + public bool Draw(InternalDXXL_Plane chartPlane, int numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn, float valueMarkingLowerEndOf_XAxis, float valueMarkingUpperEndOf_XAxis, float valueMarkingLowerEndOf_YAxis, float valueMarkingUpperEndOf_YAxis, float durationInSec, bool hiddenByNearerObjects) + { + //use ChartDrawing.Draw() instead + + thePointsOfInterestOfThisLineArePartOfTheChart = false; + if (CheckIfLineIsDrawn()) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return (dataPoints.Count > 0); } + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = chart_thisLineIsPartOf; + SetIfVisualizationOfSpecialApexPointsIsDisplayed(); + float absSizeOfPointVisualization_inWorldSpace = Mathf.Abs(chart_thisLineIsPartOf.Height_inWorldSpace * SizeOfPoints_relToChartHeight); + bool atLeastOneDatapointIsValid = false; + bool atLeastOneDrawnPointHasBeenFound = false; + int i_ofTheMostCurrentDrawnPoint = -1; + Vector3 mostRecentDrawnDataPoint_worldSpace = chart_thisLineIsPartOf.Position_worldspace; + Vector3 highestDrawnPoint_worldSpace = default; + Vector3 lowestDrawnPoint_worldSpace = default; + float heightOfHighestDrawnPoint_chartSpace = default; + float heightOfLowestDrawnPoint_chartSpace = default; + float absWidthOfConnectionLines_worldSpace = Get_absWidthOfConnectionLines_worldSpace(); + float absWidthOfPointVisualisatorLines_worldSpace = Get_absWidthOfPointVisualisatorLines_worldSpace(); + Vector3 amplitudeDir_forNonZeroWidthLines = Get_amplitudeDir_forNonZeroWidthLines(chartPlane); + bool thereHaveBeenValidPointsOutsideTheDrawnChartArea_sinceMostCurrentDrawnPoint = false; + + for (int i = 0; i < dataPoints.Count; i++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return (dataPoints.Count > 0); } + if (dataPoints[i].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) { atLeastOneDatapointIsValid = true; } + + dataPoints[i].DetermineIfAndHowPointIsDrawn(valueMarkingLowerEndOf_XAxis, valueMarkingUpperEndOf_XAxis, valueMarkingLowerEndOf_YAxis, valueMarkingUpperEndOf_YAxis, i_ofTheMostCurrentDrawnPoint, thereHaveBeenValidPointsOutsideTheDrawnChartArea_sinceMostCurrentDrawnPoint); + if (dataPoints[i].isDrawn) + { + mostRecentDrawnDataPoint_worldSpace = dataPoints[i].positionInWorldSpace; + TryDrawConnectionLineFromPrecedingPoint(i, absWidthOfConnectionLines_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects); + dataPoints[i].DrawPointVisualization(absSizeOfPointVisualization_inWorldSpace, absWidthOfConnectionLines_worldSpace, absWidthOfPointVisualisatorLines_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects); + if (atLeastOneDrawnPointHasBeenFound == false) + { + highestDrawnPoint_worldSpace = dataPoints[i].positionInWorldSpace; + lowestDrawnPoint_worldSpace = dataPoints[i].positionInWorldSpace; + heightOfHighestDrawnPoint_chartSpace = dataPoints[i].yValue; + heightOfLowestDrawnPoint_chartSpace = dataPoints[i].yValue; + atLeastOneDrawnPointHasBeenFound = true; + } + else + { + if (dataPoints[i].yValue > heightOfHighestDrawnPoint_chartSpace) + { + highestDrawnPoint_worldSpace = dataPoints[i].positionInWorldSpace; + heightOfHighestDrawnPoint_chartSpace = dataPoints[i].yValue; + } + + if (dataPoints[i].yValue < heightOfLowestDrawnPoint_chartSpace) + { + lowestDrawnPoint_worldSpace = dataPoints[i].positionInWorldSpace; + heightOfLowestDrawnPoint_chartSpace = dataPoints[i].yValue; + } + } + i_ofTheMostCurrentDrawnPoint = i; + thereHaveBeenValidPointsOutsideTheDrawnChartArea_sinceMostCurrentDrawnPoint = false; + } + else + { + if (dataPoints[i].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) { thereHaveBeenValidPointsOutsideTheDrawnChartArea_sinceMostCurrentDrawnPoint = true; } //-> current datapoint is valid, but not drawn (because it is outide of the drawn area) + } + } + + bool lineHasAtLeastOneDatapoint_validOrInvalid = dataPoints.Count > 0; + thePointsOfInterestOfThisLineArePartOfTheChart = lineHasAtLeastOneDatapoint_validOrInvalid; + if (lineHasAtLeastOneDatapoint_validOrInvalid) + { + DrawNameAsText(!atLeastOneDatapointIsValid, atLeastOneDrawnPointHasBeenFound, numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn, mostRecentDrawnDataPoint_worldSpace, highestDrawnPoint_worldSpace, lowestDrawnPoint_worldSpace, absWidthOfConnectionLines_worldSpace, durationInSec, hiddenByNearerObjects); + } + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = null; + return lineHasAtLeastOneDatapoint_validOrInvalid; + } + else + { + //-> 'dataComponentsThatAreDrawn' or 'hide' has disabled this line from drawing + bool lineIsDrawn = false; + return lineIsDrawn; + } + } + + void TryDrawConnectionLineFromPrecedingPoint(int i, float absWidthOfConnectionLines_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects) + { + if (dataPoints[i].HasAPrecedingPointFromWhichLineCanBeDrawn()) + { + Vector3 worldPos_ofPrecedingPointFromWhichLineCanBeDrawn = Get_worldPos_ofPrecedingPointFromWhichLineCanBeDrawn(i); + float yValue_ofPrecedingPointFromWhichLineCanBeDrawn_inChartSpace = Get_yValue_ofPrecedingPointFromWhichLineCanBeDrawn_inChartSpace(i); + bool lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase = CheckIf_lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase(i); + dataPoints[i].DrawConnectionLineFromPrecedingPoint(worldPos_ofPrecedingPointFromWhichLineCanBeDrawn, yValue_ofPrecedingPointFromWhichLineCanBeDrawn_inChartSpace, lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, absWidthOfConnectionLines_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects); + } + } + Vector3 Get_worldPos_ofPrecedingPointFromWhichLineCanBeDrawn(int i_ofPointForWhichToCheckThePrecedingDrawnOne) + { + return dataPoints[dataPoints[i_ofPointForWhichToCheckThePrecedingDrawnOne].i_ofPrecedingPointFromWhichLineCanBeDrawn].positionInWorldSpace; + } + + float Get_yValue_ofPrecedingPointFromWhichLineCanBeDrawn_inChartSpace(int i_ofPointForWhichToCheckThePrecedingDrawnOne) + { + return dataPoints[dataPoints[i_ofPointForWhichToCheckThePrecedingDrawnOne].i_ofPrecedingPointFromWhichLineCanBeDrawn].yValue; + + } + bool CheckIf_lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase(int i_ofPointForWhichToCheckThePrecedingDrawnOne) + { + if ((dataPoints[i_ofPointForWhichToCheckThePrecedingDrawnOne].i_ofPrecedingPointFromWhichLineCanBeDrawn + 1) == i_ofPointForWhichToCheckThePrecedingDrawnOne) + { + //the two valid points are direct neighbors: + return false; + } + else + { + //there is a gap of invalid points between the two valid points: + //(this happens because of invalid X slots of the inbetween points, in which case these invalid points are not even drawn as low alpha (despite if they were only invalid in their Y slot)) + return true; + } + } + + void DrawNameAsText(bool lineHasDatapointsButNoneOfThemIsValid, bool atLeastOneDrawnPointHasBeenFound, int numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn, Vector3 mostRecentDrawnDataPoint_worldSpace, Vector3 highestDrawnPoint_worldSpace, Vector3 lowestDrawnPoint_worldSpace, float absWidthOfConnectionLines_worldSpace, float durationInSec, bool hiddenByNearerObjects) + { + if (name == null || name == "") + { + if (nameExtraInfo != null && nameExtraInfo != "") + { + name = "[nameless line]"; + } + } + + if (name != null && name != "") + { + float textSize = 0.04f * chart_thisLineIsPartOf.Height_inWorldSpace * nameText_sizeScaleFactor; + Vector3 textPosition; + DrawText.TextAnchorDXXL textAnchor; + Vector3 extraTextPosition; + DrawText.TextAnchorDXXL extraTextAnchor; + Vector3 topRightPos_ofChart; + + switch (namePosition) + { + case NamePosition.dynamicallyMoving_atLineEnd_towardsRight: + if (atLeastOneDrawnPointHasBeenFound) + { + textPosition = mostRecentDrawnDataPoint_worldSpace; + textAnchor = DrawText.TextAnchorDXXL.MiddleLeft; + DrawMainName(lineHasDatapointsButNoneOfThemIsValid, textPosition, textSize, textAnchor, durationInSec, hiddenByNearerObjects); + if (nameExtraInfo != null && nameExtraInfo != "") + { + extraTextPosition = textPosition + (DrawText.parsedTextSpecs.widthOfLongestLine + 0.16f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine) * chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + extraTextAnchor = DrawText.TextAnchorDXXL.UpperLeft; + DrawNameExtraInfo(extraTextPosition, extraTextAnchor, durationInSec, hiddenByNearerObjects); //relies on the preceding "DrawMainName" (due to using "DrawText.parsedTextSpecs") + } + } + else + { + DrawNames_for_fixedPosAtLeft_insideChart(lineHasDatapointsButNoneOfThemIsValid, textSize, numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn, durationInSec, hiddenByNearerObjects); + } + break; + case NamePosition.dynamicallyMoving_atLineEnd_towardsLeft: + if (atLeastOneDrawnPointHasBeenFound) + { + textPosition = mostRecentDrawnDataPoint_worldSpace; + textAnchor = DrawText.TextAnchorDXXL.MiddleRight; + DrawMainName(lineHasDatapointsButNoneOfThemIsValid, textPosition, textSize, textAnchor, durationInSec, hiddenByNearerObjects); + if (nameExtraInfo != null && nameExtraInfo != "") + { + extraTextPosition = textPosition - (DrawText.parsedTextSpecs.widthOfLongestLine + 0.16f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine) * chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + extraTextAnchor = DrawText.TextAnchorDXXL.UpperRight; + DrawNameExtraInfo(extraTextPosition, extraTextAnchor, durationInSec, hiddenByNearerObjects); //relies on the preceding "DrawMainName" (due to using "DrawText.parsedTextSpecs") + } + } + else + { + DrawNames_for_fixedPosAtLeft_insideChart(lineHasDatapointsButNoneOfThemIsValid, textSize, numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn, durationInSec, hiddenByNearerObjects); + } + break; + case NamePosition.dynamic_atLowestLinePos: + if (atLeastOneDrawnPointHasBeenFound) + { + textPosition = lowestDrawnPoint_worldSpace + chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * 0.5f * textSize - chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * (0.5f * absWidthOfConnectionLines_worldSpace); + textAnchor = DrawText.TextAnchorDXXL.UpperCenter; + DrawMainName(lineHasDatapointsButNoneOfThemIsValid, textPosition, textSize, textAnchor, durationInSec, hiddenByNearerObjects); + if (nameExtraInfo != null && nameExtraInfo != "") + { + extraTextPosition = textPosition + (0.5f * DrawText.parsedTextSpecs.widthOfLongestLine + 0.16f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine) * chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace - DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine * UtilitiesDXXL_Text.relLineDistance * chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace; + extraTextAnchor = DrawText.TextAnchorDXXL.LowerLeft; + DrawNameExtraInfo(extraTextPosition, extraTextAnchor, durationInSec, hiddenByNearerObjects); //relies on the preceding "DrawMainName" (due to using "DrawText.parsedTextSpecs") + } + } + else + { + DrawNames_for_fixedPosAtLeft_insideChart(lineHasDatapointsButNoneOfThemIsValid, textSize, numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn, durationInSec, hiddenByNearerObjects); + } + break; + case NamePosition.dynamic_atHighestLinePos: + if (atLeastOneDrawnPointHasBeenFound) + { + textPosition = highestDrawnPoint_worldSpace + chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * (0.5f * absWidthOfConnectionLines_worldSpace); + textAnchor = DrawText.TextAnchorDXXL.LowerCenter; + DrawMainName(lineHasDatapointsButNoneOfThemIsValid, textPosition, textSize, textAnchor, durationInSec, hiddenByNearerObjects); + if (nameExtraInfo != null && nameExtraInfo != "") + { + extraTextPosition = textPosition + (0.5f * DrawText.parsedTextSpecs.widthOfLongestLine + 0.16f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine) * chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + extraTextAnchor = DrawText.TextAnchorDXXL.LowerLeft; + DrawNameExtraInfo(extraTextPosition, extraTextAnchor, durationInSec, hiddenByNearerObjects); //relies on the preceding "DrawMainName" (due to using "DrawText.parsedTextSpecs") + } + } + else + { + DrawNames_for_fixedPosAtLeft_insideChart(lineHasDatapointsButNoneOfThemIsValid, textSize, numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn, durationInSec, hiddenByNearerObjects); + } + break; + case NamePosition.fixedPosAtRight_outsideOfChart: + topRightPos_ofChart = chart_thisLineIsPartOf.Position_worldspace + chart_thisLineIsPartOf.xAxis.AxisVector_inWorldSpace + chart_thisLineIsPartOf.yAxis.AxisVector_inWorldSpace; + textPosition = topRightPos_ofChart - chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * 1.75f * textSize * numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn; + textAnchor = DrawText.TextAnchorDXXL.MiddleLeft; + DrawMainName(lineHasDatapointsButNoneOfThemIsValid, textPosition, textSize, textAnchor, durationInSec, hiddenByNearerObjects); + if (nameExtraInfo != null && nameExtraInfo != "") + { + extraTextPosition = textPosition + (DrawText.parsedTextSpecs.widthOfLongestLine + 0.16f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine) * chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + extraTextAnchor = DrawText.TextAnchorDXXL.UpperLeft; + DrawNameExtraInfo(extraTextPosition, extraTextAnchor, durationInSec, hiddenByNearerObjects); //relies on the preceding "DrawMainName" (due to using "DrawText.parsedTextSpecs") + } + break; + case NamePosition.fixedPosAtRight_insideChart: + topRightPos_ofChart = chart_thisLineIsPartOf.Position_worldspace + chart_thisLineIsPartOf.xAxis.AxisVector_inWorldSpace + chart_thisLineIsPartOf.yAxis.AxisVector_inWorldSpace; + textPosition = topRightPos_ofChart - chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * 1.75f * textSize * numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn; + textAnchor = DrawText.TextAnchorDXXL.MiddleRight; + DrawMainName(lineHasDatapointsButNoneOfThemIsValid, textPosition, textSize, textAnchor, durationInSec, hiddenByNearerObjects); + if (nameExtraInfo != null && nameExtraInfo != "") + { + extraTextPosition = textPosition - (DrawText.parsedTextSpecs.widthOfLongestLine + 0.16f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine) * chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + extraTextAnchor = DrawText.TextAnchorDXXL.UpperRight; + DrawNameExtraInfo(extraTextPosition, extraTextAnchor, durationInSec, hiddenByNearerObjects); //relies on the preceding "DrawMainName" (due to using "DrawText.parsedTextSpecs") + } + break; + case NamePosition.fixedPosAtLeft_insideChart: + DrawNames_for_fixedPosAtLeft_insideChart(lineHasDatapointsButNoneOfThemIsValid, textSize, numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn, durationInSec, hiddenByNearerObjects); + break; + default: + UtilitiesDXXL_Log.PrintErrorCode("7"); + textPosition = chart_thisLineIsPartOf.Position_worldspace; + textAnchor = DrawText.TextAnchorDXXL.LowerLeft; + DrawMainName(lineHasDatapointsButNoneOfThemIsValid, textPosition, textSize, textAnchor, durationInSec, hiddenByNearerObjects); + if (nameExtraInfo != null && nameExtraInfo != "") + { + extraTextPosition = textPosition + (DrawText.parsedTextSpecs.widthOfLongestLine + 0.16f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine) * chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + extraTextAnchor = DrawText.TextAnchorDXXL.LowerLeft; + DrawNameExtraInfo(extraTextPosition, extraTextAnchor, durationInSec, hiddenByNearerObjects); //relies on the preceding "DrawMainName" (due to using "DrawText.parsedTextSpecs") + } + break; + } + } + } + + void DrawMainName(bool lineHasDatapointsButNoneOfThemIsValid, Vector3 textPosition, float textSize, DrawText.TextAnchorDXXL textAnchor, float durationInSec, bool hiddenByNearerObjects) + { + float autoLineBreakWidth = 0.0f; + if (lineHasDatapointsButNoneOfThemIsValid) + { + UtilitiesDXXL_Text.WriteFramed(name + " [ All " + dataPoints.Count + " datapoints of this line are invalid (meaning 'NaN' or 'Infinity')]", textPosition, Color, textSize, chart_thisLineIsPartOf.InternalRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, chart_thisLineIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Text.WriteFramed(name, textPosition, Color, textSize, chart_thisLineIsPartOf.InternalRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, chart_thisLineIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects); + } + } + + void DrawNameExtraInfo(Vector3 extraTextPosition, DrawText.TextAnchorDXXL extraTextAnchor, float durationInSec, bool hiddenByNearerObjects) + { + float extraTextSize = 0.01f * chart_thisLineIsPartOf.Height_inWorldSpace * nameText_sizeScaleFactor; + float autoLineBreakWidth_ofExtraText = 0.0f; + UtilitiesDXXL_Text.WriteFramed(nameExtraInfo, extraTextPosition, Color, extraTextSize, chart_thisLineIsPartOf.InternalRotation, extraTextAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth_ofExtraText, chart_thisLineIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects); + } + + void DrawNames_for_fixedPosAtLeft_insideChart(bool lineHasDatapointsButNoneOfThemIsValid, float textSize, int numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 topLeftPos_ofChart = chart_thisLineIsPartOf.Position_worldspace + chart_thisLineIsPartOf.yAxis.AxisVector_inWorldSpace; + Vector3 textPosition = topLeftPos_ofChart - chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * 1.75f * textSize * numberOfLinesWithValidDataPointsThatHaveAlreadyBeenDrawn; + DrawText.TextAnchorDXXL textAnchor = DrawText.TextAnchorDXXL.MiddleLeft; + DrawMainName(lineHasDatapointsButNoneOfThemIsValid, textPosition, textSize, textAnchor, durationInSec, hiddenByNearerObjects); + if (nameExtraInfo != null && nameExtraInfo != "") + { + Vector3 extraTextPosition = textPosition + (DrawText.parsedTextSpecs.widthOfLongestLine + 0.16f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine) * chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + DrawText.TextAnchorDXXL extraTextAnchor = DrawText.TextAnchorDXXL.UpperLeft; + DrawNameExtraInfo(extraTextPosition, extraTextAnchor, durationInSec, hiddenByNearerObjects); //relies on the preceding "DrawMainName" (due to using "DrawText.parsedTextSpecs") + } + } + + public void AddValue(float yValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + InternalAdd(true, false, GetCurrentAutomaticXValue(), yValue); + } + } + + public void AddValue(bool yValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + float yValue_asFloat = (yValue == true) ? 1.0f : 0.0f; + InternalAdd(true, false, GetCurrentAutomaticXValue(), yValue_asFloat); + } + } + + public void AddXYValue(Vector2 xyValueOfTheNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + InternalAdd(false, false, xyValueOfTheNewDataPoint.x, xyValueOfTheNewDataPoint.y); + } + } + + public void AddXYValue(float xValue, bool yValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + float yValue_asFloat = (yValue == true) ? 1.0f : 0.0f; + InternalAdd(false, false, xValue, yValue_asFloat); + } + } + + public void AddXYValue(float xValue, float yValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + InternalAdd(false, false, xValue, yValue); + } + } + + public void InternalAddPlaceholderDatapointForNonExistingListSlot(float xValue_fromOtherLineInsideListFromWhereThisPlaceholderGetsFilled) + { + InternalAdd(true, true, xValue_fromOtherLineInsideListFromWhereThisPlaceholderGetsFilled, float.NaN); + } + + public void InternalAddFromList(float yValue) + { + InternalAdd(true, false, GetCurrentAutomaticXValue(), yValue); + } + + void InternalAdd(bool xValueIsFromAutomaticSource, bool newDatapoint_isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList, float xValue, float yValue) + { + if (xValueIsFromAutomaticSource == false) { chart_thisLineIsPartOf.xAxis.ReportXValueFromNonAutomaticSource(); allXValuesCameFromAutomaticSource = false; } + InternalDXXL_DataPointOfChartLine newDataPoint = new InternalDXXL_DataPointOfChartLine(); + newDataPoint.validState = InternalDXXL_DataPointOfChartLine.GetValidStateOf_datapointToBeCreated(newDatapoint_isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList, xValue, yValue); + bool newPointIsValid = (newDataPoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid); + newDataPoint.xValue = xValue; + newDataPoint.yValue = yValue; + TryAddNotificationPoint_atTransitionFromInvalidPhaseAtLineStartToFirstValidPhase(newPointIsValid, xValue, yValue); + TryAddNotificationPoint_atChangeOfInvalidTypeInsideInvalidPhase(newPointIsValid, newDataPoint); + if (newPointIsValid) { mostCurrentValidXValue = xValue; mostCurrentValidYValue = yValue; } + TryAddNotificationPoint_atTransitionFromValidPhaseToInvalidPhase(newPointIsValid, newDataPoint); + newDataPoint.i_ofThisPointInsideContainingLine = dataPoints.Count; + newDataPoint.line_thisPointIsPartOf = this; + TryMarkPointWithEmphasizingCircle_dueTo_startOrEndOfValidPhase(ref newDataPoint); + TryMarkPointWithEmphasizingCircle_dueTo_forcedByUser(ref newDataPoint); + CheckIntersectionWithHorizThresholdLines(newDataPoint); + if (forceUpcomingNextCreatedConnectionLine_toLowAlpha == true) { newDataPoint.forceConnectionLineToLowAlpha = true; forceUpcomingNextCreatedConnectionLine_toLowAlpha = false; } + UpdatePosOfVisualizationOfMostCurrentValue(newDataPoint); + dataPoints.Add(newDataPoint); + turningPointDetector.AddNewDatapoint(dataPoints.Count - 1); + NoteIf_hasAtLeastOneValuePairOfValidData(newPointIsValid); + Update_highestYValue(yValue, newPointIsValid); + Update_lowestYValue(yValue, newPointIsValid); + Update_highestXValue(xValue, newPointIsValid); + Update_lowestXValue(xValue, newPointIsValid); + } + + void TryAddNotificationPoint_atTransitionFromInvalidPhaseAtLineStartToFirstValidPhase(bool newPointIsValid, float x_ofCurrentlyAddedPoint, float y_ofCurrentlyAddedPoint) + { + if (newPointIsValid) + { + if (float.IsNaN(mostCurrentValidYValue)) + { + //-> Currently added point is the first valid point of the line + if (dataPoints.Count > 0) + { + //-> The first valid dataPoint is not the first added point. There are invalid dataPoints with lower point-index: + InternalDXXL_DataPointOfChartLine thePrecedingDatapoint_thisIsGuaranteedInvalid = dataPoints[dataPoints.Count - 1]; + if (thePrecedingDatapoint_thisIsGuaranteedInvalid.validState == InternalDXXL_DataPointOfChartLine.ValidState.isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList) + { + AddPointOfInterestWithoutHorizOrVertLine(x_ofCurrentlyAddedPoint, y_ofCurrentlyAddedPoint, " Line '" + name + "':
The index of this line didn't exist in the collection before this point (=> the Length/Count of the collection was raised)."); + } + else + { + if (dataPoints.Count == 1) + { + AddPointOfInterestWithoutHorizOrVertLine(x_ofCurrentlyAddedPoint, y_ofCurrentlyAddedPoint, " Line '" + name + "':
The value before this point is invalid:
" + thePrecedingDatapoint_thisIsGuaranteedInvalid.GetInvalidTypeString()); + } + else + { + AddPointOfInterestWithoutHorizOrVertLine(x_ofCurrentlyAddedPoint, y_ofCurrentlyAddedPoint, " Line '" + name + "':
The values before this point are invalid. The preceding point has:
" + thePrecedingDatapoint_thisIsGuaranteedInvalid.GetInvalidTypeString()); + } + } + } + } + } + } + + void TryAddNotificationPoint_atChangeOfInvalidTypeInsideInvalidPhase(bool newPointIsValid, InternalDXXL_DataPointOfChartLine newDataPoint) + { + if (float.IsNaN(mostCurrentValidYValue) == false) //this ensures also "(dataPoints.Count > 0)" + { + //->There has already been a valid phase: + InternalDXXL_DataPointOfChartLine precedingDatapoint = dataPoints[dataPoints.Count - 1]; + if (newPointIsValid == false) + { + if (precedingDatapoint.validState != InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + //->Currently added point and preceding point are both invalid: + if (precedingDatapoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList && newDataPoint.validState != InternalDXXL_DataPointOfChartLine.ValidState.isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList) + { + AddPointOfInterestWithoutHorizOrVertLine(newDataPoint.xValue, mostCurrentValidYValue, " Line '" + name + "':
The line started again here (=> the Length/Count of the collection was raised), but it starts with this invalid value:
" + newDataPoint.GetInvalidTypeString()); + } + + if (precedingDatapoint.validState != InternalDXXL_DataPointOfChartLine.ValidState.isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList && newDataPoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList) + { + AddPointOfInterestWithoutHorizOrVertLine(precedingDatapoint.xValue, mostCurrentValidYValue, " Line '" + name + "':
This is the last point of the line before the index of the line doesn't exist in the collection anymore. (=> the Length/Count of the collection was lowered)."); + } + } + } + } + else + { + //-> There was no valid phase before the currently added invalid point: + //No notification is drawn, because + //1) There is not yet a yValue availalbe where the pointer could be mounted. + //2) "TryAddNotificationPoint_atTransitionFromInvalidPhaseAtLineStartToFirstValidPhase" will supply some information later as soon as the first valid phase starts, which answers at least the question: "Did the line start here (because the collection grew in Length/Count)?" or "Is the previous value NaN or Infinity?" + } + } + + void TryAddNotificationPoint_atTransitionFromValidPhaseToInvalidPhase(bool newPointIsValid, InternalDXXL_DataPointOfChartLine newDataPoint) + { + if (newPointIsValid == false) + { + if (float.IsNaN(mostCurrentValidYValue) == false) //this ensures also "(dataPoints.Count > 0)" + { + //-> The currently added data point is invalid, but the line already contains a valid point: + InternalDXXL_DataPointOfChartLine thePrecedingDatapoint = dataPoints[dataPoints.Count - 1]; + if (thePrecedingDatapoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + InternalDXXL_DataPointOfChartLine thePrecedingDatapoint_thisIsGuaranteedValid = thePrecedingDatapoint; + if (newDataPoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList) + { + AddPointOfInterestWithoutHorizOrVertLine(thePrecedingDatapoint_thisIsGuaranteedValid.xValue, thePrecedingDatapoint_thisIsGuaranteedValid.yValue, " Line '" + name + "':
The index of this line doesn't exist in the collection anymore after this point. (=> the Length/Count of the collection was lowered)."); + } + else + { + AddPointOfInterestWithoutHorizOrVertLine(thePrecedingDatapoint_thisIsGuaranteedValid.xValue, thePrecedingDatapoint_thisIsGuaranteedValid.yValue, " Line '" + name + "':
At least one value after this one is invalid. The following value has:
" + newDataPoint.GetInvalidTypeString()); + } + } + } + } + } + + void TryMarkPointWithEmphasizingCircle_dueTo_startOrEndOfValidPhase(ref InternalDXXL_DataPointOfChartLine theNewDataPoint) + { + if (dataPoints.Count > 0) + { + InternalDXXL_DataPointOfChartLine thePrecedingDatapoint = dataPoints[dataPoints.Count - 1]; + if (theNewDataPoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + if (thePrecedingDatapoint.validState != InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + theNewDataPoint.hasLittleEmphasizingCircleAroundPoint = true; + } + } + else + { + if (thePrecedingDatapoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + thePrecedingDatapoint.hasLittleEmphasizingCircleAroundPoint = true; + } + } + } + } + + void TryMarkPointWithEmphasizingCircle_dueTo_forcedByUser(ref InternalDXXL_DataPointOfChartLine theNewDataPoint) + { + if (markNextNewlyCreatedPointWithEmphasizingCircle) + { + if (theMarkingOfTheNextNewlyCreatedPointWithEmphasizingCircle_isOnlyDoneIfThisPointIsValid) + { + if (theNewDataPoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + theNewDataPoint.hasLittleEmphasizingCircleAroundPoint = true; + } + } + else + { + theNewDataPoint.hasLittleEmphasizingCircleAroundPoint = true; + } + markNextNewlyCreatedPointWithEmphasizingCircle = false; + } + } + + void NoteIf_hasAtLeastOneValuePairOfValidData(bool newPointIsValid) + { + if (hasAtLeastOneValuePairOfValidData == false) + { + if (newPointIsValid) + { + hasAtLeastOneValuePairOfValidData = true; + } + } + } + + void Update_highestYValue(float new_yValue, bool newPointIsValid) + { + if (newPointIsValid) + { + highestYValue = Mathf.Max(highestYValue, new_yValue); + + if (chart_thisLineIsPartOf.overallMaxYValue_includingHiddenLines == float.NaN) + { + //-> is the first added data point of all lines + chart_thisLineIsPartOf.overallMaxYValue_includingHiddenLines = new_yValue; + } + else + { + chart_thisLineIsPartOf.overallMaxYValue_includingHiddenLines = Mathf.Max(chart_thisLineIsPartOf.overallMaxYValue_includingHiddenLines, new_yValue); + } + } + } + + void Update_lowestYValue(float new_yValue, bool newPointIsValid) + { + if (newPointIsValid) + { + lowestYValue = Mathf.Min(lowestYValue, new_yValue); + + if (chart_thisLineIsPartOf.overallMinYValue_includingHiddenLines == float.NaN) + { + //-> is the first added data point of all lines + chart_thisLineIsPartOf.overallMinYValue_includingHiddenLines = new_yValue; + } + else + { + chart_thisLineIsPartOf.overallMinYValue_includingHiddenLines = Mathf.Min(chart_thisLineIsPartOf.overallMinYValue_includingHiddenLines, new_yValue); + } + } + } + + void Update_highestXValue(float new_xValue, bool newPointIsValid) + { + if (newPointIsValid) + { + highestXValue = Mathf.Max(highestXValue, new_xValue); + + if (chart_thisLineIsPartOf.overallMaxXValue_includingHiddenLines == float.NaN) + { + //-> is the first added data point of all lines + chart_thisLineIsPartOf.overallMaxXValue_includingHiddenLines = new_xValue; + } + else + { + chart_thisLineIsPartOf.overallMaxXValue_includingHiddenLines = Mathf.Max(chart_thisLineIsPartOf.overallMaxXValue_includingHiddenLines, new_xValue); + } + } + } + + void Update_lowestXValue(float new_xValue, bool newPointIsValid) + { + if (newPointIsValid) + { + lowestXValue = Mathf.Min(lowestXValue, new_xValue); + + if (chart_thisLineIsPartOf.overallMinXValue_includingHiddenLines == float.NaN) + { + //-> is the first added data point of all lines + chart_thisLineIsPartOf.overallMinXValue_includingHiddenLines = new_xValue; + } + else + { + chart_thisLineIsPartOf.overallMinXValue_includingHiddenLines = Mathf.Min(chart_thisLineIsPartOf.overallMinXValue_includingHiddenLines, new_xValue); + } + } + } + + public float GetMostCurrentValidXValue() + { + if (float.IsNaN(mostCurrentValidXValue)) + { + UtilitiesDXXL_Log.PrintErrorCode("5"); //Why? The calling function already ensured that there is at least one valid data pair... + return 0.0f; + } + else + { + return mostCurrentValidXValue; + } + } + + public float GetMostCurrentValidYValue() + { + if (float.IsNaN(mostCurrentValidYValue)) + { + UtilitiesDXXL_Log.PrintErrorCode("6"); //Why? The calling function already ensured that there is at least one valid data pair... + return 0.0f; + } + else + { + return mostCurrentValidYValue; + } + } + + public float GetLowestXValue() + { + return lowestXValue; + } + + public float GetLowestYValue() + { + return lowestYValue; + } + + public float GetHighestXValue() + { + return highestXValue; + } + + public float GetHighestYValue() + { + return highestYValue; + } + + public float GetLowestXValue_insideRestricedYSpan(float minAllowedY, float maxAllowedY) + { + float lowestXValue = float.PositiveInfinity; + for (int i = 0; i < dataPoints.Count; i++) + { + float yValue_ofCurrentDatapoint = dataPoints[i].yValue; + if ((yValue_ofCurrentDatapoint >= minAllowedY) && (yValue_ofCurrentDatapoint <= maxAllowedY)) + { + float xValue_ofCurrentDatapoint = dataPoints[i].xValue; + if (xValue_ofCurrentDatapoint < lowestXValue) { lowestXValue = xValue_ofCurrentDatapoint; } + } + } + return lowestXValue; + } + + public float GetLowestYValue_insideRestricedXSpan(float minAllowedX, float maxAllowedX) + { + float lowestYValue = float.PositiveInfinity; + for (int i = 0; i < dataPoints.Count; i++) + { + float xValue_ofCurrentDatapoint = dataPoints[i].xValue; + if ((xValue_ofCurrentDatapoint >= minAllowedX) && (xValue_ofCurrentDatapoint <= maxAllowedX)) + { + float yValue_ofCurrentDatapoint = dataPoints[i].yValue; + if (yValue_ofCurrentDatapoint < lowestYValue) { lowestYValue = yValue_ofCurrentDatapoint; } + } + } + return lowestYValue; + } + + public float GetHighestXValue_insideRestricedYSpan(float minAllowedY, float maxAllowedY) + { + float highestXValue = float.NegativeInfinity; + for (int i = 0; i < dataPoints.Count; i++) + { + float yValue_ofCurrentDatapoint = dataPoints[i].yValue; + if ((yValue_ofCurrentDatapoint >= minAllowedY) && (yValue_ofCurrentDatapoint <= maxAllowedY)) + { + float xValue_ofCurrentDatapoint = dataPoints[i].xValue; + if (xValue_ofCurrentDatapoint > highestXValue) { highestXValue = xValue_ofCurrentDatapoint; } + } + } + return highestXValue; + } + + public float GetHighestYValue_insideRestricedXSpan(float minAllowedX, float maxAllowedX) + { + float highestYValue = float.NegativeInfinity; + for (int i = 0; i < dataPoints.Count; i++) + { + float xValue_ofCurrentDatapoint = dataPoints[i].xValue; + if ((xValue_ofCurrentDatapoint >= minAllowedX) && (xValue_ofCurrentDatapoint <= maxAllowedX)) + { + float yValue_ofCurrentDatapoint = dataPoints[i].yValue; + if (yValue_ofCurrentDatapoint > highestYValue) { highestYValue = yValue_ofCurrentDatapoint; } + } + } + return highestYValue; + } + + public float GetCurrentAutomaticXValue() + { + switch (chart_thisLineIsPartOf.xAxis.sourceOfAutomaticValues) + { + case ChartAxis.SourceOfAutomaticValues.fixedStepForEachValueAdding: + return (float)dataPoints.Count; + case ChartAxis.SourceOfAutomaticValues.fixedStep_followingTheManualIncrementFunction: + return (float)chart_thisLineIsPartOf.GetManuallyIncrementedXPos(); + case ChartAxis.SourceOfAutomaticValues.frameCount: + return (float)Time.frameCount; + case ChartAxis.SourceOfAutomaticValues.fixedTime: + return Time.fixedTime; + case ChartAxis.SourceOfAutomaticValues.fixedUnscaledTime: + return Time.fixedUnscaledTime; + case ChartAxis.SourceOfAutomaticValues.realtimeSinceStartup: + return Time.realtimeSinceStartup; + case ChartAxis.SourceOfAutomaticValues.time: + return Time.time; + case ChartAxis.SourceOfAutomaticValues.timeSinceLevelLoad: + return Time.timeSinceLevelLoad; + case ChartAxis.SourceOfAutomaticValues.unscaledTime: + return Time.unscaledTime; + case ChartAxis.SourceOfAutomaticValues.editorTimeSinceStartup: +#if UNITY_EDITOR + return (float)UnityEditor.EditorApplication.timeSinceStartup; +#else + return Time.realtimeSinceStartup; +#endif + default: + Debug.LogError("XValuesSource of " + chart_thisLineIsPartOf.xAxis.sourceOfAutomaticValues + " not implemented."); + return 0.0f; + } + } + + public void Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.IsDrawnBecause_theSingleComponentOfMulticomponentData_thisLineRepresents_isEnabledChecker IsDrawnCheckerFunction_thatRepresentsThe_singleComponentOfMulticomponentData) + { + IsDrawnBecause_theSingleComponentOfMulticomponentData_thisLineRepresents_isEnabled = IsDrawnCheckerFunction_thatRepresentsThe_singleComponentOfMulticomponentData; + } + + public bool CheckIfLineIsDrawn() + { + return (lineSpecsForInspector.currentHideLineState == false) && CheckIfLineIsDrawn_accordingToTheEnabledStateOfThe_singleComponentOfMulticomponentDataThisLineRepresents(); + } + + bool CheckIfLineIsDrawn_accordingToTheEnabledStateOfThe_singleComponentOfMulticomponentDataThisLineRepresents() + { + return IsDrawnBecause_theSingleComponentOfMulticomponentData_thisLineRepresents_isEnabled(chart_thisLineIsPartOf.dataComponentsThatAreDrawn); + } + + public bool IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(bool includeLinesThatRepresentDisabledMultiComponentTypes = false) + { + if (includeLinesThatRepresentDisabledMultiComponentTypes || CheckIfLineIsDrawn_accordingToTheEnabledStateOfThe_singleComponentOfMulticomponentDataThisLineRepresents()) + { + if (dataPoints.Count > 0) + { + return true; + } + } + return false; + } + + public bool IsUnhidden_andWithAtLeastOneValidOrInvalidDatapoint(bool includeLinesThatRepresentDisabledMultiComponentTypes = false) + { + if (includeLinesThatRepresentDisabledMultiComponentTypes || CheckIfLineIsDrawn_accordingToTheEnabledStateOfThe_singleComponentOfMulticomponentDataThisLineRepresents()) + { + if (dataPoints.Count > 0) + { + if (lineSpecsForInspector.currentHideLineState == false) + { + return true; + } + } + } + return false; + } + + public void AddPointOfInterest(PointOfInterest newPointOfInterest) + { + newPointOfInterest.chart_thisPointIsPartOf = chart_thisLineIsPartOf; + newPointOfInterest.chartLine_thisPointIsPartOf = this; + pointsOfInterest.Add(newPointOfInterest); + } + + public PointOfInterest AddPointOfInterest(Vector2 position, string textToDisplay = null, DrawBasics.LineStyle horizLinestyle = DrawBasics.LineStyle.invisible, DrawBasics.LineStyle vertLinestyle = DrawBasics.LineStyle.invisible, float alphaOfColor_relToParent = 1.0f, bool getsDeletedOnClear = true) + { + return AddPointOfInterest(position.x, position.y, textToDisplay, horizLinestyle, vertLinestyle, alphaOfColor_relToParent, getsDeletedOnClear); + } + + public PointOfInterest AddPointOfInterest(float position_x, float position_y, string textToDisplay = null, DrawBasics.LineStyle horizLinestyle = DrawBasics.LineStyle.invisible, DrawBasics.LineStyle vertLinestyle = DrawBasics.LineStyle.invisible, float alphaOfColor_relToParent = 1.0f, bool getsDeletedOnClear = true) + { + //the function returns the new point of interest, so it can then be accessed and be further modified. + if (textToDisplay == null || textToDisplay == "") + { + if (horizLinestyle == DrawBasics.LineStyle.invisible) { horizLinestyle = DrawBasics.LineStyle.solid; } + if (vertLinestyle == DrawBasics.LineStyle.invisible) { vertLinestyle = DrawBasics.LineStyle.solid; } + } + + Color colorOfPoint = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(Color, alphaOfColor_relToParent); + PointOfInterest newPointOfInterest = new PointOfInterest(position_x, position_y, colorOfPoint, chart_thisLineIsPartOf, this, textToDisplay); + newPointOfInterest.isDeletedOnClear = getsDeletedOnClear; + newPointOfInterest.xValue.lineStyle = vertLinestyle; + newPointOfInterest.yValue.lineStyle = horizLinestyle; + pointsOfInterest.Add(newPointOfInterest); + return newPointOfInterest; + } + + void DeletePointsOfInterestOnClear() + { + for (int i = pointsOfInterest.Count - 1; i >= 0; i--) + { + if (pointsOfInterest[i].isDeletedOnClear) + { + pointsOfInterest.RemoveAt(i); + } + } + turningPointDetector.Clear(); + } + + bool thePointsOfInterestOfThisLineArePartOfTheChart; + public int Internal_Set_isDrawnInNextPass_forAllPointsOfInterest(int stillAvailableTextBoxes_inUpperRightCorner) + { + //Needs "line.Draw()" called beforehand (which sets "thePointsOfInterestOfThisLineArePartOfTheChart") + if (thePointsOfInterestOfThisLineArePartOfTheChart) + { + for (int i = pointsOfInterest.Count - 1; i >= 0; i--) //-> counting DOWNWARD means: only the NEWEST textBoxes get drawn + { + stillAvailableTextBoxes_inUpperRightCorner = pointsOfInterest[i].Internal_Set_isDrawnInNextPass(stillAvailableTextBoxes_inUpperRightCorner); + } + } + return stillAvailableTextBoxes_inUpperRightCorner; + } + + public Vector3 DrawPointsOfInterest(Vector3 next_lowAnchorPositionOfText_inWorldspace, float durationInSec, bool hiddenByNearerObjects) + { + //use ChartDrawing.Draw() instead + + //Use ChartDrawing.Draw()(<-link) instead. + //Needs "line.Draw()" called beforehand (which sets "thePointsOfInterestOfThisLineArePartOfTheChart") + if (thePointsOfInterestOfThisLineArePartOfTheChart) + { + UpdateColorsOfIntersectionPointMarkers(); //-> cannot be set onSetColor, because Unity serialization doesn't support C# properties + UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted = UtilitiesDXXL_Math.SkewedDirection.upRight; + for (int i = pointsOfInterest.Count - 1; i >= 0; i--) //-> counting DOWNWARDS, because this produces less crossings of the pointerLines in most cases for PointOfInterestBoxes on the upperLeftSide. Though this has the disadvantage, that the "newest/oldest"-ordering is the other way round than the PointOfInterestBoxes on the upperRightSide. + { + next_lowAnchorPositionOfText_inWorldspace = pointsOfInterest[i].TryDraw(next_lowAnchorPositionOfText_inWorldspace, cornerOfChartWhereTextBoxIsMounted, durationInSec, hiddenByNearerObjects); + } + } + return next_lowAnchorPositionOfText_inWorldspace; + } + + void AddPointOfInterestWithoutHorizOrVertLine(float xPos, float yPos, string textToDisplay) + { + PointOfInterest newPointOfInterest = AddPointOfInterest(xPos, yPos, textToDisplay, DrawBasics.LineStyle.invisible, DrawBasics.LineStyle.invisible, 1.0f, true); + newPointOfInterest.drawTextBoxIfPointIsOutsideOfChartArea = true; + newPointOfInterest.forceColorOfParent = true; + } + + + public void AddHorizontalThresholdLine(float yPosition, bool lineItselfCountsToLowerArea = false, Color colorOfHorizLine = default(Color), bool hideThresholdLineAndShowOnlyTheIntersectionPointers = false) + { + //if you want to add the threshold to all lines at once you can use the "AddHorizontalThresholdLine"-version in "chartDrawing" + //If you don't want to see the intersection points and only want to draw a horizontal line that doesn't do anything you can use 'chart.AddFixedHorizLine' instead. + //"forceColor": if the color should be different from the line color + // "lineItselfCountsToLowerArea" determines if it counts as an intersection if the line doesn't cross the threshold but runs exactly onto it. + + if (UtilitiesDXXL_Math.FloatIsInvalid(yPosition)) + { + Debug.LogError("Cannot create threshold line at " + yPosition); + return; + } + + if (hideThresholdLineAndShowOnlyTheIntersectionPointers == false) + { + if (UtilitiesDXXL_Colors.IsDefaultColor(colorOfHorizLine)) + { + colorOfHorizLine = UtilitiesDXXL_Colors.GetSimilarColorWithSlightlyOtherBrightnessValue(Color); + } + + PointOfInterest pointOfInterst_visualizingTheHorizThresholdLine = new PointOfInterest(0.0f, yPosition, colorOfHorizLine, Chart_thisLineIsPartOf, this, null); + pointOfInterst_visualizingTheHorizThresholdLine.isDeletedOnClear = false; + pointOfInterst_visualizingTheHorizThresholdLine.forceColorOfParent = false; + pointOfInterst_visualizingTheHorizThresholdLine.xValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterst_visualizingTheHorizThresholdLine.yValue.lineStyle = DrawBasics.LineStyle.solid; + pointOfInterst_visualizingTheHorizThresholdLine.yValue.labelText = "Threshold"; + pointOfInterst_visualizingTheHorizThresholdLine.yValue.drawCoordinateAsText = true; + pointOfInterst_visualizingTheHorizThresholdLine.yValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + pointsOfInterest.Add(pointOfInterst_visualizingTheHorizThresholdLine); + } + + InternalDXXL_HorizontalThresholdLine newHorizThresholdLine = new InternalDXXL_HorizontalThresholdLine(yPosition, this, lineItselfCountsToLowerArea); + horizontalThresholdLines.Add(newHorizThresholdLine); + } + + void CheckIntersectionWithHorizThresholdLines(InternalDXXL_DataPointOfChartLine theNewDataPoint) + { + if (dataPoints.Count > 0) + { + InternalDXXL_DataPointOfChartLine thePrecedingDatapoint = dataPoints[dataPoints.Count - 1]; + for (int i = 0; i < horizontalThresholdLines.Count; i++) + { + PointOfInterest createdIntersection = horizontalThresholdLines[i].CheckIntersection(thePrecedingDatapoint, theNewDataPoint); + if (createdIntersection != null) + { + pointsOfInterest.Add(createdIntersection); + pointsOfInterest_fromIntersectionsWithHorizLines.Add(createdIntersection); + } + } + } + } + + void UpdateColorsOfIntersectionPointMarkers() + { + if (pointsOfInterest_fromIntersectionsWithHorizLines.Count > 0) + { + Color colorOfGeneratedIntersectionPoints = UtilitiesDXXL_Colors.GetSimilarColorWithSlightlyOtherBrightnessValue(Color); + colorOfGeneratedIntersectionPoints.a = 1.0f; + for (int i = 0; i < pointsOfInterest_fromIntersectionsWithHorizLines.Count; i++) + { + pointsOfInterest_fromIntersectionsWithHorizLines[i].SetWholeColor(colorOfGeneratedIntersectionPoints); + } + } + } + + public void InternalAssignRepresentedGameobject(GameObject newGameobject) + { + gameobject_thatThisLineCurrentlyRepresents = newGameobject; + } + + public void ForceMostCurrentConnectionLine_toLowAlpha() + { + if (dataPoints.Count > 0) + { + dataPoints[dataPoints.Count - 1].forceConnectionLineToLowAlpha = true; + } + } + + bool forceUpcomingNextCreatedConnectionLine_toLowAlpha = false; + public void ForceUpcomingNextCreatedConnectionLine_toLowAlpha() + { + forceUpcomingNextCreatedConnectionLine_toLowAlpha = true; + } + + bool markNextNewlyCreatedPointWithEmphasizingCircle = false; + bool theMarkingOfTheNextNewlyCreatedPointWithEmphasizingCircle_isOnlyDoneIfThisPointIsValid = true; + public void AddEmphasizingCircleToMostCurrentPoint(bool onlyIfPointIsValid = true, bool andMarkNextNewlyCreatedPointAsWell = false) + { + //if you want to mark only the next data point that gets created you can use "AddEmphasizingCircleToUpcomingNextDatapointThatGetsCreated" + AddEmphasizingCircleToAPoint(dataPoints.Count - 1, onlyIfPointIsValid); + markNextNewlyCreatedPointWithEmphasizingCircle = andMarkNextNewlyCreatedPointAsWell; + theMarkingOfTheNextNewlyCreatedPointWithEmphasizingCircle_isOnlyDoneIfThisPointIsValid = onlyIfPointIsValid; + } + + public void AddEmphasizingCircleToUpcomingNextDatapointThatGetsCreated(bool onlyIfPointIsValid = true) + { + //if you want to mark the most current already existing data point you can use "AddEmphasizingCircleToMostCurrentPoint" + markNextNewlyCreatedPointWithEmphasizingCircle = true; + theMarkingOfTheNextNewlyCreatedPointWithEmphasizingCircle_isOnlyDoneIfThisPointIsValid = onlyIfPointIsValid; + } + + public void AddEmphasizingCircleToAPoint(int i_ofDataPoint, bool onlyIfPointIsValid = true) + { + if (i_ofDataPoint >= 0) + { + if (i_ofDataPoint < dataPoints.Count) + { + if (onlyIfPointIsValid) + { + if (dataPoints[i_ofDataPoint].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + dataPoints[i_ofDataPoint].hasLittleEmphasizingCircleAroundPoint = true; + } + } + else + { + dataPoints[i_ofDataPoint].hasLittleEmphasizingCircleAroundPoint = true; + } + } + } + } + + void SetIfVisualizationOfSpecialApexPointsIsDisplayed() + { + SetIfVisualizationOfMostCurrentValueIsDisplayed(); + turningPointDetector.SetIfVisualizationIsDisplayed(); + } + + void SetIfVisualizationOfMostCurrentValueIsDisplayed() + { + if (dataPoints.Count > 0) + { + if (representsValuesFromAddedLists && (chart_thisLineIsPartOf.displayHighlightingOfMostCurrentValues_forLinesFromLists == false)) + { + pointOfInterest_thatHighlightsTheMostCurrentValue.xValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterest_thatHighlightsTheMostCurrentValue.yValue.lineStyle = DrawBasics.LineStyle.invisible; + return; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(alpha_ofHighlighterForMostCurrentValue_xDim)) + { + pointOfInterest_thatHighlightsTheMostCurrentValue.xValue.lineStyle = DrawBasics.LineStyle.invisible; + } + else + { + pointOfInterest_thatHighlightsTheMostCurrentValue.xValue.lineStyle = DrawBasics.LineStyle.solid; + pointOfInterest_thatHighlightsTheMostCurrentValue.xValue.color = new Color(1, 1, 1, alpha_ofHighlighterForMostCurrentValue_xDim); //-> only for setting alpha. The actual color gets forced from lineParent + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(alpha_ofHighlighterForMostCurrentValue_yDim)) + { + pointOfInterest_thatHighlightsTheMostCurrentValue.yValue.lineStyle = DrawBasics.LineStyle.invisible; + } + else + { + pointOfInterest_thatHighlightsTheMostCurrentValue.yValue.lineStyle = DrawBasics.LineStyle.solid; + pointOfInterest_thatHighlightsTheMostCurrentValue.yValue.color = new Color(1, 1, 1, alpha_ofHighlighterForMostCurrentValue_yDim); //-> only for setting alpha. The actual color gets forced from lineParent + } + if (disableMinMaxYVisualizers_dueTo_lineRepresentsBoolValues) { pointOfInterest_thatHighlightsTheMostCurrentValue.yValue.lineStyle = DrawBasics.LineStyle.invisible; } + } + else + { + pointOfInterest_thatHighlightsTheMostCurrentValue.xValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterest_thatHighlightsTheMostCurrentValue.yValue.lineStyle = DrawBasics.LineStyle.invisible; + } + } + + PointOfInterest CreatePointOfInterestThatHighlightsTheMostCurrentValue() + { + PointOfInterest created_pointOfInterest = new PointOfInterest(0.0f, 0.0f, DrawBasics.defaultColor, chart_thisLineIsPartOf, this, null); + created_pointOfInterest.drawTextBoxIfPointIsOutsideOfChartArea = false; + created_pointOfInterest.isDeletedOnClear = false; + created_pointOfInterest.forceColorOfParent = true; + + created_pointOfInterest.xValue.lineStyle = DrawBasics.LineStyle.solid; + created_pointOfInterest.xValue.drawCoordinateAsText = true; + created_pointOfInterest.xValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.axisToPoint; + + created_pointOfInterest.yValue.lineStyle = DrawBasics.LineStyle.solid; + created_pointOfInterest.yValue.drawCoordinateAsText = false; //-> coordinate is coded into the labelText + created_pointOfInterest.yValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.axisToPoint; + + return created_pointOfInterest; + } + + void UpdatePosOfVisualizationOfMostCurrentValue(InternalDXXL_DataPointOfChartLine newDataPoint) + { + if (newDataPoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + pointOfInterest_thatHighlightsTheMostCurrentValue.xValue.position = newDataPoint.xValue; + pointOfInterest_thatHighlightsTheMostCurrentValue.yValue.position = newDataPoint.yValue; + + string labelText_atHorizLine = null; + if (displayDeltaAtHighlighterForMostCurrentValue) + { + if (dataPoints.Count > 0) + { + InternalDXXL_DataPointOfChartLine thePrecedingDatapoint = dataPoints[dataPoints.Count - 1]; + if (thePrecedingDatapoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + float deltaSincePrecedingValue = newDataPoint.yValue - thePrecedingDatapoint.yValue; + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(newDataPoint.yValue, thePrecedingDatapoint.yValue) || UtilitiesDXXL_Math.ApproximatelyZero(deltaSincePrecedingValue)) + { + labelText_atHorizLine = "" + newDataPoint.yValue + " ( +/- 0)"; + } + else + { + if (deltaSincePrecedingValue > 0.0f) + { + Color risingValueColor = UtilitiesDXXL_Colors.green_boolTrue; + risingValueColor.a = alpha_ofHighlighterForMostCurrentValue_yDim * 2.0f; + labelText_atHorizLine = "" + newDataPoint.yValue + " (" + deltaSincePrecedingValue + ")"; + } + else + { + Color fallingValueColor = UtilitiesDXXL_Colors.red_boolFalse; + fallingValueColor.a = alpha_ofHighlighterForMostCurrentValue_yDim * 2.0f; + labelText_atHorizLine = "" + newDataPoint.yValue + " (" + deltaSincePrecedingValue + ")"; + } + } + } + } + } + + if (labelText_atHorizLine == null) { labelText_atHorizLine = "" + newDataPoint.yValue; } + pointOfInterest_thatHighlightsTheMostCurrentValue.yValue.labelText = labelText_atHorizLine; + } + } + + float Get_absWidthOfConnectionLines_worldSpace() + { + if (UtilitiesDXXL_Math.ApproximatelyZero(LineWidth_relToChartHeight)) + { + return 0.0f; + } + else + { + return Mathf.Abs(LineWidth_relToChartHeight * Chart_thisLineIsPartOf.Height_inWorldSpace); + } + } + + float Get_absWidthOfPointVisualisatorLines_worldSpace() + { + if (UtilitiesDXXL_Math.ApproximatelyZero(pointVisualisationLineWidth_relToChartHeight)) + { + return 0.0f; + } + else + { + return Mathf.Abs(pointVisualisationLineWidth_relToChartHeight * Chart_thisLineIsPartOf.Height_inWorldSpace); + } + } + + Vector3 Get_amplitudeDir_forNonZeroWidthLines(InternalDXXL_Plane chartPlane) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(LineWidth_relToChartHeight) && UtilitiesDXXL_Math.ApproximatelyZero(pointVisualisationLineWidth_relToChartHeight)) + { + return default(Vector3); + } + else + { + if (UtilitiesDXXL_Math.IsQuaternionIdentity(chart_thisLineIsPartOf.InternalRotation)) + { + return default(Vector3); + } + else + { + Vector3 aVectorInsideTheChartPlane = chartPlane.Get_projectionOfVectorOntoPlane(UtilitiesDXXL_Math.arbitrarySeldomDir_normalized_precalced); + Vector3 aVectorInsideTheChartPlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(aVectorInsideTheChartPlane); + Vector3 aVectorInsideTheChartPlane_veryLong = aVectorInsideTheChartPlane_normalized * 10000000.0f; + //-> Making it very long reduces jitter artifacts, that sometimes occur when drawing nonZeroWidth-Lines: + //-> Reproducing unwanted jitter: + //---> Turn the chart to non-default-orientation + //---> Make the chart size very small. + //---> Draw a line that makes a smooth round curve and therefore tangents all possible directions (like a parabola) + //---> Raise the lineWidth + //---> To emphasize the jitter: Scroll X during ComponentInspectionPhase. + //-> The problem may come from: float calculation imprecision during automatic amplitude calculation in "UtilitiesDXXL_LineAmplitudeAndTextDirCalculation" + //-> A clean solution would be not to use "arbitrarySeldomDir_normalized_precalced" but calculate "amplitudeDir_forNonZeroWidthLines" per datapoint via cross product, but this can get expensive for many datapoints. + return aVectorInsideTheChartPlane_veryLong; + } + } + } + + public void InitInspectionViaComponent() + { + lineSpecsForInspector.Reconstruct_arrayWithNeighboringDatapointValues(); + } + + public string GetNameCompound(bool addSpacesBeside_namePartsConnectingMinus) + { + if (addSpacesBeside_namePartsConnectingMinus) + { + if (name == null || name == "") + { + if (nameExtraInfo == null || nameExtraInfo == "") + { + return "[nameless]"; + } + else + { + return ("[nameless] - " + nameExtraInfo); + } + } + else + { + if (nameExtraInfo == null || nameExtraInfo == "") + { + return name; + } + else + { + return (name + " - " + nameExtraInfo); + } + } + } + else + { + if (name == null || name == "") + { + if (nameExtraInfo == null || nameExtraInfo == "") + { + return "[nameless]"; + } + else + { + return ("[nameless]-" + nameExtraInfo); + } + } + else + { + if (nameExtraInfo == null || nameExtraInfo == "") + { + return name; + } + else + { + return (name + "-" + nameExtraInfo); + } + } + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/ChartLine.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/ChartLine.cs.meta new file mode 100644 index 0000000..1d0e4b2 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/ChartLine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 051a68451ba2f49419c91170b3f49f91 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/ChartLines.cs b/Runtime/DrawDebugLibrary/charts/line charts/ChartLines.cs new file mode 100644 index 0000000..c2663d3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/ChartLines.cs @@ -0,0 +1,2257 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class ChartLines + { + static float default_luminanceOfLineColors = 0.5f; + private float luminanceOfLineColors = default_luminanceOfLineColors; + public float LuminanceOfLineColors + { + get { return luminanceOfLineColors; } + set + { + value = Mathf.Clamp01(value); + ReassignLuminanceToLinecolors(luminanceOfLineColors, value); + luminanceOfLineColors = value; + } + } + + ChartDrawing chart_theseLinesArePartOf; + List horizontalThresholdsInitializer = new List(); + + //default colors: + static float default_colorHue_of_xDimension = 0.0f; + static float default_colorHue_of_yDimension = 0.3333333f; + static float default_colorHue_of_zDimension = 0.6666666f; + static float default_colorHue_of_wDimension = 0.2f; + static float default_colorHue_of_premadeLine_float = 0.14f; + static float default_colorHue_of_premadeLine_int = 0.465f; + // static float default_colorHue_of_premadeLine_bool = 0.88f; + static float default_colorHue_of_premadeLine_bool = 0.05f; + //premade lines: + List preMadeLines = new List(); + List userMadeLines = new List(); + public ChartLine premadeLine_float; + public ChartLine premadeLine_int; + public ChartLine premadeLine_vector2_x; + public ChartLine premadeLine_vector2_y; + public ChartLine premadeLine_vector3_x; + public ChartLine premadeLine_vector3_y; + public ChartLine premadeLine_vector3_z; + public ChartLine premadeLine_vector4_x; + public ChartLine premadeLine_vector4_y; + public ChartLine premadeLine_vector4_z; + public ChartLine premadeLine_vector4_w; + public ChartLine premadeLine_color_r; + public ChartLine premadeLine_color_g; + public ChartLine premadeLine_color_b; + public ChartLine premadeLine_color_a; + public ChartLine premadeLine_rotation_eulerX; + public ChartLine premadeLine_rotation_eulerY; + public ChartLine premadeLine_rotation_eulerZ; + public ChartLine premadeLine_bool; + //premade lines for transform: + //int i_premadeLine_markingTheFirstOneOfTheTransformLines; + //int i_premadeLine_markingTheLastOneOfTheTransformLines; + public ChartLine premadeLine_transform_localPosition_x; + public ChartLine premadeLine_transform_localPosition_y; + public ChartLine premadeLine_transform_localPosition_z; + public ChartLine premadeLine_transform_localEulerAngle_x; + public ChartLine premadeLine_transform_localEulerAngle_y; + public ChartLine premadeLine_transform_localEulerAngle_z; + public ChartLine premadeLine_transform_localScale_x; + public ChartLine premadeLine_transform_localScale_y; + public ChartLine premadeLine_transform_localScale_z; + public ChartLine premadeLine_transform_globalPosition_x; + public ChartLine premadeLine_transform_globalPosition_y; + public ChartLine premadeLine_transform_globalPosition_z; + public ChartLine premadeLine_transform_globalEulerAngle_x; + public ChartLine premadeLine_transform_globalEulerAngle_y; + public ChartLine premadeLine_transform_globalEulerAngle_z; + public ChartLine premadeLine_transform_lossyScale_x; + public ChartLine premadeLine_transform_lossyScale_y; + public ChartLine premadeLine_transform_lossyScale_z; + //premade lines for lists: + List> listOfPremadeListsOfLines = new List>(); + List preMadeListOfLines_float; + List preMadeListOfLines_int; + List preMadeListOfLines_vector2_x; + List preMadeListOfLines_vector2_y; + List preMadeListOfLines_vector3_x; + List preMadeListOfLines_vector3_y; + List preMadeListOfLines_vector3_z; + List preMadeListOfLines_rotation_eulerX; + List preMadeListOfLines_rotation_eulerY; + List preMadeListOfLines_rotation_eulerZ; + List preMadeListOfLines_bool; + List preMadeListOfLines_transforms_localPosition_x; + List preMadeListOfLines_transforms_localPosition_y; + List preMadeListOfLines_transforms_localPosition_z; + List preMadeListOfLines_transforms_localEulerAngle_x; + List preMadeListOfLines_transforms_localEulerAngle_y; + List preMadeListOfLines_transforms_localEulerAngle_z; + List preMadeListOfLines_transforms_localScale_x; + List preMadeListOfLines_transforms_localScale_y; + List preMadeListOfLines_transforms_localScale_z; + List preMadeListOfLines_transforms_globalPosition_x; + List preMadeListOfLines_transforms_globalPosition_y; + List preMadeListOfLines_transforms_globalPosition_z; + List preMadeListOfLines_transforms_globalEulerAngle_x; + List preMadeListOfLines_transforms_globalEulerAngle_y; + List preMadeListOfLines_transforms_globalEulerAngle_z; + List preMadeListOfLines_transforms_lossyScale_x; + List preMadeListOfLines_transforms_lossyScale_y; + List preMadeListOfLines_transforms_lossyScale_z; + + public ChartLines(ChartDrawing chart_theseLinesArePartOf) + { + this.chart_theseLinesArePartOf = chart_theseLinesArePartOf; + + premadeLine_float = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_premadeLine_float, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_float.Name = "float"; + preMadeLines.Add(premadeLine_float); + + premadeLine_int = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_premadeLine_int, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_int.Name = "int"; + preMadeLines.Add(premadeLine_int); + + premadeLine_vector2_x = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_vector2_x.Name = "x"; + premadeLine_vector2_x.NameExtraInfo = "of Vector2"; + premadeLine_vector2_x.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_vector2_x_isEnabled); + preMadeLines.Add(premadeLine_vector2_x); + + premadeLine_vector2_y = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_vector2_y.Name = "y"; + premadeLine_vector2_y.NameExtraInfo = "of Vector2"; + premadeLine_vector2_y.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_vector2_y_isEnabled); + preMadeLines.Add(premadeLine_vector2_y); + + premadeLine_vector3_x = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_vector3_x.Name = "x"; + premadeLine_vector3_x.NameExtraInfo = "of Vector3"; + premadeLine_vector3_x.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_vector3_x_isEnabled); + preMadeLines.Add(premadeLine_vector3_x); + + premadeLine_vector3_y = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_vector3_y.Name = "y"; + premadeLine_vector3_y.NameExtraInfo = "of Vector3"; + premadeLine_vector3_y.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_vector3_y_isEnabled); + preMadeLines.Add(premadeLine_vector3_y); + + premadeLine_vector3_z = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_vector3_z.Name = "z"; + premadeLine_vector3_z.NameExtraInfo = "of Vector3"; + premadeLine_vector3_z.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_vector3_z_isEnabled); + preMadeLines.Add(premadeLine_vector3_z); + + premadeLine_vector4_x = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_vector4_x.Name = "x"; + premadeLine_vector4_x.NameExtraInfo = "of Vector4"; + premadeLine_vector4_x.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_vector4_x_isEnabled); + preMadeLines.Add(premadeLine_vector4_x); + + premadeLine_vector4_y = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_vector4_y.Name = "y"; + premadeLine_vector4_y.NameExtraInfo = "of Vector4"; + premadeLine_vector4_y.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_vector4_y_isEnabled); + preMadeLines.Add(premadeLine_vector4_y); + + premadeLine_vector4_z = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_vector4_z.Name = "z"; + premadeLine_vector4_z.NameExtraInfo = "of Vector4"; + premadeLine_vector4_z.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_vector4_z_isEnabled); + preMadeLines.Add(premadeLine_vector4_z); + + premadeLine_vector4_w = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_wDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_vector4_w.Name = "w"; + premadeLine_vector4_w.NameExtraInfo = "of Vector4"; + premadeLine_vector4_w.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_vector4_w_isEnabled); + preMadeLines.Add(premadeLine_vector4_w); + + premadeLine_color_r = new ChartLine(Color.red, chart_theseLinesArePartOf); + premadeLine_color_r.Name = "red"; + premadeLine_color_r.NameExtraInfo = "color component"; + premadeLine_color_r.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_color_r_isEnabled); + preMadeLines.Add(premadeLine_color_r); + + premadeLine_color_g = new ChartLine(Color.green, chart_theseLinesArePartOf); + premadeLine_color_g.Name = "green"; + premadeLine_color_g.NameExtraInfo = "color component"; + premadeLine_color_g.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_color_g_isEnabled); + preMadeLines.Add(premadeLine_color_g); + + premadeLine_color_b = new ChartLine(Color.blue, chart_theseLinesArePartOf); + premadeLine_color_b.Name = "blue"; + premadeLine_color_b.NameExtraInfo = "color component"; + premadeLine_color_b.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_color_b_isEnabled); + preMadeLines.Add(premadeLine_color_b); + + premadeLine_color_a = new ChartLine(Color.white, chart_theseLinesArePartOf); + premadeLine_color_a.Name = "alpha"; + premadeLine_color_a.NameExtraInfo = "color component"; + premadeLine_color_a.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_color_a_isEnabled); + preMadeLines.Add(premadeLine_color_a); + + premadeLine_rotation_eulerX = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_rotation_eulerX.Name = "x"; + premadeLine_rotation_eulerX.NameExtraInfo = "rotation euler [degrees]"; + premadeLine_rotation_eulerX.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_rotation_eulerX_isEnabled); + preMadeLines.Add(premadeLine_rotation_eulerX); + + premadeLine_rotation_eulerY = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_rotation_eulerY.Name = "y"; + premadeLine_rotation_eulerY.NameExtraInfo = "rotation euler [degrees]"; + premadeLine_rotation_eulerY.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_rotation_eulerY_isEnabled); + preMadeLines.Add(premadeLine_rotation_eulerY); + + premadeLine_rotation_eulerZ = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_rotation_eulerZ.Name = "z"; + premadeLine_rotation_eulerZ.NameExtraInfo = "rotation euler [degrees]"; + premadeLine_rotation_eulerZ.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_rotation_eulerZ_isEnabled); + preMadeLines.Add(premadeLine_rotation_eulerZ); + + premadeLine_bool = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_premadeLine_bool, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_bool.Name = "bool"; + premadeLine_bool.disableMinMaxYVisualizers_dueTo_lineRepresentsBoolValues = true; + preMadeLines.Add(premadeLine_bool); + + //i_premadeLine_markingTheFirstOneOfTheTransformLines = preMadeLines.Count; + + premadeLine_transform_localPosition_x = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_localPosition_x.Name = "x"; + premadeLine_transform_localPosition_x.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_localPosition_x_isEnabled); + preMadeLines.Add(premadeLine_transform_localPosition_x); + + premadeLine_transform_localPosition_y = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_localPosition_y.Name = "y"; + premadeLine_transform_localPosition_y.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_localPosition_y_isEnabled); + preMadeLines.Add(premadeLine_transform_localPosition_y); + + premadeLine_transform_localPosition_z = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_localPosition_z.Name = "z"; + premadeLine_transform_localPosition_z.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_localPosition_z_isEnabled); + preMadeLines.Add(premadeLine_transform_localPosition_z); + + premadeLine_transform_localEulerAngle_x = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_localEulerAngle_x.Name = "x"; + premadeLine_transform_localEulerAngle_x.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_x_isEnabled); + preMadeLines.Add(premadeLine_transform_localEulerAngle_x); + + premadeLine_transform_localEulerAngle_y = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_localEulerAngle_y.Name = "y"; + premadeLine_transform_localEulerAngle_y.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_y_isEnabled); + preMadeLines.Add(premadeLine_transform_localEulerAngle_y); + + premadeLine_transform_localEulerAngle_z = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_localEulerAngle_z.Name = "z"; + premadeLine_transform_localEulerAngle_z.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_z_isEnabled); + preMadeLines.Add(premadeLine_transform_localEulerAngle_z); + + premadeLine_transform_localScale_x = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_localScale_x.Name = "x"; + premadeLine_transform_localScale_x.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_localScale_x_isEnabled); + preMadeLines.Add(premadeLine_transform_localScale_x); + + premadeLine_transform_localScale_y = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_localScale_y.Name = "y"; + premadeLine_transform_localScale_y.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_localScale_y_isEnabled); + preMadeLines.Add(premadeLine_transform_localScale_y); + + premadeLine_transform_localScale_z = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_localScale_z.Name = "z"; + premadeLine_transform_localScale_z.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_localScale_z_isEnabled); + preMadeLines.Add(premadeLine_transform_localScale_z); + + premadeLine_transform_globalPosition_x = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_globalPosition_x.Name = "x"; + premadeLine_transform_globalPosition_x.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_globalPosition_x_isEnabled); + preMadeLines.Add(premadeLine_transform_globalPosition_x); + + premadeLine_transform_globalPosition_y = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_globalPosition_y.Name = "y"; + premadeLine_transform_globalPosition_y.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_globalPosition_y_isEnabled); + preMadeLines.Add(premadeLine_transform_globalPosition_y); + + premadeLine_transform_globalPosition_z = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_globalPosition_z.Name = "z"; + premadeLine_transform_globalPosition_z.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_globalPosition_z_isEnabled); + preMadeLines.Add(premadeLine_transform_globalPosition_z); + + premadeLine_transform_globalEulerAngle_x = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_globalEulerAngle_x.Name = "x"; + premadeLine_transform_globalEulerAngle_x.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_x_isEnabled); + preMadeLines.Add(premadeLine_transform_globalEulerAngle_x); + + premadeLine_transform_globalEulerAngle_y = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_globalEulerAngle_y.Name = "y"; + premadeLine_transform_globalEulerAngle_y.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_y_isEnabled); + preMadeLines.Add(premadeLine_transform_globalEulerAngle_y); + + premadeLine_transform_globalEulerAngle_z = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_globalEulerAngle_z.Name = "z"; + premadeLine_transform_globalEulerAngle_z.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_z_isEnabled); + preMadeLines.Add(premadeLine_transform_globalEulerAngle_z); + + premadeLine_transform_lossyScale_x = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_lossyScale_x.Name = "x"; + premadeLine_transform_lossyScale_x.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_lossyScale_x_isEnabled); + preMadeLines.Add(premadeLine_transform_lossyScale_x); + + premadeLine_transform_lossyScale_y = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_lossyScale_y.Name = "y"; + premadeLine_transform_lossyScale_y.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_lossyScale_y_isEnabled); + preMadeLines.Add(premadeLine_transform_lossyScale_y); + + premadeLine_transform_lossyScale_z = new ChartLine(SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, default_luminanceOfLineColors), chart_theseLinesArePartOf); + premadeLine_transform_lossyScale_z.Name = "z"; + premadeLine_transform_lossyScale_z.Assign_singleComponentOfMulticomponentData_thisLineRepresents(UtilitiesDXXL_ChartLine.DrawIf_lossyScale_z_isEnabled); + preMadeLines.Add(premadeLine_transform_lossyScale_z); + + //i_premadeLine_markingTheLastOneOfTheTransformLines = preMadeLines.Count - 1; + } + + public void Clear() + { + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].Clear(); + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].Clear(); + } + listOfPremadeListsOfLines = new List>(); + preMadeListOfLines_float = null; + preMadeListOfLines_int = null; + preMadeListOfLines_vector2_x = null; + preMadeListOfLines_vector2_y = null; + preMadeListOfLines_vector3_x = null; + preMadeListOfLines_vector3_y = null; + preMadeListOfLines_vector3_z = null; + preMadeListOfLines_rotation_eulerX = null; + preMadeListOfLines_rotation_eulerY = null; + preMadeListOfLines_rotation_eulerZ = null; + preMadeListOfLines_bool = null; + preMadeListOfLines_transforms_localPosition_x = null; + preMadeListOfLines_transforms_localPosition_y = null; + preMadeListOfLines_transforms_localPosition_z = null; + preMadeListOfLines_transforms_localEulerAngle_x = null; + preMadeListOfLines_transforms_localEulerAngle_y = null; + preMadeListOfLines_transforms_localEulerAngle_z = null; + preMadeListOfLines_transforms_localScale_x = null; + preMadeListOfLines_transforms_localScale_y = null; + preMadeListOfLines_transforms_localScale_z = null; + preMadeListOfLines_transforms_globalPosition_x = null; + preMadeListOfLines_transforms_globalPosition_y = null; + preMadeListOfLines_transforms_globalPosition_z = null; + preMadeListOfLines_transforms_globalEulerAngle_x = null; + preMadeListOfLines_transforms_globalEulerAngle_y = null; + preMadeListOfLines_transforms_globalEulerAngle_z = null; + preMadeListOfLines_transforms_lossyScale_x = null; + preMadeListOfLines_transforms_lossyScale_y = null; + preMadeListOfLines_transforms_lossyScale_z = null; + } + + public void Draw(InternalDXXL_Plane chartPlane, float durationInSec, bool hiddenByNearerObjects) + { + //Use "chartDrawing.Draw" instead + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = chart_theseLinesArePartOf; + int numberOfAlreadyDrawnLines = 0; + for (int i = 0; i < preMadeLines.Count; i++) + { + bool lineWasDrawn = preMadeLines[i].Draw(chartPlane, numberOfAlreadyDrawnLines, chart_theseLinesArePartOf.xAxis.ValueMarkingLowerEndOfTheAxis, chart_theseLinesArePartOf.xAxis.ValueMarkingUpperEndOfTheAxis, chart_theseLinesArePartOf.yAxis.ValueMarkingLowerEndOfTheAxis, chart_theseLinesArePartOf.yAxis.ValueMarkingUpperEndOfTheAxis, durationInSec, hiddenByNearerObjects); + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = chart_theseLinesArePartOf; + if (lineWasDrawn) { numberOfAlreadyDrawnLines++; } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + bool lineWasDrawn = userMadeLines[i].Draw(chartPlane, numberOfAlreadyDrawnLines, chart_theseLinesArePartOf.xAxis.ValueMarkingLowerEndOfTheAxis, chart_theseLinesArePartOf.xAxis.ValueMarkingUpperEndOfTheAxis, chart_theseLinesArePartOf.yAxis.ValueMarkingLowerEndOfTheAxis, chart_theseLinesArePartOf.yAxis.ValueMarkingUpperEndOfTheAxis, durationInSec, hiddenByNearerObjects); + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = chart_theseLinesArePartOf; + if (lineWasDrawn) { numberOfAlreadyDrawnLines++; } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + bool lineWasDrawn = listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].Draw(chartPlane, numberOfAlreadyDrawnLines, chart_theseLinesArePartOf.xAxis.ValueMarkingLowerEndOfTheAxis, chart_theseLinesArePartOf.xAxis.ValueMarkingUpperEndOfTheAxis, chart_theseLinesArePartOf.yAxis.ValueMarkingLowerEndOfTheAxis, chart_theseLinesArePartOf.yAxis.ValueMarkingUpperEndOfTheAxis, durationInSec, hiddenByNearerObjects); + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = chart_theseLinesArePartOf; + if (lineWasDrawn) { numberOfAlreadyDrawnLines++; } + } + } + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = null; + } + + GameObject gameobject_thatDeliveredThePreviousValue; + public void AddValue(Transform yValueOfNewDataPoint) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + if (yValueOfNewDataPoint == null) + { + Debug.LogError("Chart: Cannot add value, because Transform is null."); + return; + } + + bool isFirstValueOfThisGameobject = false; + if (gameobject_thatDeliveredThePreviousValue == null) + { + isFirstValueOfThisGameobject = true; + gameobject_thatDeliveredThePreviousValue = yValueOfNewDataPoint.gameObject; + } + else + { + if (gameobject_thatDeliveredThePreviousValue != yValueOfNewDataPoint.gameObject) + { + AddPointOfInterestForChangingValueSourceGameobject(premadeLine_transform_localPosition_x.GetCurrentAutomaticXValue(), gameobject_thatDeliveredThePreviousValue, yValueOfNewDataPoint.gameObject); + isFirstValueOfThisGameobject = true; + gameobject_thatDeliveredThePreviousValue = yValueOfNewDataPoint.gameObject; + } + } + + AddValuesToTheTransformLines(yValueOfNewDataPoint, isFirstValueOfThisGameobject); + } + } + + void AddValuesToTheTransformLines(Transform yValueOfNewDataPoint, bool isFirstValueOfThisGameobject) + { + //use chartDrawing.AddValue() instead + AddValueToATransformLine(premadeLine_transform_localPosition_x, yValueOfNewDataPoint.localPosition.x, isFirstValueOfThisGameobject, "local position", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_localPosition_y, yValueOfNewDataPoint.localPosition.y, isFirstValueOfThisGameobject, "local position", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_localPosition_z, yValueOfNewDataPoint.localPosition.z, isFirstValueOfThisGameobject, "local position", yValueOfNewDataPoint.gameObject); + + AddValueToATransformLine(premadeLine_transform_localEulerAngle_x, yValueOfNewDataPoint.localEulerAngles.x, isFirstValueOfThisGameobject, "local euler angles", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_localEulerAngle_y, yValueOfNewDataPoint.localEulerAngles.y, isFirstValueOfThisGameobject, "local euler angles", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_localEulerAngle_z, yValueOfNewDataPoint.localEulerAngles.z, isFirstValueOfThisGameobject, "local euler angles", yValueOfNewDataPoint.gameObject); + + AddValueToATransformLine(premadeLine_transform_localScale_x, yValueOfNewDataPoint.localScale.x, isFirstValueOfThisGameobject, "local scale", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_localScale_y, yValueOfNewDataPoint.localScale.y, isFirstValueOfThisGameobject, "local scale", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_localScale_z, yValueOfNewDataPoint.localScale.z, isFirstValueOfThisGameobject, "local scale", yValueOfNewDataPoint.gameObject); + + AddValueToATransformLine(premadeLine_transform_globalPosition_x, yValueOfNewDataPoint.position.x, isFirstValueOfThisGameobject, "global position", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_globalPosition_y, yValueOfNewDataPoint.position.y, isFirstValueOfThisGameobject, "global position", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_globalPosition_z, yValueOfNewDataPoint.position.z, isFirstValueOfThisGameobject, "global position", yValueOfNewDataPoint.gameObject); + + AddValueToATransformLine(premadeLine_transform_globalEulerAngle_x, yValueOfNewDataPoint.eulerAngles.x, isFirstValueOfThisGameobject, "global euler angles", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_globalEulerAngle_y, yValueOfNewDataPoint.eulerAngles.y, isFirstValueOfThisGameobject, "global euler angles", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_globalEulerAngle_z, yValueOfNewDataPoint.eulerAngles.z, isFirstValueOfThisGameobject, "global euler angles", yValueOfNewDataPoint.gameObject); + + AddValueToATransformLine(premadeLine_transform_lossyScale_x, yValueOfNewDataPoint.lossyScale.x, isFirstValueOfThisGameobject, "lossy scale", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_lossyScale_y, yValueOfNewDataPoint.lossyScale.y, isFirstValueOfThisGameobject, "lossy scale", yValueOfNewDataPoint.gameObject); + AddValueToATransformLine(premadeLine_transform_lossyScale_z, yValueOfNewDataPoint.lossyScale.z, isFirstValueOfThisGameobject, "lossy scale", yValueOfNewDataPoint.gameObject); + } + + void AddValueToATransformLine(ChartLine thisLine, float addedYValue, bool isFirstValueOfThisGameobject, string lineNameExtraInfo, GameObject gameobject_thatDeliversTheValue) + { + thisLine.AddValue(addedYValue); + if (isFirstValueOfThisGameobject) + { + thisLine.NameExtraInfo = lineNameExtraInfo + " (of " + gameobject_thatDeliversTheValue.name + ")"; + thisLine.InternalAssignRepresentedGameobject(gameobject_thatDeliversTheValue); + } + } + + public void AddValuesFromList_toListWithFloatLines(List yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_float, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfFloats_preAllocated, UtilitiesDXXL_ChartLine.DoDrawBecauseLineDoesntRepresentMultiComponentData, UtilitiesDXXL_Math.DimensionNullable.none, "(float)"); + } + } + + public void AddValuesFromArray_toListWithFloatLines(float[] yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines(ref preMadeListOfLines_float, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfFloats_preAllocated, UtilitiesDXXL_ChartLine.DoDrawBecauseLineDoesntRepresentMultiComponentData, UtilitiesDXXL_Math.DimensionNullable.none, "(float)"); + } + } + + public void AddValuesFromList_toListWithIntLines(List yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_int, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfInts_preAllocated, UtilitiesDXXL_ChartLine.DoDrawBecauseLineDoesntRepresentMultiComponentData, UtilitiesDXXL_Math.DimensionNullable.none, "(int)"); + } + } + + public void AddValuesFromArray_toListWithIntLines(int[] yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines(ref preMadeListOfLines_int, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfInts_preAllocated, UtilitiesDXXL_ChartLine.DoDrawBecauseLineDoesntRepresentMultiComponentData, UtilitiesDXXL_Math.DimensionNullable.none, "(int)"); + } + } + + public void AddValuesFromList_toListWithVector2Lines(List yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_vector2_x, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfVector2s_xComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_vector2_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, "of Vector2"); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_vector2_y, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfVector2s_yComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_vector2_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, "of Vector2"); + } + } + + public void AddValuesFromArray_toListWithVector2Lines(Vector2[] yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines(ref preMadeListOfLines_vector2_x, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfVector2s_xComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_vector2_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, "of Vector2"); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_vector2_y, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfVector2s_yComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_vector2_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, "of Vector2"); + } + } + + public void AddValuesFromList_toListWithVector3Lines(List yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_vector3_x, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfVector3s_xComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_vector3_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, "of Vector3"); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_vector3_y, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfVector3s_yComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_vector3_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, "of Vector3"); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_vector3_z, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfVector3s_zComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_vector3_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, "of Vector3"); + } + } + + public void AddValuesFromArray_toListWithVector3Lines(Vector3[] yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines(ref preMadeListOfLines_vector3_x, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfVector3s_xComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_vector3_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, "of Vector3"); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_vector3_y, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfVector3s_yComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_vector3_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, "of Vector3"); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_vector3_z, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfVector3s_zComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_vector3_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, "of Vector3"); + } + } + + public void AddValuesFromList_toListWithQuaternionLines(List yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_rotation_eulerX, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfQuaternions_eulerXComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_rotation_eulerX_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, "(euler angles)"); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_rotation_eulerY, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfQuaternions_eulerYComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_rotation_eulerY_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, "(euler angles)"); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_rotation_eulerZ, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfQuaternions_eulerZComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_rotation_eulerZ_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, "(euler angles)"); + } + } + + public void AddValuesFromArray_toListWithQuaternionLines(Quaternion[] yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines(ref preMadeListOfLines_rotation_eulerX, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfQuaternions_eulerXComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_rotation_eulerX_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, "(euler angles)"); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_rotation_eulerY, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfQuaternions_eulerYComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_rotation_eulerY_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, "(euler angles)"); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_rotation_eulerZ, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfQuaternions_eulerZComponent_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_rotation_eulerZ_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, "(euler angles)"); + } + } + + public void AddValuesFromList_toListWithBoolLines(List yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_bool, false, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfBools_preAllocated, UtilitiesDXXL_ChartLine.DoDrawBecauseLineDoesntRepresentMultiComponentData, UtilitiesDXXL_Math.DimensionNullable.none, "(bool)"); + } + } + + public void AddValuesFromArray_toListWithBoolLines(bool[] yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + AddValueCollectionSlots_toLines(ref preMadeListOfLines_bool, false, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfBools_preAllocated, UtilitiesDXXL_ChartLine.DoDrawBecauseLineDoesntRepresentMultiComponentData, UtilitiesDXXL_Math.DimensionNullable.none, "(bool)"); + } + } + + public void AddValuesFromList_toListWithGameobjectLines(List yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + TrySetPointsOfInterest_forChangingGameobjectsInCollectionSlots(yValues); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localPosition_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_localPosition_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localPosition_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_localPosition_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localPosition_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_localPosition_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localEulerAngle_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_localEulerAngle_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localEulerAngle_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_localEulerAngle_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localEulerAngle_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_localEulerAngle_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localScale_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_localScale_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localScale_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_localScale_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localScale_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_localScale_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalPosition_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_globalPosition_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalPosition_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_globalPosition_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalPosition_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_globalPosition_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalEulerAngle_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_globalEulerAngle_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalEulerAngle_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_globalEulerAngle_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalEulerAngle_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_globalEulerAngle_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_lossyScale_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_lossyScale_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_lossyScale_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_lossyScale_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_lossyScale_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfGameobjects_lossyScale_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + } + } + + public void AddValuesFromArray_toListWithGameobjectLines(GameObject[] yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + TrySetPointsOfInterest_forChangingGameobjectsInCollectionSlots(yValues); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localPosition_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_localPosition_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localPosition_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_localPosition_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localPosition_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_localPosition_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localEulerAngle_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_localEulerAngle_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localEulerAngle_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_localEulerAngle_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localEulerAngle_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_localEulerAngle_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localScale_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_localScale_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localScale_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_localScale_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localScale_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_localScale_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalPosition_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_globalPosition_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalPosition_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_globalPosition_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalPosition_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_globalPosition_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalEulerAngle_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_globalEulerAngle_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalEulerAngle_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_globalEulerAngle_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalEulerAngle_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_globalEulerAngle_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_lossyScale_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_lossyScale_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_lossyScale_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_lossyScale_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_lossyScale_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfGameobjects_lossyScale_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + } + } + + public void AddValuesFromList_toListWithTransformLines(List yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + TrySetPointsOfInterest_forChangingGameobjectsInCollectionSlots(yValues); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localPosition_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_localPosition_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localPosition_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_localPosition_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localPosition_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_localPosition_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localEulerAngle_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_localEulerAngle_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localEulerAngle_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_localEulerAngle_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localEulerAngle_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_localEulerAngle_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localScale_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_localScale_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localScale_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_localScale_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_localScale_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_localScale_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalPosition_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_globalPosition_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalPosition_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_globalPosition_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalPosition_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_globalPosition_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalEulerAngle_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_globalEulerAngle_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalEulerAngle_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_globalEulerAngle_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_globalEulerAngle_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_globalEulerAngle_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_lossyScale_x, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_lossyScale_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_lossyScale_y, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_lossyScale_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines>(ref preMadeListOfLines_transforms_lossyScale_z, true, yValues, yValues.Count, UtilitiesDXXL_ChartDrawing.GetYValueFrom_listOfTransforms_lossyScale_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + } + } + + public void AddValuesFromArray_toListWithTransformLines(Transform[] yValues) + { + //use chartDrawing.AddValues_eachIndexIsALine() instead + + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + TrySetPointsOfInterest_forChangingGameobjectsInCollectionSlots(yValues); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localPosition_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_localPosition_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localPosition_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_localPosition_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localPosition_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_localPosition_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localPosition_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localEulerAngle_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_localEulerAngle_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localEulerAngle_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_localEulerAngle_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localEulerAngle_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_localEulerAngle_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localEulerAngle_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localScale_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_localScale_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localScale_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_localScale_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_localScale_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_localScale_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_localScale_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalPosition_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_globalPosition_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalPosition_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_globalPosition_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalPosition_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_globalPosition_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalPosition_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalEulerAngle_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_globalEulerAngle_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalEulerAngle_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_globalEulerAngle_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_globalEulerAngle_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_globalEulerAngle_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_globalEulerAngle_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_lossyScale_x, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_lossyScale_x_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_x_isEnabled, UtilitiesDXXL_Math.DimensionNullable.x, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_lossyScale_y, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_lossyScale_y_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_y_isEnabled, UtilitiesDXXL_Math.DimensionNullable.y, null); + AddValueCollectionSlots_toLines(ref preMadeListOfLines_transforms_lossyScale_z, true, yValues, yValues.Length, UtilitiesDXXL_ChartDrawing.GetYValueFrom_arrayOfTransforms_lossyScale_z_preAllocated, UtilitiesDXXL_ChartLine.DrawIf_lossyScale_z_isEnabled, UtilitiesDXXL_Math.DimensionNullable.z, null); + } + } + + void AddValueCollectionSlots_toLines(ref List concernedPremadeListOfLines, bool dataSourceIsFromGameobjectRespTransform, CollectionWithYValues yValues, int count_ofCollectionWithYValues, UtilitiesDXXL_ChartDrawing.FlexibleGetYValueFromCollection FunctionThatObtainsYValueOfGenericCollection, UtilitiesDXXL_ChartLine.IsDrawnBecause_theSingleComponentOfMulticomponentData_thisLineRepresents_isEnabledChecker FunctionThatAssignsTheMultiComponentComponentThisLineRepresents, UtilitiesDXXL_Math.DimensionNullable vectorDimensionThisListOfLinesRepresents, string lineNameExtraInfo_forNonGameObjectDataSources) + { + if (yValues == null) + { + Debug.LogError("Chart: Cannot add values, because list is null."); + return; + } + + if (concernedPremadeListOfLines == null) + { + concernedPremadeListOfLines = new List(); + listOfPremadeListsOfLines.Add(concernedPremadeListOfLines); + } + + ChartLine lineOfList_withMostDataPoints_beforeCurrentlyAddedOne = Get_lineOfList_withMostDataPoints_beforeCurrentlyAddedOne(concernedPremadeListOfLines); + int numberOfDataPoints_ofLineOfThisListWithMostDataPoints_beforeCurrentlyAddedOne = (lineOfList_withMostDataPoints_beforeCurrentlyAddedOne == null) ? 0 : lineOfList_withMostDataPoints_beforeCurrentlyAddedOne.dataPoints.Count; + for (int i_insideNewValuesListThatEachMarkASeparateLine = 0; i_insideNewValuesListThatEachMarkASeparateLine < count_ofCollectionWithYValues; i_insideNewValuesListThatEachMarkASeparateLine++) + { + float addedYValue_asFloat = FunctionThatObtainsYValueOfGenericCollection(yValues, i_insideNewValuesListThatEachMarkASeparateLine, out GameObject gameobjectInCurrSlotOfAddedNewValuesList, out string lineNameExtraInfo_forTransformsAndGameObjects); + CreateNewLineForCurrListSlot(ref concernedPremadeListOfLines, i_insideNewValuesListThatEachMarkASeparateLine, dataSourceIsFromGameobjectRespTransform, gameobjectInCurrSlotOfAddedNewValuesList, lineNameExtraInfo_forTransformsAndGameObjects, lineNameExtraInfo_forNonGameObjectDataSources, FunctionThatAssignsTheMultiComponentComponentThisLineRepresents, vectorDimensionThisListOfLinesRepresents); + TryAssignGameobject_toCurrSlotsExistingLineWhichUntilNowHadANullGameobject(concernedPremadeListOfLines, i_insideNewValuesListThatEachMarkASeparateLine, dataSourceIsFromGameobjectRespTransform, gameobjectInCurrSlotOfAddedNewValuesList, lineNameExtraInfo_forTransformsAndGameObjects); + BackwardFillGapOfLine_forSlotsThatWereTemporarlyNotContainedInTheList(concernedPremadeListOfLines, i_insideNewValuesListThatEachMarkASeparateLine, numberOfDataPoints_ofLineOfThisListWithMostDataPoints_beforeCurrentlyAddedOne, lineOfList_withMostDataPoints_beforeCurrentlyAddedOne); + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].InternalAddFromList(addedYValue_asFloat); + TryReassignNewGameobject_toCurrSlotsLineWhichUntilNowHadADifferentGameobject(concernedPremadeListOfLines, i_insideNewValuesListThatEachMarkASeparateLine, dataSourceIsFromGameobjectRespTransform, gameobjectInCurrSlotOfAddedNewValuesList, lineNameExtraInfo_forTransformsAndGameObjects); + } + } + + ChartLine Get_lineOfList_withMostDataPoints_beforeCurrentlyAddedOne(List concernedListOfLines) + { + if (concernedListOfLines == null) + { + return null; + } + else + { + if (concernedListOfLines.Count == 0) + { + return null; + } + else + { + int currMaxDataPointsOfALine = 0; + ChartLine returnedLine = concernedListOfLines[0]; + for (int i = 0; i < concernedListOfLines.Count; i++) + { + if (concernedListOfLines[i].dataPoints.Count > currMaxDataPointsOfALine) + { + currMaxDataPointsOfALine = concernedListOfLines[i].dataPoints.Count; + returnedLine = concernedListOfLines[i]; + } + } + return returnedLine; + } + } + } + + void CreateNewLineForCurrListSlot(ref List concernedPremadeListOfLines, int i_insideNewValuesListThatEachMarkASeparateLine, bool dataSourceIsFromGameobjectRespTransform, GameObject gameobjectInCurrSlotOfAddedNewValuesList, string lineNameExtraInfo_forTransformsAndGameObjects, string lineNameExtraInfo_forNonGameObjectDataSources, UtilitiesDXXL_ChartLine.IsDrawnBecause_theSingleComponentOfMulticomponentData_thisLineRepresents_isEnabledChecker FunctionThatAssignsTheMultiComponentComponentThisLineRepresents, UtilitiesDXXL_Math.DimensionNullable vectorDimensionThisListOfLinesRepresents) + { + if (concernedPremadeListOfLines.Count <= i_insideNewValuesListThatEachMarkASeparateLine) + { + ChartLine newlyCreatedLine = new ChartLine(default(Color), chart_theseLinesArePartOf); + newlyCreatedLine.representsValuesFromAddedLists = true; + AddExistingHorizThresholdsToNewlyCreatedLine(ref newlyCreatedLine); + concernedPremadeListOfLines.Add(newlyCreatedLine); + + switch (vectorDimensionThisListOfLinesRepresents) + { + case UtilitiesDXXL_Math.DimensionNullable.x: + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].Name = "i=" + i_insideNewValuesListThatEachMarkASeparateLine + " x"; + break; + case UtilitiesDXXL_Math.DimensionNullable.y: + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].Name = "i=" + i_insideNewValuesListThatEachMarkASeparateLine + " y"; + break; + case UtilitiesDXXL_Math.DimensionNullable.z: + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].Name = "i=" + i_insideNewValuesListThatEachMarkASeparateLine + " z"; + break; + case UtilitiesDXXL_Math.DimensionNullable.none: + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].Name = "i=" + i_insideNewValuesListThatEachMarkASeparateLine; + break; + default: + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].Name = "i=" + i_insideNewValuesListThatEachMarkASeparateLine; + break; + } + + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].Assign_singleComponentOfMulticomponentData_thisLineRepresents(FunctionThatAssignsTheMultiComponentComponentThisLineRepresents); + if (dataSourceIsFromGameobjectRespTransform) + { + if (gameobjectInCurrSlotOfAddedNewValuesList == null) + { + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].NameExtraInfo = lineNameExtraInfo_forTransformsAndGameObjects; + } + else + { + AssignGameobjectToCurrListSlotsLine(concernedPremadeListOfLines, i_insideNewValuesListThatEachMarkASeparateLine, gameobjectInCurrSlotOfAddedNewValuesList, lineNameExtraInfo_forTransformsAndGameObjects); + } + } + else + { + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].NameExtraInfo = lineNameExtraInfo_forNonGameObjectDataSources; + } + ReassignListsLineColors(concernedPremadeListOfLines, vectorDimensionThisListOfLinesRepresents, luminanceOfLineColors); + } + } + + void TryAssignGameobject_toCurrSlotsExistingLineWhichUntilNowHadANullGameobject(List concernedPremadeListOfLines, int i_insideNewValuesListThatEachMarkASeparateLine, bool dataSourceIsFromGameobjectRespTransform, GameObject gameobjectInCurrSlotOfAddedNewValuesList, string lineNameExtraInfo_forTransformsAndGameObjects) + { + if (dataSourceIsFromGameobjectRespTransform) + { + if (concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].Gameobject_thatThisLineCurrentlyRepresents == null) + { + if (gameobjectInCurrSlotOfAddedNewValuesList != null) + { + //-> the line has already been created (because a previously added valueList contained this slot), but until now the slot was always filled with 'null': + AssignGameobjectToCurrListSlotsLine(concernedPremadeListOfLines, i_insideNewValuesListThatEachMarkASeparateLine, gameobjectInCurrSlotOfAddedNewValuesList, lineNameExtraInfo_forTransformsAndGameObjects); + } + } + } + } + + void BackwardFillGapOfLine_forSlotsThatWereTemporarlyNotContainedInTheList(List concernedPremadeListOfLines, int i_insideNewValuesListThatEachMarkASeparateLine, int numberOfDataPoints_ofLineOfThisListWithMostDataPoints_beforeCurrentlyAddedOne, ChartLine lineOfList_withMostDataPoints_beforeCurrentlyAddedOne) + { + int dataPointCount_ofCurrLineInsidePremadeList_beforeCurrentlyAddedOne = concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].dataPoints.Count; + if (dataPointCount_ofCurrLineInsidePremadeList_beforeCurrentlyAddedOne < numberOfDataPoints_ofLineOfThisListWithMostDataPoints_beforeCurrentlyAddedOne) + { + //-> Filling gaps if yValues.Length/Count changed from call to call (in other words: if currLine wasn't supplied during the preceding "AddValues_eachIndexIsALine()"-calls (because the collection-Length/Count was shorter) and it now has to "catch up"): + for (int i = dataPointCount_ofCurrLineInsidePremadeList_beforeCurrentlyAddedOne; i < numberOfDataPoints_ofLineOfThisListWithMostDataPoints_beforeCurrentlyAddedOne; i++) + { + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].InternalAddPlaceholderDatapointForNonExistingListSlot(lineOfList_withMostDataPoints_beforeCurrentlyAddedOne.dataPoints[i].xValue); + } + } + } + + void TryReassignNewGameobject_toCurrSlotsLineWhichUntilNowHadADifferentGameobject(List concernedPremadeListOfLines, int i_insideNewValuesListThatEachMarkASeparateLine, bool dataSourceIsFromGameobjectRespTransform, GameObject gameobjectInCurrSlotOfAddedNewValuesList, string lineNameExtraInfo_forTransformsAndGameObjects) + { + if (dataSourceIsFromGameobjectRespTransform) + { + if (gameobjectInCurrSlotOfAddedNewValuesList != null) + { + // "concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].gameobject_thatThisLineCurrentlyRepresents" cannot be "null" here + bool theGameobjectThatIsRepresentedByTheCurrList_changedSinceLastValueAdding = (gameobjectInCurrSlotOfAddedNewValuesList != concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].Gameobject_thatThisLineCurrentlyRepresents); + if (theGameobjectThatIsRepresentedByTheCurrList_changedSinceLastValueAdding) + { + AssignGameobjectToCurrListSlotsLine(concernedPremadeListOfLines, i_insideNewValuesListThatEachMarkASeparateLine, gameobjectInCurrSlotOfAddedNewValuesList, lineNameExtraInfo_forTransformsAndGameObjects); + } + } + } + } + + void AssignGameobjectToCurrListSlotsLine(List concernedPremadeListOfLines, int i_insideNewValuesListThatEachMarkASeparateLine, GameObject gameobjectInCurrSlotOfAddedNewValuesList, string lineNameExtraInfo_forTransformsAndGameObjects) + { + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].NameExtraInfo = lineNameExtraInfo_forTransformsAndGameObjects; + concernedPremadeListOfLines[i_insideNewValuesListThatEachMarkASeparateLine].InternalAssignRepresentedGameobject(gameobjectInCurrSlotOfAddedNewValuesList); + } + + public ChartLine AddLine(string name, Color color = default(Color)) + { + if (name == null || name == "") + { + Debug.LogError("'AddLine()' failed, because 'name' is null or empty."); + return null; + } + + ChartLine alreadyExistingLineWithSameName = GetUsermadeLine(name, false); + if (alreadyExistingLineWithSameName == null) + { + ChartLine newLine = new ChartLine(UtilitiesDXXL_Colors.red_xAxisAlpha1, chart_theseLinesArePartOf); + newLine.Name = name; + userMadeLines.Add(newLine); + if (UtilitiesDXXL_Colors.IsDefaultColor(color)) + { + TryReassignRainbowColorsToAllUsermadeLines(); + } + else + { + newLine.Color = color; + } + AddExistingHorizThresholdsToNewlyCreatedLine(ref newLine); + return newLine; + } + else + { + Debug.LogError("'AddLine()' failed, because a line with the name '" + name + "' already exists."); + return null; + } + } + + public ChartLine GetUsermadeLine(string lineName, bool createLineIfItDoesntExist) + { + if (lineName == null || lineName == "") + { + Debug.LogError("'GetUsermadeLine()' failed, because the requested 'lineName' is null or empty."); + return null; + } + + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].Name != null) + { + if (userMadeLines[i].Name == lineName) + { + return userMadeLines[i]; + } + } + } + + //A line with this name doesn't exist yet: + if (createLineIfItDoesntExist) + { + return chart_theseLinesArePartOf.AddLine(lineName, default(Color), false); + } + else + { + return null; + } + } + + public void SetLineNamesPositions(ChartLine.NamePosition newLineNamesPosition) + { + //overwrites the linePosition for all lines of the chart. If you want to specificy different linename positions for each line you can directly set chartLine.namePosition + chart_theseLinesArePartOf.default_lineNamePosition = newLineNamesPosition; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].namePosition = newLineNamesPosition; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].namePosition = newLineNamesPosition; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].namePosition = newLineNamesPosition; + } + } + } + + public void SetLineNamesSize(float newLineNamesSizeScaleFactor) + { + //overwrites the NameText_sizeScaleFactor for all lines of the chart. If you want to specificy different NameText_sizeScaleFactor for each line you can directly set chartLine.NameText_sizeScaleFactor + chart_theseLinesArePartOf.default_lineNameText_sizeScaleFactor = newLineNamesSizeScaleFactor; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].NameText_sizeScaleFactor = newLineNamesSizeScaleFactor; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].NameText_sizeScaleFactor = newLineNamesSizeScaleFactor; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].NameText_sizeScaleFactor = newLineNamesSizeScaleFactor; + } + } + } + + public void Set_lineConnectionsType(ChartLine.LineConnectionsType newLineConnectionsType) + { + //overwrites the lineConnectionsType for all lines of the chart. If you want to specificy different lineConnectionsTypes for each line you can directly set chartLine.lineConnectionsType + chart_theseLinesArePartOf.default_lineConnectionsType = newLineConnectionsType; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].lineConnectionsType = newLineConnectionsType; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].lineConnectionsType = newLineConnectionsType; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].lineConnectionsType = newLineConnectionsType; + } + } + } + + public void Set_dataPointVisualization(ChartLine.DataPointVisualization newDataPointVisualization) + { + //overwrites the dataPointVisualization for all lines of the chart. If you want to specificy different dataPointVisualization for each line you can directly set chartLine.dataPointVisualization + chart_theseLinesArePartOf.default_dataPointVisualization = newDataPointVisualization; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].dataPointVisualization = newDataPointVisualization; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].dataPointVisualization = newDataPointVisualization; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].dataPointVisualization = newDataPointVisualization; + } + } + } + + public void Set_alpha_ofVerticalAreaFillLines(float newAlpha) + { + //overwrites the alpha_ofVerticalFillAreaLines for all lines of the chart. If you want to specificy different alpha_ofVerticalFillAreaLines for each line you can directly set chartLine.alpha_ofVerticalFillAreaLines + chart_theseLinesArePartOf.default_alpha_ofVerticalAreaFillLines = newAlpha; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].Alpha_ofVerticalAreaFillLines = newAlpha; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].Alpha_ofVerticalAreaFillLines = newAlpha; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].Alpha_ofVerticalAreaFillLines = newAlpha; + } + } + } + + public void Set_alpha_ofHighlighterForMostCurrentValue_xDim(float newAlpha) + { + //overwrites the alpha_ofHighlighterForMostCurrentValue_xDim for all lines of the chart. If you want to specificy different alpha_ofHighlighterForMostCurrentValue_xDim for each line you can directly set chartLine.alpha_ofHighlighterForMostCurrentValue_xDim + chart_theseLinesArePartOf.default_alpha_ofHighlighterForMostCurrentValue_xDim = newAlpha; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].alpha_ofHighlighterForMostCurrentValue_xDim = newAlpha; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].alpha_ofHighlighterForMostCurrentValue_xDim = newAlpha; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].alpha_ofHighlighterForMostCurrentValue_xDim = newAlpha; + } + } + } + + public void Set_alpha_ofHighlighterForMostCurrentValue_yDim(float newAlpha) + { + //overwrites the alpha_ofHighlighterForMostCurrentValue_yDim for all lines of the chart. If you want to specificy different alpha_ofHighlighterForMostCurrentValue_yDim for each line you can directly set chartLine.alpha_ofHighlighterForMostCurrentValue_yDim + chart_theseLinesArePartOf.default_alpha_ofHighlighterForMostCurrentValue_yDim = newAlpha; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].alpha_ofHighlighterForMostCurrentValue_yDim = newAlpha; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].alpha_ofHighlighterForMostCurrentValue_yDim = newAlpha; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].alpha_ofHighlighterForMostCurrentValue_yDim = newAlpha; + } + } + } + + public void Set_displayDeltaAtHighlighterForMostCurrentValue(bool doDisplay) + { + //overwrites the displayDeltaAtHighlighterForMostCurrentValue for all lines of the chart. If you want to specificy different displayDeltaAtHighlighterForMostCurrentValue for each line you can directly set chartLine.displayDeltaAtHighlighterForMostCurrentValue + chart_theseLinesArePartOf.default_displayDeltaAtHighlighterForMostCurrentValue = doDisplay; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].displayDeltaAtHighlighterForMostCurrentValue = doDisplay; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].displayDeltaAtHighlighterForMostCurrentValue = doDisplay; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].displayDeltaAtHighlighterForMostCurrentValue = doDisplay; + } + } + } + + public void Set_alpha_ofMaxiumumYValueMarker(float newAlpha) + { + //overwrites the alpha_ofMaxiumumYValueMarker for all lines of the chart. If you want to specificy different alpha_ofMaxiumumYValueMarker for each line you can directly set chartLine.alpha_ofMaxiumumYValueMarker + chart_theseLinesArePartOf.default_alpha_ofMaxiumumYValueMarker = newAlpha; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].alpha_ofMaxiumumYValueMarker = newAlpha; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].alpha_ofMaxiumumYValueMarker = newAlpha; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].alpha_ofMaxiumumYValueMarker = newAlpha; + } + } + } + + public void Set_alpha_ofMinimumYValueMarker(float newAlpha) + { + //overwrites the alpha_ofMinimumYValueMarker for all lines of the chart. If you want to specificy different alpha_ofMinimumYValueMarker for each line you can directly set chartLine.alpha_ofMinimumYValueMarker + chart_theseLinesArePartOf.default_alpha_ofMinimumYValueMarker = newAlpha; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].alpha_ofMinimumYValueMarker = newAlpha; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].alpha_ofMinimumYValueMarker = newAlpha; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].alpha_ofMinimumYValueMarker = newAlpha; + } + } + } + + public void Set_markAllYMaximumTurningPoints(bool markEnabled) + { + //overwrites the markAllYMaximumTurningPoints for all lines of the chart. If you want to specificy different markAllYMaximumTurningPoints for each line you can directly set chartLine.markAllYMaximumTurningPoints + chart_theseLinesArePartOf.default_markAllYMaximumTurningPoints = markEnabled; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].markAllYMaximumTurningPoints = markEnabled; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].markAllYMaximumTurningPoints = markEnabled; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].markAllYMaximumTurningPoints = markEnabled; + } + } + } + + public void Set_markAllYMinimumTurningPoints(bool markEnabled) + { + //overwrites the markAllYMinimumTurningPoints for all lines of the chart. If you want to specificy different markAllYMinimumTurningPoints for each line you can directly set chartLine.markAllYMinimumTurningPoints + chart_theseLinesArePartOf.default_markAllYMinimumTurningPoints = markEnabled; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].markAllYMinimumTurningPoints = markEnabled; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].markAllYMinimumTurningPoints = markEnabled; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].markAllYMinimumTurningPoints = markEnabled; + } + } + } + + public void Set_SizeOfPoints_relToChartHeight(float newRelSize) + { + //overwrites the SizeOfPoints_relToChartHeight for all lines of the chart. If you want to specificy different SizeOfPoints_relToChartHeight for each line you can directly set chartLine.SizeOfPoints_relToChartHeight + chart_theseLinesArePartOf.default_SizeOfPoints_relToChartHeight = newRelSize; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].SizeOfPoints_relToChartHeight = newRelSize; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].SizeOfPoints_relToChartHeight = newRelSize; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].SizeOfPoints_relToChartHeight = newRelSize; + } + } + } + + public void Set_lineWidth_relToChartHeight(float newRelSize) + { + //overwrites the lineWidth_relToChartHeight for all lines of the chart. If you want to specificy different lineWidth_relToChartHeight for each line you can directly set chartLine.lineWidth_relToChartHeight + chart_theseLinesArePartOf.default_lineWidth_relToChartHeight = newRelSize; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].LineWidth_relToChartHeight = newRelSize; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].LineWidth_relToChartHeight = newRelSize; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].LineWidth_relToChartHeight = newRelSize; + } + } + } + + public void Set_pointVisualisationLineWidth_relToChartHeight(float newRelSize) + { + //overwrites the pointVisualisationLineWidth_relToChartHeight for all lines of the chart. If you want to specificy different pointVisualisationLineWidth_relToChartHeight for each line you can directly set chartLine.pointVisualisationLineWidth_relToChartHeight + chart_theseLinesArePartOf.default_pointVisualisationLineWidth_relToChartHeight = newRelSize; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].pointVisualisationLineWidth_relToChartHeight = newRelSize; + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].pointVisualisationLineWidth_relToChartHeight = newRelSize; + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].pointVisualisationLineWidth_relToChartHeight = newRelSize; + } + } + } + + int stillAvailableTextBoxes_inUpperRightCorner_duringPreviousDrawRun = 0; + public void DrawPointsOfInterest(float yHeightFacor_forColumnStartPos, float durationInSec, bool hiddenByNearerObjects) + { + //Use "chartDrawing.Draw() instead. + + //first pass: check if they are drawn + int stillAvailableTextBoxes_inUpperRightCorner = chart_theseLinesArePartOf.MaxDisplayedPointOfInterestTextBoxesPerSide; + for (int i = 0; i < preMadeLines.Count; i++) + { + stillAvailableTextBoxes_inUpperRightCorner = preMadeLines[i].Internal_Set_isDrawnInNextPass_forAllPointsOfInterest(stillAvailableTextBoxes_inUpperRightCorner); + } + for (int i = 0; i < userMadeLines.Count; i++) + { + stillAvailableTextBoxes_inUpperRightCorner = userMadeLines[i].Internal_Set_isDrawnInNextPass_forAllPointsOfInterest(stillAvailableTextBoxes_inUpperRightCorner); + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + stillAvailableTextBoxes_inUpperRightCorner = listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].Internal_Set_isDrawnInNextPass_forAllPointsOfInterest(stillAvailableTextBoxes_inUpperRightCorner); + } + } + + //second pass: draw them + Vector3 next_lowAnchorPositionOfText_inWorldspace = chart_theseLinesArePartOf.Position_worldspace + chart_theseLinesArePartOf.yAxis.AxisVector_inWorldSpace * yHeightFacor_forColumnStartPos + chart_theseLinesArePartOf.xAxis.AxisVector_inWorldSpace * 1.00f; + for (int i = 0; i < preMadeLines.Count; i++) + { + next_lowAnchorPositionOfText_inWorldspace = preMadeLines[i].DrawPointsOfInterest(next_lowAnchorPositionOfText_inWorldspace, durationInSec, hiddenByNearerObjects); + } + for (int i = 0; i < userMadeLines.Count; i++) + { + next_lowAnchorPositionOfText_inWorldspace = userMadeLines[i].DrawPointsOfInterest(next_lowAnchorPositionOfText_inWorldspace, durationInSec, hiddenByNearerObjects); + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + next_lowAnchorPositionOfText_inWorldspace = listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].DrawPointsOfInterest(next_lowAnchorPositionOfText_inWorldspace, durationInSec, hiddenByNearerObjects); + } + } + + //draw "hiddenTextBoxes-communicating-textBox" + //-> draw this "hiddenTextBoxes-communicating-textBox" AFTER(=ABOVE) the other textBoxes, so that it appears as the "oldest" text box: newer text boxes will be drawn lower than this + if (stillAvailableTextBoxes_inUpperRightCorner < 0) + { + if (stillAvailableTextBoxes_inUpperRightCorner != stillAvailableTextBoxes_inUpperRightCorner_duringPreviousDrawRun) //-> saving GC.alloc by only recreating the text when something changes + { + if (stillAvailableTextBoxes_inUpperRightCorner == (-1)) + { + chart_theseLinesArePartOf.pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide.text = "...and 1 more hidden older text box.

See also 'ChartDrawing.maxDisplayedPointOfInterestTextBoxesPerSide'."; + } + else + { + chart_theseLinesArePartOf.pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide.text = "...and " + (-stillAvailableTextBoxes_inUpperRightCorner) + " more hidden older text boxes.

See also 'ChartDrawing.maxDisplayedPointOfInterestTextBoxesPerSide'."; + } + } + stillAvailableTextBoxes_inUpperRightCorner_duringPreviousDrawRun = stillAvailableTextBoxes_inUpperRightCorner; + chart_theseLinesArePartOf.pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide.colorOfPointerTextBox = chart_theseLinesArePartOf.color; + UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted = UtilitiesDXXL_Math.SkewedDirection.upRight; + chart_theseLinesArePartOf.pointOfInterest_thatCommunicatesTheHiddenPointsOfInterest_onTheRightSide.TryDraw(next_lowAnchorPositionOfText_inWorldspace, cornerOfChartWhereTextBoxIsMounted, durationInSec, hiddenByNearerObjects); + } + } + + public void AddHorizontalThresholdToEachLine(float yPosition, bool lineItselfCountsToLowerArea = false) + { + //use "chartDrawing.AddHorizontalThresholdLine" instead + + if (UtilitiesDXXL_Math.FloatIsInvalid(yPosition)) + { + Debug.LogError("Cannot create threshold line at " + yPosition); + return; + } + + InternalDXXL_HorizontalThresholdLineInitializer thresholdLineInitializer = new InternalDXXL_HorizontalThresholdLineInitializer(); + thresholdLineInitializer.yPositionOfThresholdToCreate = yPosition; + thresholdLineInitializer.lineItselfCountsToLowerArea = lineItselfCountsToLowerArea; + horizontalThresholdsInitializer.Add(thresholdLineInitializer); + + bool hideThresholdLineAndShowOnlyTheIntersectionPointers = true; + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].AddHorizontalThresholdLine(yPosition, lineItselfCountsToLowerArea, default(Color), hideThresholdLineAndShowOnlyTheIntersectionPointers); + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].AddHorizontalThresholdLine(yPosition, lineItselfCountsToLowerArea, default(Color), hideThresholdLineAndShowOnlyTheIntersectionPointers); + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].AddHorizontalThresholdLine(yPosition, lineItselfCountsToLowerArea, default(Color), hideThresholdLineAndShowOnlyTheIntersectionPointers); + } + } + } + + void AddExistingHorizThresholdsToNewlyCreatedLine(ref ChartLine newlyCreatedChartLine) + { + bool hideThresholdLineAndShowOnlyTheIntersectionPointers = true; + for (int i = 0; i < horizontalThresholdsInitializer.Count; i++) + { + newlyCreatedChartLine.AddHorizontalThresholdLine(horizontalThresholdsInitializer[i].yPositionOfThresholdToCreate, horizontalThresholdsInitializer[i].lineItselfCountsToLowerArea, default(Color), hideThresholdLineAndShowOnlyTheIntersectionPointers); + } + } + + int numberOfUserMadeLines_inMomentOfLastAutomaticRainbowColorReassignment = 0; + void TryReassignRainbowColorsToAllUsermadeLines() + { + for (int i = 0; i < userMadeLines.Count; i++) + { + bool isTheNewlyCreatedLine = (i == (userMadeLines.Count - 1)); + if (isTheNewlyCreatedLine) + { + userMadeLines[i].Color = SeededColorGenerator.GetRainbowColor(i, 1.0f, userMadeLines.Count, luminanceOfLineColors); + } + else + { + Color expectedColorOfLine_beforeCurrReassignment_ifColorWasAutogenerated = SeededColorGenerator.GetRainbowColor(i, 1.0f, numberOfUserMadeLines_inMomentOfLastAutomaticRainbowColorReassignment, luminanceOfLineColors); + bool colorWasManuallySetByUser = (UtilitiesDXXL_Colors.IsApproxSameColor(userMadeLines[i].Color, expectedColorOfLine_beforeCurrReassignment_ifColorWasAutogenerated) == false); + if (colorWasManuallySetByUser == false) + { + userMadeLines[i].Color = SeededColorGenerator.GetRainbowColor(i, 1.0f, userMadeLines.Count, luminanceOfLineColors); + } + } + } + numberOfUserMadeLines_inMomentOfLastAutomaticRainbowColorReassignment = userMadeLines.Count; + } + + void ReassignLuminanceToLinecolors(float oldLuminance, float newLuminance) + { + Color colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated; + Color colorToAssign_ifAutogenerated; + + for (int i = 0; i < userMadeLines.Count; i++) + { + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetRainbowColor(i, 1.0f, numberOfUserMadeLines_inMomentOfLastAutomaticRainbowColorReassignment, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetRainbowColor(i, 1.0f, numberOfUserMadeLines_inMomentOfLastAutomaticRainbowColorReassignment, newLuminance); + ReassignLuminanceToLineColor(userMadeLines[i], colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + } + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_premadeLine_float, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_premadeLine_float, newLuminance); + ReassignLuminanceToLineColor(premadeLine_float, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_premadeLine_int, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_premadeLine_int, newLuminance); + ReassignLuminanceToLineColor(premadeLine_int, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_vector2_x, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_vector2_y, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_vector3_x, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_vector3_y, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_vector3_z, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_vector4_x, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_vector4_y, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_vector4_z, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_wDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_wDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_vector4_w, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + //premadeLine_color_r -> doesn't change it's luminance + //premadeLine_color_g -> doesn't change it's luminance + //premadeLine_color_b -> doesn't change it's luminance + //premadeLine_color_a -> doesn't change it's luminance + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_rotation_eulerX, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_rotation_eulerY, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_rotation_eulerZ, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_premadeLine_bool, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_premadeLine_bool, newLuminance); + ReassignLuminanceToLineColor(premadeLine_bool, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + //Non-list transform lines: + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_localPosition_x, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_localPosition_y, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_localPosition_z, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_localEulerAngle_x, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_localEulerAngle_y, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_localEulerAngle_z, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_localScale_x, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_localScale_y, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_localScale_z, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_globalPosition_x, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_globalPosition_y, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_globalPosition_z, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_globalEulerAngle_x, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_globalEulerAngle_y, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_globalEulerAngle_z, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_xDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_lossyScale_x, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_yDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_lossyScale_y, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(default_colorHue_of_zDimension, newLuminance); + ReassignLuminanceToLineColor(premadeLine_transform_lossyScale_z, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + + //for listOfLines: no check if user has overwritten the line color. Always force to rainbowColorWithLuminance: + ReassignListsLineColors(preMadeListOfLines_float, UtilitiesDXXL_Math.DimensionNullable.none, newLuminance); + ReassignListsLineColors(preMadeListOfLines_int, UtilitiesDXXL_Math.DimensionNullable.none, newLuminance); + ReassignListsLineColors(preMadeListOfLines_vector2_x, UtilitiesDXXL_Math.DimensionNullable.x, newLuminance); + ReassignListsLineColors(preMadeListOfLines_vector2_y, UtilitiesDXXL_Math.DimensionNullable.y, newLuminance); + ReassignListsLineColors(preMadeListOfLines_vector3_x, UtilitiesDXXL_Math.DimensionNullable.x, newLuminance); + ReassignListsLineColors(preMadeListOfLines_vector3_y, UtilitiesDXXL_Math.DimensionNullable.y, newLuminance); + ReassignListsLineColors(preMadeListOfLines_vector3_z, UtilitiesDXXL_Math.DimensionNullable.z, newLuminance); + ReassignListsLineColors(preMadeListOfLines_rotation_eulerX, UtilitiesDXXL_Math.DimensionNullable.x, newLuminance); + ReassignListsLineColors(preMadeListOfLines_rotation_eulerY, UtilitiesDXXL_Math.DimensionNullable.y, newLuminance); + ReassignListsLineColors(preMadeListOfLines_rotation_eulerZ, UtilitiesDXXL_Math.DimensionNullable.z, newLuminance); + ReassignListsLineColors(preMadeListOfLines_bool, UtilitiesDXXL_Math.DimensionNullable.none, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_localPosition_x, UtilitiesDXXL_Math.DimensionNullable.x, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_localPosition_y, UtilitiesDXXL_Math.DimensionNullable.y, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_localPosition_z, UtilitiesDXXL_Math.DimensionNullable.z, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_localEulerAngle_x, UtilitiesDXXL_Math.DimensionNullable.x, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_localEulerAngle_y, UtilitiesDXXL_Math.DimensionNullable.y, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_localEulerAngle_z, UtilitiesDXXL_Math.DimensionNullable.z, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_localScale_x, UtilitiesDXXL_Math.DimensionNullable.x, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_localScale_y, UtilitiesDXXL_Math.DimensionNullable.y, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_localScale_z, UtilitiesDXXL_Math.DimensionNullable.z, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_globalPosition_x, UtilitiesDXXL_Math.DimensionNullable.x, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_globalPosition_y, UtilitiesDXXL_Math.DimensionNullable.y, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_globalPosition_z, UtilitiesDXXL_Math.DimensionNullable.z, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_globalEulerAngle_x, UtilitiesDXXL_Math.DimensionNullable.x, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_globalEulerAngle_y, UtilitiesDXXL_Math.DimensionNullable.y, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_globalEulerAngle_z, UtilitiesDXXL_Math.DimensionNullable.z, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_lossyScale_x, UtilitiesDXXL_Math.DimensionNullable.x, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_lossyScale_y, UtilitiesDXXL_Math.DimensionNullable.y, newLuminance); + ReassignListsLineColors(preMadeListOfLines_transforms_lossyScale_z, UtilitiesDXXL_Math.DimensionNullable.z, newLuminance); + } + + void ReassignLuminanceToLineColor(ChartLine concernedLine, Color colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, Color colorToAssign_ifAutogenerated, float newLuminance) + { + bool colorWasAutogenerated = UtilitiesDXXL_Colors.IsApproxSameColor(concernedLine.Color, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated); + if (colorWasAutogenerated) + { + concernedLine.Color = colorToAssign_ifAutogenerated; + } + else + { + //color has been manually set by user: + if (UtilitiesDXXL_Math.ApproximatelyZero(concernedLine.Color.r) && UtilitiesDXXL_Math.ApproximatelyZero(concernedLine.Color.g) && UtilitiesDXXL_Math.ApproximatelyZero(concernedLine.Color.b)) + { + //-> black colors cannot be forced with luminance, therefore: slight lift, to make it grey, which can be forced: + concernedLine.Color = new Color(0.01f, 0.01f, 0.01f, concernedLine.Color.a); + } + concernedLine.Color = SeededColorGenerator.ForceApproxLuminance(concernedLine.Color, newLuminance); + } + } + + void ReassignListsLineColors(List concernedPremadeListOfLines, UtilitiesDXXL_Math.DimensionNullable vectorDimensionThisListOfLinesRepresents, float usedLuminance) + { + if (concernedPremadeListOfLines != null) + { + for (int i = 0; i < concernedPremadeListOfLines.Count; i++) + { + switch (vectorDimensionThisListOfLinesRepresents) + { + case UtilitiesDXXL_Math.DimensionNullable.none: + concernedPremadeListOfLines[i].Color = SeededColorGenerator.GetRainbowColor(i, 1.0f, concernedPremadeListOfLines.Count, usedLuminance); + break; + case UtilitiesDXXL_Math.DimensionNullable.x: + concernedPremadeListOfLines[i].Color = SeededColorGenerator.GetRainbowColorAroundRed(i, 1.0f, concernedPremadeListOfLines.Count, false, usedLuminance); + break; + case UtilitiesDXXL_Math.DimensionNullable.y: + concernedPremadeListOfLines[i].Color = SeededColorGenerator.GetRainbowColorAroundGreen(i, 1.0f, concernedPremadeListOfLines.Count, false, usedLuminance); + break; + case UtilitiesDXXL_Math.DimensionNullable.z: + concernedPremadeListOfLines[i].Color = SeededColorGenerator.GetRainbowColorAroundBlue(i, 1.0f, concernedPremadeListOfLines.Count, false, usedLuminance); + break; + default: + UtilitiesDXXL_Log.PrintErrorCode("8"); + concernedPremadeListOfLines[i].Color = SeededColorGenerator.GetRainbowColor(i, 1.0f, concernedPremadeListOfLines.Count, usedLuminance); + break; + } + } + } + } + + public bool HasAtLeastOneDrawnLineWithAtLeastOneValidValue() + { + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + return true; + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + return true; + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + return true; + } + } + } + return false; + } + + public float GetMostCurrentXValueOfAllLines() + { + float mostCurrentXValue_ofAllLines = float.NegativeInfinity; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + mostCurrentXValue_ofAllLines = Mathf.Max(mostCurrentXValue_ofAllLines, preMadeLines[i].GetMostCurrentValidXValue()); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + mostCurrentXValue_ofAllLines = Mathf.Max(mostCurrentXValue_ofAllLines, userMadeLines[i].GetMostCurrentValidXValue()); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + mostCurrentXValue_ofAllLines = Mathf.Max(mostCurrentXValue_ofAllLines, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].GetMostCurrentValidXValue()); + } + } + } + return mostCurrentXValue_ofAllLines; + } + + public float GetMostCurrentYValueOfAllLines() + { + float mostCurrentYValue_ofAllLines = float.NegativeInfinity; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + mostCurrentYValue_ofAllLines = Mathf.Max(mostCurrentYValue_ofAllLines, preMadeLines[i].GetMostCurrentValidYValue()); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + mostCurrentYValue_ofAllLines = Mathf.Max(mostCurrentYValue_ofAllLines, userMadeLines[i].GetMostCurrentValidYValue()); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + mostCurrentYValue_ofAllLines = Mathf.Max(mostCurrentYValue_ofAllLines, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].GetMostCurrentValidYValue()); + } + } + } + return mostCurrentYValue_ofAllLines; + } + + public float GetLowestXValueOfAllLines() + { + //see also "chart_theseLinesArePartOf.overallMinXValue_includingHiddenLines", which is similar, but also includes hidden lines + float lowestXValue_ofAllLines = float.PositiveInfinity; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + lowestXValue_ofAllLines = Mathf.Min(lowestXValue_ofAllLines, preMadeLines[i].GetLowestXValue()); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + lowestXValue_ofAllLines = Mathf.Min(lowestXValue_ofAllLines, userMadeLines[i].GetLowestXValue()); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + lowestXValue_ofAllLines = Mathf.Min(lowestXValue_ofAllLines, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].GetLowestXValue()); + } + } + } + return lowestXValue_ofAllLines; + } + + public float GetLowestYValueOfAllLines() + { + //see also "chart_theseLinesArePartOf.overallMinYValue_includingHiddenLines", which is similar, but also includes hidden lines + float lowestYValue_ofAllLines = float.PositiveInfinity; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + lowestYValue_ofAllLines = Mathf.Min(lowestYValue_ofAllLines, preMadeLines[i].GetLowestYValue()); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + lowestYValue_ofAllLines = Mathf.Min(lowestYValue_ofAllLines, userMadeLines[i].GetLowestYValue()); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + lowestYValue_ofAllLines = Mathf.Min(lowestYValue_ofAllLines, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].GetLowestYValue()); + } + } + } + return lowestYValue_ofAllLines; + } + + public float GetHighestXValueOfAllLines() + { + //see also "chart_theseLinesArePartOf.overallMaxXValue_includingHiddenLines", which is similar, but also includes hidden lines + float highestXValue_ofAllLines = float.NegativeInfinity; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + highestXValue_ofAllLines = Mathf.Max(highestXValue_ofAllLines, preMadeLines[i].GetHighestXValue()); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + highestXValue_ofAllLines = Mathf.Max(highestXValue_ofAllLines, userMadeLines[i].GetHighestXValue()); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + highestXValue_ofAllLines = Mathf.Max(highestXValue_ofAllLines, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].GetHighestXValue()); + } + } + } + return highestXValue_ofAllLines; + } + + public float GetHighestYValueOfAllLines() + { + //see also "chart_theseLinesArePartOf.overallMaxYValue_includingHiddenLines", which is similar, but also includes hidden lines + float highestYValue_ofAllLines = float.NegativeInfinity; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + highestYValue_ofAllLines = Mathf.Max(highestYValue_ofAllLines, preMadeLines[i].GetHighestYValue()); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + highestYValue_ofAllLines = Mathf.Max(highestYValue_ofAllLines, userMadeLines[i].GetHighestYValue()); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + highestYValue_ofAllLines = Mathf.Max(highestYValue_ofAllLines, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].GetHighestYValue()); + } + } + } + return highestYValue_ofAllLines; + } + + public float GetLowestXValueOfAllLines_insideRestricedYSpan(float minAllowedY, float maxAllowedY) + { + float lowestXValue_ofAllLines = float.PositiveInfinity; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + lowestXValue_ofAllLines = Mathf.Min(lowestXValue_ofAllLines, preMadeLines[i].GetLowestXValue_insideRestricedYSpan(minAllowedY, maxAllowedY)); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + lowestXValue_ofAllLines = Mathf.Min(lowestXValue_ofAllLines, userMadeLines[i].GetLowestXValue_insideRestricedYSpan(minAllowedY, maxAllowedY)); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + lowestXValue_ofAllLines = Mathf.Min(lowestXValue_ofAllLines, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].GetLowestXValue_insideRestricedYSpan(minAllowedY, maxAllowedY)); + } + } + } + return lowestXValue_ofAllLines; + } + + public float GetLowestYValueOfAllLines_insideRestricedXSpan(float minAllowedX, float maxAllowedX) + { + float lowestYValue_ofAllLines = float.PositiveInfinity; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + lowestYValue_ofAllLines = Mathf.Min(lowestYValue_ofAllLines, preMadeLines[i].GetLowestYValue_insideRestricedXSpan(minAllowedX, maxAllowedX)); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + lowestYValue_ofAllLines = Mathf.Min(lowestYValue_ofAllLines, userMadeLines[i].GetLowestYValue_insideRestricedXSpan(minAllowedX, maxAllowedX)); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + lowestYValue_ofAllLines = Mathf.Min(lowestYValue_ofAllLines, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].GetLowestYValue_insideRestricedXSpan(minAllowedX, maxAllowedX)); + } + } + } + return lowestYValue_ofAllLines; + } + + public float GetHighestXValueOfAllLines_insideRestricedYSpan(float minAllowedY, float maxAllowedY) + { + float highestXValue_ofAllLines = float.NegativeInfinity; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + highestXValue_ofAllLines = Mathf.Max(highestXValue_ofAllLines, preMadeLines[i].GetHighestXValue_insideRestricedYSpan(minAllowedY, maxAllowedY)); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + highestXValue_ofAllLines = Mathf.Max(highestXValue_ofAllLines, userMadeLines[i].GetHighestXValue_insideRestricedYSpan(minAllowedY, maxAllowedY)); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + highestXValue_ofAllLines = Mathf.Max(highestXValue_ofAllLines, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].GetHighestXValue_insideRestricedYSpan(minAllowedY, maxAllowedY)); + } + } + } + return highestXValue_ofAllLines; + } + + public float GetHighestYValueOfAllLines_insideRestricedXSpan(float minAllowedX, float maxAllowedX) + { + float highestYValue_ofAllLines = float.NegativeInfinity; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].HasAtLeastOneValuePairOfValidData && preMadeLines[i].CheckIfLineIsDrawn()) + { + highestYValue_ofAllLines = Mathf.Max(highestYValue_ofAllLines, preMadeLines[i].GetHighestYValue_insideRestricedXSpan(minAllowedX, maxAllowedX)); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].HasAtLeastOneValuePairOfValidData && userMadeLines[i].CheckIfLineIsDrawn()) + { + highestYValue_ofAllLines = Mathf.Max(highestYValue_ofAllLines, userMadeLines[i].GetHighestYValue_insideRestricedXSpan(minAllowedX, maxAllowedX)); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].HasAtLeastOneValuePairOfValidData && listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].CheckIfLineIsDrawn()) + { + highestYValue_ofAllLines = Mathf.Max(highestYValue_ofAllLines, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].GetHighestYValue_insideRestricedXSpan(minAllowedX, maxAllowedX)); + } + } + } + return highestYValue_ofAllLines; + } + + void TrySetPointsOfInterest_forChangingGameobjectsInCollectionSlots(List yValues) + { + for (int i_newlyAddedValueListSlot = 0; i_newlyAddedValueListSlot < yValues.Count; i_newlyAddedValueListSlot++) + { + TrySetPointOfInterest_forChangingGameobjectInCollectionSlot(yValues[i_newlyAddedValueListSlot], i_newlyAddedValueListSlot); + } + } + + void TrySetPointsOfInterest_forChangingGameobjectsInCollectionSlots(GameObject[] yValues) + { + for (int i_newlyAddedValueListSlot = 0; i_newlyAddedValueListSlot < yValues.Length; i_newlyAddedValueListSlot++) + { + TrySetPointOfInterest_forChangingGameobjectInCollectionSlot(yValues[i_newlyAddedValueListSlot], i_newlyAddedValueListSlot); + } + } + + void TrySetPointsOfInterest_forChangingGameobjectsInCollectionSlots(List yValues) + { + for (int i_newlyAddedValueListSlot = 0; i_newlyAddedValueListSlot < yValues.Count; i_newlyAddedValueListSlot++) + { + TrySetPointOfInterest_forChangingGameobjectInCollectionSlot(yValues[i_newlyAddedValueListSlot].gameObject, i_newlyAddedValueListSlot); + } + } + + void TrySetPointsOfInterest_forChangingGameobjectsInCollectionSlots(Transform[] yValues) + { + for (int i_newlyAddedValueListSlot = 0; i_newlyAddedValueListSlot < yValues.Length; i_newlyAddedValueListSlot++) + { + TrySetPointOfInterest_forChangingGameobjectInCollectionSlot(yValues[i_newlyAddedValueListSlot].gameObject, i_newlyAddedValueListSlot); + } + } + + void TrySetPointOfInterest_forChangingGameobjectInCollectionSlot(GameObject gameobjectInCheckedSlotOf_newlyAddedValues, int i_newlyAddedValueListSlot) + { + if (gameobjectInCheckedSlotOf_newlyAddedValues != null) + { + //-> using "preMadeListOfLines_transforms_localPosition_x" as representative of all "preMadeListOfLines_transforms_*" + if (preMadeListOfLines_transforms_localPosition_x != null) + { + if (i_newlyAddedValueListSlot < preMadeListOfLines_transforms_localPosition_x.Count) + { + if (preMadeListOfLines_transforms_localPosition_x[i_newlyAddedValueListSlot] != null) + { + if (preMadeListOfLines_transforms_localPosition_x[i_newlyAddedValueListSlot].Gameobject_thatThisLineCurrentlyRepresents != null) + { + if (gameobjectInCheckedSlotOf_newlyAddedValues != preMadeListOfLines_transforms_localPosition_x[i_newlyAddedValueListSlot].Gameobject_thatThisLineCurrentlyRepresents) + { + //-> Only setting the notification point. For the reassignment of '.Gameobject_thatThisLineCurrentlyRepresents' will 'AddValueCollectionSlots_toLines()' take care. + SetPointOfInterest_forChangingGameobjectInCollectionSlot(gameobjectInCheckedSlotOf_newlyAddedValues, i_newlyAddedValueListSlot); + } + } + } + } + } + } + } + + void SetPointOfInterest_forChangingGameobjectInCollectionSlot(GameObject gameobjectInCheckedSlotOf_newlyAddedValues, int i_newlyAddedValueListSlot) + { + Vector2 position = new Vector2(preMadeListOfLines_transforms_localPosition_x[i_newlyAddedValueListSlot].GetCurrentAutomaticXValue(), float.NaN); + string textToDisplay = " 'i=" + i_newlyAddedValueListSlot + "':
A new Gameobject delivers the values:
" + gameobjectInCheckedSlotOf_newlyAddedValues.name + "
Up to now the values came from:
" + preMadeListOfLines_transforms_localPosition_x[i_newlyAddedValueListSlot].Gameobject_thatThisLineCurrentlyRepresents.name; + DrawBasics.LineStyle horizLinestyle = DrawBasics.LineStyle.invisible; + DrawBasics.LineStyle vertLinestyle = DrawBasics.LineStyle.solid; + float alphaOfColor_relToParent = 1.0f; + bool getsDeletedOnClear = true; + PointOfInterest pointOfInterest_indicatingTheChangeOfTheGameobjectInsideACollectionSlot = chart_theseLinesArePartOf.AddPointOfInterest(position, textToDisplay, horizLinestyle, vertLinestyle, alphaOfColor_relToParent, getsDeletedOnClear); + pointOfInterest_indicatingTheChangeOfTheGameobjectInsideACollectionSlot.drawTextBoxIfPointIsOutsideOfChartArea = true; + pointOfInterest_indicatingTheChangeOfTheGameobjectInsideACollectionSlot.forceColorOfParent = true; + pointOfInterest_indicatingTheChangeOfTheGameobjectInsideACollectionSlot.xValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_localPosition_x[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_localPosition_y[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_localPosition_z[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_localEulerAngle_x[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_localEulerAngle_y[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_localEulerAngle_z[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_localScale_x[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_localScale_y[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_localScale_z[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_globalPosition_x[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_globalPosition_y[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_globalPosition_z[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_globalEulerAngle_x[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_globalEulerAngle_y[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_globalEulerAngle_z[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_lossyScale_x[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_lossyScale_y[i_newlyAddedValueListSlot]); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(preMadeListOfLines_transforms_lossyScale_z[i_newlyAddedValueListSlot]); + } + + void AddPointOfInterestForChangingValueSourceGameobject(float xPos, GameObject theOldGameobject, GameObject theNewGameobject) + { + Color colorOfVertLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(chart_theseLinesArePartOf.color, 0.75f); + PointOfInterest pointOfInterest_visualizingTheChangingGameobject = new PointOfInterest(xPos, 0.0f, colorOfVertLine, chart_theseLinesArePartOf, null, null); + pointOfInterest_visualizingTheChangingGameobject.isDeletedOnClear = true; + pointOfInterest_visualizingTheChangingGameobject.forceColorOfParent = true; + pointOfInterest_visualizingTheChangingGameobject.xValue.lineStyle = DrawBasics.LineStyle.solid; + pointOfInterest_visualizingTheChangingGameobject.xValue.labelText = " A new Gameobject delivers the values: '" + theNewGameobject.name + "'. Up to now the values came from '" + theOldGameobject.name + "'"; + pointOfInterest_visualizingTheChangingGameobject.xValue.drawCoordinateAsText = true; + pointOfInterest_visualizingTheChangingGameobject.xValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + pointOfInterest_visualizingTheChangingGameobject.yValue.lineStyle = DrawBasics.LineStyle.invisible; + chart_theseLinesArePartOf.AddPointOfInterest(pointOfInterest_visualizingTheChangingGameobject); + + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_localPosition_x); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_localPosition_y); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_localPosition_z); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_localEulerAngle_x); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_localEulerAngle_y); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_localEulerAngle_z); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_localScale_x); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_localScale_y); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_localScale_z); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_globalPosition_x); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_globalPosition_y); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_globalPosition_z); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_globalEulerAngle_x); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_globalEulerAngle_y); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_globalEulerAngle_z); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_lossyScale_x); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_lossyScale_y); + MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(premadeLine_transform_lossyScale_z); + } + + void MarkTransitionAndDiscardTurningPointsDetection_forLineWhoseRepresentedGameobjectChanged(ChartLine concernedLine) + { + concernedLine.AddEmphasizingCircleToMostCurrentPoint(true, true); + concernedLine.ForceUpcomingNextCreatedConnectionLine_toLowAlpha(); + concernedLine.turningPointDetector.DiscardPrecedingPointsFromComparison(); + } + + public List Get_all_hiddenAndUnhiddenLines_withAtLeastOneValidOrInvalidDatapoint(bool includeLinesThatRepresentDisabledMultiComponentComponents = false) + { + return Get_all_hiddenAndUnhiddenLines_withAtLeastOneValidOrInvalidDatapoint(out int numberOfDatapoints_inLongestLine, includeLinesThatRepresentDisabledMultiComponentComponents); + } + + public List Get_all_hiddenAndUnhiddenLines_withAtLeastOneValidOrInvalidDatapoint(out int numberOfDatapoints_inLongestLine, bool includeLinesThatRepresentDisabledMultiComponentComponents = false) + { + List list_with_allLinesWithAtLeastOneDataPoint_validOrInvalid = new List(); + numberOfDatapoints_inLongestLine = 0; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + numberOfDatapoints_inLongestLine = Mathf.Max(numberOfDatapoints_inLongestLine, preMadeLines[i].dataPoints.Count); + list_with_allLinesWithAtLeastOneDataPoint_validOrInvalid.Add(preMadeLines[i]); + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + numberOfDatapoints_inLongestLine = Mathf.Max(numberOfDatapoints_inLongestLine, userMadeLines[i].dataPoints.Count); + list_with_allLinesWithAtLeastOneDataPoint_validOrInvalid.Add(userMadeLines[i]); + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + numberOfDatapoints_inLongestLine = Mathf.Max(numberOfDatapoints_inLongestLine, listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].dataPoints.Count); + list_with_allLinesWithAtLeastOneDataPoint_validOrInvalid.Add(listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList]); + } + } + } + return list_with_allLinesWithAtLeastOneDataPoint_validOrInvalid; + } + + public int Get_numberOf_allHiddenAndUnhiddenLines_withAtLeastOneValidOrInvalidDatapoint(bool includeLinesThatRepresentDisabledMultiComponentComponents = false) + { + int numberOfAllLinesWithAtLeastOneDataPoint_validOrInvalid = 0; + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + numberOfAllLinesWithAtLeastOneDataPoint_validOrInvalid++; + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + numberOfAllLinesWithAtLeastOneDataPoint_validOrInvalid++; + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + numberOfAllLinesWithAtLeastOneDataPoint_validOrInvalid++; + } + } + } + return numberOfAllLinesWithAtLeastOneDataPoint_validOrInvalid; + } + + public void InitInspectionViaComponent() + { + for (int i = 0; i < preMadeLines.Count; i++) + { + preMadeLines[i].InitInspectionViaComponent(); + } + for (int i = 0; i < userMadeLines.Count; i++) + { + userMadeLines[i].InitInspectionViaComponent(); + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].InitInspectionViaComponent(); + } + } + } + + public ChartLine.NamePosition GetAUsedLineNamePosition(bool includeLinesThatRepresentDisabledMultiComponentComponents = false) + { + //First: only try unhidden lines: + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].IsUnhidden_andWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return preMadeLines[i].namePosition; + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].IsUnhidden_andWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return userMadeLines[i].namePosition; + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].IsUnhidden_andWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].namePosition; + } + } + } + + //Second: Also try hidden lines: + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return preMadeLines[i].namePosition; + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return userMadeLines[i].namePosition; + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].namePosition; + } + } + } + + //Third: Fallback + return ChartLine.NamePosition.dynamicallyMoving_atLineEnd_towardsRight; + } + + + public float GetAUsedLineNameSizeSclaeFactor(bool includeLinesThatRepresentDisabledMultiComponentComponents = false) + { + //First: only try unhidden lines: + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].IsUnhidden_andWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return preMadeLines[i].NameText_sizeScaleFactor; + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].IsUnhidden_andWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return userMadeLines[i].NameText_sizeScaleFactor; + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].IsUnhidden_andWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].NameText_sizeScaleFactor; + } + } + } + + //Second: Also try hidden lines: + for (int i = 0; i < preMadeLines.Count; i++) + { + if (preMadeLines[i].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return preMadeLines[i].NameText_sizeScaleFactor; + } + } + for (int i = 0; i < userMadeLines.Count; i++) + { + if (userMadeLines[i].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return userMadeLines[i].NameText_sizeScaleFactor; + } + } + for (int i_listOfLines = 0; i_listOfLines < listOfPremadeListsOfLines.Count; i_listOfLines++) + { + for (int i_lineInsideCurrList = 0; i_lineInsideCurrList < listOfPremadeListsOfLines[i_listOfLines].Count; i_lineInsideCurrList++) + { + if (listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint(includeLinesThatRepresentDisabledMultiComponentComponents)) + { + return listOfPremadeListsOfLines[i_listOfLines][i_lineInsideCurrList].NameText_sizeScaleFactor; + } + } + } + + //Third: Fallback + return 1.0f; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/ChartLines.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/ChartLines.cs.meta new file mode 100644 index 0000000..546b8bc --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/ChartLines.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7375d9685841fd498fb7395e665d967 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/DataComponentsThatAreDrawn.cs b/Runtime/DrawDebugLibrary/charts/line charts/DataComponentsThatAreDrawn.cs new file mode 100644 index 0000000..82a2cdb --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/DataComponentsThatAreDrawn.cs @@ -0,0 +1,95 @@ +namespace DrawXXL +{ + public class DataComponentsThatAreDrawn + { + //Vector2: + public bool vector2_x = true; + public bool vector2_y = true; + + //Vector3: + public bool vector3_x = true; + public bool vector3_y = true; + public bool vector3_z = true; + + //Vector4: + public bool vector4_x = true; + public bool vector4_y = true; + public bool vector4_z = true; + public bool vector4_w = true; + + //Color: + public bool color_r = true; + public bool color_g = true; + public bool color_b = true; + public bool color_a = true; + + //Rotation: + public bool rotation_eulerX = true; + public bool rotation_eulerY = true; + public bool rotation_eulerZ = true; + + //Transform: + public bool localPosition_x = true; + public bool localPosition_y = true; + public bool localPosition_z = true; + public bool localEulerAngle_x = false; + public bool localEulerAngle_y = false; + public bool localEulerAngle_z = false; + public bool localScale_x = false; + public bool localScale_y = false; + public bool localScale_z = false; + public bool globalPosition_x = false; + public bool globalPosition_y = false; + public bool globalPosition_z = false; + public bool globalEulerAngle_x = false; + public bool globalEulerAngle_y = false; + public bool globalEulerAngle_z = false; + public bool lossyScale_x = false; + public bool lossyScale_y = false; + public bool lossyScale_z = false; + + public void CopyValueFromOtherConfig(DataComponentsThatAreDrawn newConfig) + { + vector2_x = newConfig.vector2_x; + vector2_y = newConfig.vector2_y; + + vector3_x = newConfig.vector3_x; + vector3_y = newConfig.vector3_y; + vector3_z = newConfig.vector3_z; + + vector4_x = newConfig.vector4_x; + vector4_y = newConfig.vector4_y; + vector4_z = newConfig.vector4_z; + vector4_w = newConfig.vector4_w; + + color_r = newConfig.color_r; + color_g = newConfig.color_g; + color_b = newConfig.color_b; + color_a = newConfig.color_a; + + rotation_eulerX = newConfig.rotation_eulerX; + rotation_eulerY = newConfig.rotation_eulerY; + rotation_eulerZ = newConfig.rotation_eulerZ; + + localPosition_x = newConfig.localPosition_x; + localPosition_y = newConfig.localPosition_y; + localPosition_z = newConfig.localPosition_z; + localEulerAngle_x = newConfig.localEulerAngle_x; + localEulerAngle_y = newConfig.localEulerAngle_y; + localEulerAngle_z = newConfig.localEulerAngle_z; + localScale_x = newConfig.localScale_x; + localScale_y = newConfig.localScale_y; + localScale_z = newConfig.localScale_z; + globalPosition_x = newConfig.globalPosition_x; + globalPosition_y = newConfig.globalPosition_y; + globalPosition_z = newConfig.globalPosition_z; + globalEulerAngle_x = newConfig.globalEulerAngle_x; + globalEulerAngle_y = newConfig.globalEulerAngle_y; + globalEulerAngle_z = newConfig.globalEulerAngle_z; + lossyScale_x = newConfig.lossyScale_x; + lossyScale_y = newConfig.lossyScale_y; + lossyScale_z = newConfig.lossyScale_z; + } + + } +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/DataComponentsThatAreDrawn.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/DataComponentsThatAreDrawn.cs.meta new file mode 100644 index 0000000..f1d655a --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/DataComponentsThatAreDrawn.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 60d9d04a4f7323747aaf7b1253d4d4f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/DimensionOf_PointOfInterest.cs b/Runtime/DrawDebugLibrary/charts/line charts/DimensionOf_PointOfInterest.cs new file mode 100644 index 0000000..9aa6fcc --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/DimensionOf_PointOfInterest.cs @@ -0,0 +1,413 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class DimensionOf_PointOfInterest + { + public enum LineExtent { axisToPoint, throughWholeChart_ifOtherDimensionsValueIsInsideChart, throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart } + + private static float sizeOfLabeltext_relToChartHeight = 0.02f; + public static float SizeOfLabeltext_relToChartHeight //this changes globally for all PointsOfInterest + { + get { return sizeOfLabeltext_relToChartHeight; } + set { sizeOfLabeltext_relToChartHeight = Mathf.Max(value, 0.002f); } + } + + private static float sizeOfCoordinateText_relToChartHeight = 0.02f; + public static float SizeOfCoordinateText_relToChartHeight //this changes globally for all PointsOfInterest + { + get { return sizeOfCoordinateText_relToChartHeight; } + set { sizeOfCoordinateText_relToChartHeight = Mathf.Max(value, 0.002f); } + } + + public float position; + public DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid; + public float lineWidth_relToChartHeight = 0.0f; + public float linestylePatternScaleFactor = 1.0f; + public string labelText; //is only drawn if lineStyle is not invisible + public bool drawCoordinateAsText = true; //"lineStyle is invisible" also disables the drawing of the coordinate value + public Color color; + public LineExtent lineExtent = LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart; + UtilitiesDXXL_Math.Dimension representedDimension; + ChartDrawing chart_thisPointIsPartOf; + public DimensionOf_PointOfInterest theOtherDimension; + float currLineWidth_inWorldUnits; + public bool placeTextTowardsOutsideOfChart = false; //By default the labelText at the horizontal or vertical lines is mounted at the x respectively y axis and extends towards the inside of the chart. Setting "placeTextTowardsOutsideOfChart" to "true" shifts the "labelText", so it extends towards the outside of the chart. It is useful if you have many labelTexts from different points of interest in the chart, that intersect each other and are therefore not readable anymore. In such cases you gain some more breathing space for displayed texts. + + public DimensionOf_PointOfInterest(float position, Color color, UtilitiesDXXL_Math.Dimension representedDimension, ChartDrawing chart_thisPointIsPartOf) + { + //use ChartDrawing.AddPointOfInterest() instead + this.position = position; + this.color = color; + this.representedDimension = representedDimension; + this.chart_thisPointIsPartOf = chart_thisPointIsPartOf; + } + + public void Draw(float durationInSec, bool hiddenByNearerObjects) + { + //use ChartDrawing.Draw() instead + if (representedDimension == UtilitiesDXXL_Math.Dimension.x) + { + bool lineHasBeenDrawn = DrawVertLineAtXPos(durationInSec, hiddenByNearerObjects); + DrawCoordinateText_vertForXValues(lineHasBeenDrawn, durationInSec, hiddenByNearerObjects); + DrawLabelText_vertForXValues(lineHasBeenDrawn, durationInSec, hiddenByNearerObjects); + } + else + { + bool lineHasBeenDrawn = DrawHorizLineAtYPos(durationInSec, hiddenByNearerObjects); + DrawCoordinateText_horizForYValues(lineHasBeenDrawn, durationInSec, hiddenByNearerObjects); + DrawLabelText_horizForYValues(lineHasBeenDrawn, durationInSec, hiddenByNearerObjects); + } + } + + bool DrawVertLineAtXPos(float durationInSec, bool hiddenByNearerObjects) + { + //function returns if line was drawn + if (lineStyle != DrawBasics.LineStyle.invisible) + { + if (UtilitiesDXXL_Math.FloatIsValid(position)) + { + Vector2 start_inChartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingLowerEndOfTheAxis); + Vector2 end_inChartspace; + bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea; + if (UtilitiesDXXL_Math.FloatIsValid(theOtherDimension.position)) + { + switch (lineExtent) + { + case LineExtent.axisToPoint: + GetLineDrawSpecs_for_vertLineAtXPos_extentCase_axisToPoint(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace); + break; + case LineExtent.throughWholeChart_ifOtherDimensionsValueIsInsideChart: + GetLineDrawSpecs_for_vertLineAtXPos_extentCase_throughWholeChart_ifOtherDimensionsValueIsInsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace); + break; + case LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart: + GetLineDrawSpecs_for_vertLineAtXPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace); + break; + default: + UtilitiesDXXL_Log.PrintErrorCode("10-" + lineExtent); + return false; + } + } + else + { + //other dimensions position is invalid: + GetLineDrawSpecs_for_vertLineAtXPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace); + } + return TryDrawLine(shouldBeDrawn_becauseItHasPartsInsideTheChartArea, start_inChartspace, end_inChartspace, durationInSec, hiddenByNearerObjects); + } + else + { + return false; + } + } + else + { + return false; + } + } + + void GetLineDrawSpecs_for_vertLineAtXPos_extentCase_axisToPoint(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false; + lineEnd_inChartspace = new Vector2(position, theOtherDimension.position); + if (chart_thisPointIsPartOf.xAxis.IsInsideDisplayedSpan(position)) + { + if (theOtherDimension.position > chart_thisPointIsPartOf.yAxis.ValueMarkingLowerEndOfTheAxis) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true; + if (theOtherDimension.position > chart_thisPointIsPartOf.yAxis.ValueMarkingUpperEndOfTheAxis) + { + lineEnd_inChartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingUpperEndOfTheAxis); + } + } + } + } + + void GetLineDrawSpecs_for_vertLineAtXPos_extentCase_throughWholeChart_ifOtherDimensionsValueIsInsideChart(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false; + lineEnd_inChartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingUpperEndOfTheAxis); + if (chart_thisPointIsPartOf.xAxis.IsInsideDisplayedSpan(position)) + { + if (chart_thisPointIsPartOf.yAxis.IsInsideDisplayedSpan(theOtherDimension.position)) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true; + } + } + } + + void GetLineDrawSpecs_for_vertLineAtXPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false; + lineEnd_inChartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingUpperEndOfTheAxis); + if (chart_thisPointIsPartOf.xAxis.IsInsideDisplayedSpan(position)) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true; + } + } + + bool DrawHorizLineAtYPos(float durationInSec, bool hiddenByNearerObjects) + { + //function returns if line was drawn + if (lineStyle != DrawBasics.LineStyle.invisible) + { + if (UtilitiesDXXL_Math.FloatIsValid(position)) + { + Vector2 start_inChartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingLowerEndOfTheAxis, position); + Vector2 end_inChartspace; + bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea; + if (UtilitiesDXXL_Math.FloatIsValid(theOtherDimension.position)) + { + switch (lineExtent) + { + case LineExtent.axisToPoint: + GetLineDrawSpecs_for_horizLineAtYPos_extentCase_axisToPoint(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace); + break; + case LineExtent.throughWholeChart_ifOtherDimensionsValueIsInsideChart: + GetLineDrawSpecs_for_horizLineAtYPos_extentCase_throughWholeChart_ifOtherDimensionsValueIsInsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace); + break; + case LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart: + GetLineDrawSpecs_for_horizLineAtYPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace); + break; + default: + UtilitiesDXXL_Log.PrintErrorCode("11-" + lineExtent); + return false; + } + } + else + { + //other dimensions position is invalid: + GetLineDrawSpecs_for_horizLineAtYPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace); + } + return TryDrawLine(shouldBeDrawn_becauseItHasPartsInsideTheChartArea, start_inChartspace, end_inChartspace, durationInSec, hiddenByNearerObjects); + } + else + { + return false; + } + } + else + { + return false; + } + } + + void GetLineDrawSpecs_for_horizLineAtYPos_extentCase_axisToPoint(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false; + lineEnd_inChartspace = new Vector2(theOtherDimension.position, position); + if (chart_thisPointIsPartOf.yAxis.IsInsideDisplayedSpan(position)) + { + if (theOtherDimension.position > chart_thisPointIsPartOf.xAxis.ValueMarkingLowerEndOfTheAxis) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true; + if (theOtherDimension.position > chart_thisPointIsPartOf.xAxis.ValueMarkingUpperEndOfTheAxis) + { + lineEnd_inChartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingUpperEndOfTheAxis, position); + } + } + } + } + + void GetLineDrawSpecs_for_horizLineAtYPos_extentCase_throughWholeChart_ifOtherDimensionsValueIsInsideChart(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false; + lineEnd_inChartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingUpperEndOfTheAxis, position); + if (chart_thisPointIsPartOf.yAxis.IsInsideDisplayedSpan(position)) + { + if (chart_thisPointIsPartOf.xAxis.IsInsideDisplayedSpan(theOtherDimension.position)) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true; + } + } + } + + void GetLineDrawSpecs_for_horizLineAtYPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false; + lineEnd_inChartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingUpperEndOfTheAxis, position); + if (chart_thisPointIsPartOf.yAxis.IsInsideDisplayedSpan(position)) + { + shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true; + } + } + + bool TryDrawLine(bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, Vector2 start_inChartspace, Vector2 end_inChartspace, float durationInSec, bool hiddenByNearerObjects) + { + //function returns if line was drawn + if (shouldBeDrawn_becauseItHasPartsInsideTheChartArea || chart_thisPointIsPartOf.drawValuesOutsideOfChartArea) + { + Vector3 start_inWorldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(start_inChartspace); + Vector3 end_inWorldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(end_inChartspace); + Vector3 customAmplitudeAndTextDir = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace + chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace; + + float stylePatternScaleFactor_inWorldspace; + if (UtilitiesDXXL_Math.ApproximatelyZero(linestylePatternScaleFactor)) + { + stylePatternScaleFactor_inWorldspace = 0.0f; + } + else + { + stylePatternScaleFactor_inWorldspace = linestylePatternScaleFactor * chart_thisPointIsPartOf.Height_inWorldSpace; + } + float widened_stylePatternScaleFactor_inWorldspace = GetStylePatternScaleFactor_widenedForDottedStyles_inWorldspace(stylePatternScaleFactor_inWorldspace); + + if (UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_relToChartHeight)) + { + currLineWidth_inWorldUnits = 0.0f; + } + else + { + currLineWidth_inWorldUnits = lineWidth_relToChartHeight * chart_thisPointIsPartOf.Height_inWorldSpace; + } + lineStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(lineStyle); + Line_fadeableAnimSpeed.InternalDraw(start_inWorldspace, end_inWorldspace, color, currLineWidth_inWorldUnits, null, lineStyle, widened_stylePatternScaleFactor_inWorldspace, 0.0f, null, customAmplitudeAndTextDir, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true); + return true; + } + else + { + return false; + } + } + + void DrawCoordinateText_vertForXValues(bool vertLineHasBeenDrawnfloat, float durationInSec, bool hiddenByNearerObjects) + { + if (vertLineHasBeenDrawnfloat) + { + if (drawCoordinateAsText) + { + Vector2 position_chartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingLowerEndOfTheAxis); + Vector3 posOffset_forMoreLeveledDistanceToLine = (-chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace) * (chart_thisPointIsPartOf.yAxis.Length_inWorldSpace * sizeOfCoordinateText_relToChartHeight * relAdditionalShiftOfText); + float absHalfLineWidth_inWorldUnits = Mathf.Abs(0.5f * currLineWidth_inWorldUnits); + Vector3 posOffset_forDifferentLineWidths; + DrawText.TextAnchorDXXL textAnchor; + if (labelText == null || labelText == "") + { + textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.LowerRight : DrawText.TextAnchorDXXL.LowerLeft; + posOffset_forDifferentLineWidths = (-chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace) * absHalfLineWidth_inWorldUnits; + } + else + { + textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.UpperRight : DrawText.TextAnchorDXXL.UpperLeft; + posOffset_forDifferentLineWidths = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * absHalfLineWidth_inWorldUnits; + } + Vector3 position_worldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(position_chartspace) + posOffset_forMoreLeveledDistanceToLine + posOffset_forDifferentLineWidths; + float textSize = chart_thisPointIsPartOf.Height_inWorldSpace * sizeOfCoordinateText_relToChartHeight; + Vector3 textDir_normalized = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace; + Vector3 textUp_normalized = -chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + UtilitiesDXXL_Text.Write("" + position, position_worldspace, color, textSize, textDir_normalized, textUp_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisPointIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + } + + float relAdditionalShiftOfText = 0.3f; + void DrawCoordinateText_horizForYValues(bool horizLineHasBeenDrawn, float durationInSec, bool hiddenByNearerObjects) + { + if (horizLineHasBeenDrawn) + { + if (drawCoordinateAsText) + { + Vector2 position_chartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingLowerEndOfTheAxis, position); + Vector3 posOffset_forMoreLeveledDistanceToLine = chart_thisPointIsPartOf.yAxis.AxisVector_inWorldSpace * sizeOfCoordinateText_relToChartHeight * relAdditionalShiftOfText; + float absHalfLineWidth_inWorldUnits = Mathf.Abs(0.5f * currLineWidth_inWorldUnits); + Vector3 posOffset_forDifferentLineWidths; + DrawText.TextAnchorDXXL textAnchor; + if (labelText == null || labelText == "") + { + textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.LowerRight : DrawText.TextAnchorDXXL.LowerLeft; + posOffset_forDifferentLineWidths = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * absHalfLineWidth_inWorldUnits; + } + else + { + textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.UpperRight : DrawText.TextAnchorDXXL.UpperLeft; + posOffset_forDifferentLineWidths = (-chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace) * absHalfLineWidth_inWorldUnits; + } + Vector3 position_worldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(position_chartspace) + posOffset_forMoreLeveledDistanceToLine + posOffset_forDifferentLineWidths; + float textSize = chart_thisPointIsPartOf.Height_inWorldSpace * sizeOfCoordinateText_relToChartHeight; + Vector3 textDir_normalized = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + Vector3 textUp_normalized = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace; + UtilitiesDXXL_Text.Write("" + position, position_worldspace, color, textSize, textDir_normalized, textUp_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisPointIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + } + + void DrawLabelText_vertForXValues(bool vertLineHasBeenDrawn, float durationInSec, bool hiddenByNearerObjects) + { + if (vertLineHasBeenDrawn) + { + if (labelText != null && labelText != "") + { + Vector2 position_chartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingLowerEndOfTheAxis); + Vector3 posOffset_forMoreLeveledDistanceToLine = (-chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace) * (chart_thisPointIsPartOf.yAxis.Length_inWorldSpace * sizeOfCoordinateText_relToChartHeight * relAdditionalShiftOfText); + float absHalfLineWidth_inWorldUnits = Mathf.Abs(0.5f * currLineWidth_inWorldUnits); + Vector3 posOffset_forDifferentLineWidths = (-chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace) * absHalfLineWidth_inWorldUnits; + Vector3 position_worldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(position_chartspace) + posOffset_forMoreLeveledDistanceToLine + posOffset_forDifferentLineWidths; + float textSize = chart_thisPointIsPartOf.Height_inWorldSpace * sizeOfLabeltext_relToChartHeight; + Vector3 textDir_normalized = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace; + Vector3 textUp_normalized = -chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + DrawText.TextAnchorDXXL textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.LowerRight : DrawText.TextAnchorDXXL.LowerLeft; + UtilitiesDXXL_Text.Write(labelText, position_worldspace, color, textSize, textDir_normalized, textUp_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisPointIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + } + + void DrawLabelText_horizForYValues(bool horizLineHasBeenDrawn, float durationInSec, bool hiddenByNearerObjects) + { + if (horizLineHasBeenDrawn) + { + if (labelText != null && labelText != "") + { + Vector2 position_chartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingLowerEndOfTheAxis, position); + Vector3 posOffset_forMoreLeveledDistanceToLine = chart_thisPointIsPartOf.yAxis.AxisVector_inWorldSpace * sizeOfCoordinateText_relToChartHeight * relAdditionalShiftOfText; + float absHalfLineWidth_inWorldUnits = Mathf.Abs(0.5f * currLineWidth_inWorldUnits); + Vector3 posOffset_forDifferentLineWidths = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * absHalfLineWidth_inWorldUnits; + Vector3 position_worldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(position_chartspace) + posOffset_forMoreLeveledDistanceToLine + posOffset_forDifferentLineWidths; + float textSize = chart_thisPointIsPartOf.Height_inWorldSpace * sizeOfLabeltext_relToChartHeight; + Vector3 textDir_normalized = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + Vector3 textUp_normalized = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace; + DrawText.TextAnchorDXXL textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.LowerRight : DrawText.TextAnchorDXXL.LowerLeft; + UtilitiesDXXL_Text.Write(labelText, position_worldspace, color, textSize, textDir_normalized, textUp_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisPointIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + } + + float GetStylePatternScaleFactor_widenedForDottedStyles_inWorldspace(float unwidened_stylePatternScaleFactor_inWorldspace) + { + if (lineStyle == DrawBasics.LineStyle.dotted) + { + return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f; + } + if (lineStyle == DrawBasics.LineStyle.dottedDense) + { + return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f; + } + if (lineStyle == DrawBasics.LineStyle.dottedWide) + { + return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f; + } + if (lineStyle == DrawBasics.LineStyle.dotDash) + { + return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f; + } + if (lineStyle == DrawBasics.LineStyle.dotDashLong) + { + return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f; + } + if (lineStyle == DrawBasics.LineStyle.twoDash) + { + return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f; + } + if (lineStyle == DrawBasics.LineStyle.dashed) + { + return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f; + } + if (lineStyle == DrawBasics.LineStyle.dashedLong) + { + return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f; + } + return unwidened_stylePatternScaleFactor_inWorldspace; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/DimensionOf_PointOfInterest.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/DimensionOf_PointOfInterest.cs.meta new file mode 100644 index 0000000..6b25627 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/DimensionOf_PointOfInterest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb0d678b5da020c48b13303fbfe38aa2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/PointOfInterest.cs b/Runtime/DrawDebugLibrary/charts/line charts/PointOfInterest.cs new file mode 100644 index 0000000..89cf241 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/PointOfInterest.cs @@ -0,0 +1,369 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class PointOfInterest + { + private static float textSize_relToChartHeight = 0.04f; + public static float TextSize_relToChartHeight //This changes globally for all PointsOfInterest. This only affects the text in the textbox that is connected with a pointer. For the textsize right at the horizontal und vertical line throught the point: see "DimensionOf_PointOfInterest.SizeOfLabeltext_relToChartHeight" and "DimensionOf_PointOfInterest.SizeOfCoordinateText_relToChartHeight". + { + get { return textSize_relToChartHeight; } + set { textSize_relToChartHeight = Mathf.Max(value, 0.002f); } + } + public static float distanceBetweenTextBoxes_relToChartHeight = 0.06f; + public static float pointerConeLength_relToChartHeight = 0.05f; + + public DimensionOf_PointOfInterest xValue; + public DimensionOf_PointOfInterest yValue; + public string text; //if you want to let the textbox pointer point horizontally or vertically into the chart (indicating an x-value or y-value rather than an xy-position) you can set one of the two dimensions(xValue/yValue).position to float.NaN + public Color colorOfPointerTextBox; //this only sets the color of the pointer and the text box. If you want to set the color of the horizonal and vertical line use "SetWholeColor()" or "xValue/yValue.color" + public bool drawTextBoxIfPointIsOutsideOfChartArea = true; + public bool isDeletedOnClear = true; + public bool forceColorOfParent = false; //if this is enabled then "field.colorOfPointerTextBox" and "xValue/yValue.color" and "SetWholeColor" will have no effect anymore but it gets always the color used of the chart or the line this POI is part of. The alpha value is untouched and not forced from the parents.default is false. + public ChartDrawing chart_thisPointIsPartOf; + public ChartLine chartLine_thisPointIsPartOf; + bool isDrawnInNextPass; + public bool internal_isPOIthatCommunicatesTheHiddenPOIs = false; //"POI" = "point of interest" + + public PointOfInterest(float position_x, float position_y, Color color, ChartDrawing chart_thisPointIsPartOf, ChartLine chartLine_thisPointIsPartOf, string textToDisplay) + { + //use ChartDrawing.AddPointOfInterest() instead + //use ChartLine.AddPointOfInterest() instead + this.chart_thisPointIsPartOf = chart_thisPointIsPartOf; + this.chartLine_thisPointIsPartOf = chartLine_thisPointIsPartOf; + if (chart_thisPointIsPartOf == null && chartLine_thisPointIsPartOf != null) + { + this.chart_thisPointIsPartOf = chartLine_thisPointIsPartOf.Chart_thisLineIsPartOf; + } + this.colorOfPointerTextBox = color; + xValue = new DimensionOf_PointOfInterest(position_x, color, UtilitiesDXXL_Math.Dimension.x, chart_thisPointIsPartOf); + yValue = new DimensionOf_PointOfInterest(position_y, color, UtilitiesDXXL_Math.Dimension.y, chart_thisPointIsPartOf); + xValue.theOtherDimension = yValue; + yValue.theOtherDimension = xValue; + text = textToDisplay; + } + + public Vector3 TryDraw(Vector3 lowAnchorPositionOfText_inWorldspace, UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted, float durationInSec, bool hiddenByNearerObjects) + { + //use ChartDrawing.Draw() instead + + //"cornerOfChartWhereTextBoxIsMounted": only "upLeft" and "upRight" are implemented + if (isDrawnInNextPass) + { + TryForceColorFromParent(false); + xValue.Draw(durationInSec, hiddenByNearerObjects); + yValue.Draw(durationInSec, hiddenByNearerObjects); + Vector3 lowAnchorPositionOfNextText_inWorldspace = TryDrawTextBoxAndPointer(lowAnchorPositionOfText_inWorldspace, cornerOfChartWhereTextBoxIsMounted, durationInSec, hiddenByNearerObjects); + return lowAnchorPositionOfNextText_inWorldspace; + } + else + { + Vector3 lowAnchorPositionOfNextText_inWorldspace = lowAnchorPositionOfText_inWorldspace; + return lowAnchorPositionOfNextText_inWorldspace; + } + } + + Vector3 TryDrawTextBoxAndPointer(Vector3 lowAnchorPositionOfText_inWorldspace, UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 lowAnchorPositionOfNextText_inWorldspace; + if (HasTextBox()) + { + GetIfAndHowPointerIsDrawn(out Vector2 posOfPointOfInterest_chartSpace, out bool oneDimIsValid_theOtherOneIsInvalid, out UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, out bool textboxIsDrawn, out bool pointerIsDrawn, out string printedText); + if (textboxIsDrawn) + { + lowAnchorPositionOfNextText_inWorldspace = DrawTextBoxAndPointer(pointerIsDrawn, lowAnchorPositionOfText_inWorldspace, posOfPointOfInterest_chartSpace, oneDimIsValid_theOtherOneIsInvalid, theSingleValidDimension, printedText, cornerOfChartWhereTextBoxIsMounted, durationInSec, hiddenByNearerObjects); + } + else + { + lowAnchorPositionOfNextText_inWorldspace = lowAnchorPositionOfText_inWorldspace; + } + } + else + { + lowAnchorPositionOfNextText_inWorldspace = lowAnchorPositionOfText_inWorldspace; + } + return lowAnchorPositionOfNextText_inWorldspace; + } + + UtilitiesDXXL_Math.DimensionNullable GetTheSingleValidDimension(bool oneDimIsValid_theOtherOneIsInvalid, bool xDim_isValid) + { + UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension = UtilitiesDXXL_Math.DimensionNullable.none; + if (oneDimIsValid_theOtherOneIsInvalid) + { + if (xDim_isValid) + { + theSingleValidDimension = UtilitiesDXXL_Math.DimensionNullable.x; + } + else + { + theSingleValidDimension = UtilitiesDXXL_Math.DimensionNullable.y; + } + } + return theSingleValidDimension; + } + + + bool CheckIf_isInsideChartArea(bool bothDimValuesAreInvalid, bool bothDimValuesAreValid, UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, Vector2 posOfPointOfInterest_chartSpace) + { + if (bothDimValuesAreInvalid) + { + return false; + } + else + { + if (bothDimValuesAreValid) + { + return chart_thisPointIsPartOf.IsInsideDrawnChartArea(posOfPointOfInterest_chartSpace); + } + else + { + if (theSingleValidDimension == UtilitiesDXXL_Math.DimensionNullable.x) + { + return chart_thisPointIsPartOf.xAxis.IsInsideDisplayedSpan(xValue.position); + } + else + { + return chart_thisPointIsPartOf.yAxis.IsInsideDisplayedSpan(yValue.position); + } + } + } + } + + public int Internal_Set_isDrawnInNextPass(int stillAvailableTextBoxes) + { + if (HasTextBox()) + { + if (TextBoxWillAnywayNotGetDrawn_becauseOfItsSettingThatHidesItOutsideOfTheChartArea()) + { + isDrawnInNextPass = true; //Enable the possibility that a horiz/vert-crosshair may get drawn... + return stillAvailableTextBoxes; //...but don't affect the "available text boxes"-count + } + else + { + isDrawnInNextPass = (stillAvailableTextBoxes > 0); + return (stillAvailableTextBoxes - 1); + } + } + else + { + isDrawnInNextPass = true; + return stillAvailableTextBoxes; + } + } + + bool TextBoxWillAnywayNotGetDrawn_becauseOfItsSettingThatHidesItOutsideOfTheChartArea() + { + GetIfAndHowPointerIsDrawn(out Vector2 posOfPointOfInterest_chartSpace, out bool oneDimIsValid_theOtherOneIsInvalid, out UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, out bool textboxIsDrawn, out bool pointerIsDrawn, out string printedText); + return (!textboxIsDrawn); + } + + void GetIfAndHowPointerIsDrawn(out Vector2 posOfPointOfInterest_chartSpace, out bool oneDimIsValid_theOtherOneIsInvalid, out UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, out bool textboxIsDrawn, out bool pointerIsDrawn, out string printedText) + { + posOfPointOfInterest_chartSpace = new Vector2(xValue.position, yValue.position); + bool xDim_isValid = UtilitiesDXXL_Math.FloatIsValid(xValue.position); + bool yDim_isValid = UtilitiesDXXL_Math.FloatIsValid(yValue.position); + bool atLeastOneDimValueIsValid = (xDim_isValid || yDim_isValid); + bool bothDimValuesAreValid = (xDim_isValid && yDim_isValid); + bool bothDimValuesAreInvalid = ((xDim_isValid == false) && (yDim_isValid == false)); + oneDimIsValid_theOtherOneIsInvalid = (xDim_isValid != yDim_isValid); + theSingleValidDimension = GetTheSingleValidDimension(oneDimIsValid_theOtherOneIsInvalid, xDim_isValid); + bool isInsideChartArea = CheckIf_isInsideChartArea(bothDimValuesAreInvalid, bothDimValuesAreValid, theSingleValidDimension, posOfPointOfInterest_chartSpace); + GetIfAndHowPointerIsDrawn(out textboxIsDrawn, out pointerIsDrawn, out printedText, isInsideChartArea, atLeastOneDimValueIsValid); + } + + void GetIfAndHowPointerIsDrawn(out bool textboxIsDrawn, out bool pointerIsDrawn, out string printedText, bool isInsideChartArea, bool atLeastOneDimValueIsValid) + { + printedText = null; + if (internal_isPOIthatCommunicatesTheHiddenPOIs) + { + textboxIsDrawn = true; + pointerIsDrawn = false; + printedText = text; + } + else + { + if (isInsideChartArea || chart_thisPointIsPartOf.drawValuesOutsideOfChartArea) + { + textboxIsDrawn = true; + pointerIsDrawn = atLeastOneDimValueIsValid ? true : false; + printedText = text; + } + else + { + //->"is OUTSIDE of chart area" and "chart DOESN'T draw values outside of the chart area" + pointerIsDrawn = false; + if (drawTextBoxIfPointIsOutsideOfChartArea) + { + textboxIsDrawn = true; + printedText = "[ Is outside of chart area at
( " + xValue.position + " / " + yValue.position + " )]
" + text; + } + else + { + textboxIsDrawn = false; + } + } + } + } + + Vector3 DrawTextBoxAndPointer(bool pointerIsDrawn, Vector3 lowAnchorPositionOfText_inWorldspace, Vector2 posOfPointOfInterest_chartSpace, bool oneDimIsValid_theOtherOneIsInvalid, UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, string printedText, UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted, float durationInSec, bool hiddenByNearerObjects) + { + float textSize = textSize_relToChartHeight * chart_thisPointIsPartOf.Height_inWorldSpace; + DrawText.TextAnchorDXXL textAnchor; + if (cornerOfChartWhereTextBoxIsMounted == UtilitiesDXXL_Math.SkewedDirection.upLeft) + { + //topLeftCorner: + textAnchor = DrawText.TextAnchorDXXL.LowerRight; + } + else + { + //topRightCorner: + textAnchor = DrawText.TextAnchorDXXL.LowerLeft; + } + float enclosingBox_paddingSize_relToTextSize = 0.0f; + float autoLineBreakWidth = 0.7f * chart_thisPointIsPartOf.Width_inWorldSpace; + + UtilitiesDXXL_Text.WriteFramed(printedText, lowAnchorPositionOfText_inWorldspace, colorOfPointerTextBox, textSize, chart_thisPointIsPartOf.InternalRotation, textAnchor, DrawBasics.LineStyle.solid, 0.0f, enclosingBox_paddingSize_relToTextSize, 0.0f, 0.0f, autoLineBreakWidth, chart_thisPointIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects); + if (pointerIsDrawn) + { + DrawPointer(posOfPointOfInterest_chartSpace, oneDimIsValid_theOtherOneIsInvalid, theSingleValidDimension, cornerOfChartWhereTextBoxIsMounted, durationInSec, hiddenByNearerObjects); + } + + Vector3 highCorner_ofTextBox_worldSpace; + if (cornerOfChartWhereTextBoxIsMounted == UtilitiesDXXL_Math.SkewedDirection.upLeft) + { + //boxes in topLeftCorner: + highCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.upperRightPos_ofEnclosingBox; + } + else + { + //boxes in topRightCorner: + highCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.upperLeftPos_ofEnclosingBox; + } + return (highCorner_ofTextBox_worldSpace + chart_thisPointIsPartOf.yAxis.AxisVector_inWorldSpace * distanceBetweenTextBoxes_relToChartHeight); + } + + void DrawPointer(Vector2 posOfPointOfInterest_chartSpace, bool oneDimIsValid_theOtherOneIsInvalid, UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted, float durationInSec, bool hiddenByNearerObjects) + { + //-> already guaranteed here: at least one dimension value is valid: + + Vector3 lowInnerCorner_ofTextBox_worldSpace; + Vector3 lowOuterCorner_ofTextBox_worldSpace; + if (cornerOfChartWhereTextBoxIsMounted == UtilitiesDXXL_Math.SkewedDirection.upLeft) + { + //boxes in topLeftCorner: + lowInnerCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.lowRightPos_ofEnclosingBox; + lowOuterCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.lowLeftPos_ofEnclosingBox; + } + else + { + //boxes in topRightCorner: + lowInnerCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.lowLeftPos_ofEnclosingBox; + lowOuterCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.lowRightPos_ofEnclosingBox; + } + + float forceFixedConeLength = chart_thisPointIsPartOf.Height_inWorldSpace * pointerConeLength_relToChartHeight; + + bool pointerIsDrawnWithKink_thenAxisParallelIntoChart = oneDimIsValid_theOtherOneIsInvalid; + if (pointerIsDrawnWithKink_thenAxisParallelIntoChart) + { + DrawPointerWithKink(lowInnerCorner_ofTextBox_worldSpace, lowOuterCorner_ofTextBox_worldSpace, theSingleValidDimension, cornerOfChartWhereTextBoxIsMounted, forceFixedConeLength, durationInSec, hiddenByNearerObjects); + } + else + { + DrawPointerWithoutKink(posOfPointOfInterest_chartSpace, lowInnerCorner_ofTextBox_worldSpace, forceFixedConeLength, durationInSec, hiddenByNearerObjects); + } + } + + void DrawPointerWithKink(Vector3 lowInnerCorner_ofTextBox_worldSpace, Vector3 lowOuterCorner_ofTextBox_worldSpace, UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted, float forceFixedConeLength, float durationInSec, bool hiddenByNearerObjects) + { + float lengthFactor_forAxisParallelPointerSection = 0.1f; + Vector3 customAmplitudeAndTextDir; + Vector3 startPosAtTextBoxCorner_worldSpace; + Vector3 kinkPosToFinalPointer_worldSpace; + Vector3 pointerTargetPos_worldSpace; + + if (theSingleValidDimension == UtilitiesDXXL_Math.DimensionNullable.x) + { + customAmplitudeAndTextDir = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + startPosAtTextBoxCorner_worldSpace = lowInnerCorner_ofTextBox_worldSpace; + Vector2 pointerTargetPos_chartSpace = new Vector2(xValue.position, chart_thisPointIsPartOf.yAxis.ValueMarkingUpperEndOfTheAxis); + pointerTargetPos_worldSpace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(pointerTargetPos_chartSpace) - chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * (0.5f * pointerConeLength_relToChartHeight); + kinkPosToFinalPointer_worldSpace = pointerTargetPos_worldSpace + chart_thisPointIsPartOf.yAxis.AxisVector_inWorldSpace * lengthFactor_forAxisParallelPointerSection; + } + else + { + customAmplitudeAndTextDir = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace; + startPosAtTextBoxCorner_worldSpace = lowOuterCorner_ofTextBox_worldSpace; + if (cornerOfChartWhereTextBoxIsMounted == UtilitiesDXXL_Math.SkewedDirection.upLeft) + { + Vector2 pointerTargetPos_chartSpace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingLowerEndOfTheAxis, yValue.position); + pointerTargetPos_worldSpace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(pointerTargetPos_chartSpace); + kinkPosToFinalPointer_worldSpace = pointerTargetPos_worldSpace - chart_thisPointIsPartOf.xAxis.AxisVector_inWorldSpace * lengthFactor_forAxisParallelPointerSection; + } + else + { + Vector2 pointerTargetPos_chartSpace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingUpperEndOfTheAxis, yValue.position); + pointerTargetPos_worldSpace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(pointerTargetPos_chartSpace); + kinkPosToFinalPointer_worldSpace = pointerTargetPos_worldSpace + chart_thisPointIsPartOf.xAxis.AxisVector_inWorldSpace * lengthFactor_forAxisParallelPointerSection; + } + } + + Line_fadeableAnimSpeed.InternalDraw(startPosAtTextBoxCorner_worldSpace, kinkPosToFinalPointer_worldSpace, colorOfPointerTextBox, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + bool setConeLengthToRelative_notToAbsolute = UtilitiesDXXL_Math.ApproximatelyZero(forceFixedConeLength); + float coneLength_ifSetToRelative = 0.17f; + float coneLength_ifSetToAbsolute = forceFixedConeLength; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + DrawBasics.Vector(kinkPosToFinalPointer_worldSpace, pointerTargetPos_worldSpace, colorOfPointerTextBox, 0.0f, null, coneLength, false, true, customAmplitudeAndTextDir, false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + void DrawPointerWithoutKink(Vector2 posOfPointOfInterest_chartSpace, Vector3 lowInnerCorner_ofTextBox_worldSpace, float forceFixedConeLength, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 customAmplitudeAndTextDir = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace; + Vector3 startPosAtTextBoxCorner_worldSpace = lowInnerCorner_ofTextBox_worldSpace; + Vector3 pointerTargetPos_worldSpace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(posOfPointOfInterest_chartSpace); + + bool setConeLengthToRelative_notToAbsolute = UtilitiesDXXL_Math.ApproximatelyZero(forceFixedConeLength); + float coneLength_ifSetToRelative = 0.17f; + float coneLength_ifSetToAbsolute = forceFixedConeLength; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + DrawBasics.Vector(startPosAtTextBoxCorner_worldSpace, pointerTargetPos_worldSpace, colorOfPointerTextBox, 0.0f, null, coneLength, false, true, customAmplitudeAndTextDir, false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + public void SetWholeColor(Color newColor) + { + //This not only sets the color of the poiner and the text box (as setting field.colorOfPointerTextBox would) but also of the horizonal and vertical line. + colorOfPointerTextBox = newColor; + xValue.color = newColor; + yValue.color = newColor; + } + + void TryForceColorFromParent(bool alsoForceAlpha = false) + { + if (forceColorOfParent) + { + if (chartLine_thisPointIsPartOf != null) + { + colorOfPointerTextBox = new Color(chartLine_thisPointIsPartOf.Color.r, chartLine_thisPointIsPartOf.Color.g, chartLine_thisPointIsPartOf.Color.b, alsoForceAlpha ? chartLine_thisPointIsPartOf.Color.a : colorOfPointerTextBox.a); + xValue.color = new Color(chartLine_thisPointIsPartOf.Color.r, chartLine_thisPointIsPartOf.Color.g, chartLine_thisPointIsPartOf.Color.b, alsoForceAlpha ? chartLine_thisPointIsPartOf.Color.a : xValue.color.a); + yValue.color = new Color(chartLine_thisPointIsPartOf.Color.r, chartLine_thisPointIsPartOf.Color.g, chartLine_thisPointIsPartOf.Color.b, alsoForceAlpha ? chartLine_thisPointIsPartOf.Color.a : yValue.color.a); + } + else + { + colorOfPointerTextBox = new Color(chart_thisPointIsPartOf.color.r, chart_thisPointIsPartOf.color.g, chart_thisPointIsPartOf.color.b, alsoForceAlpha ? chart_thisPointIsPartOf.color.a : colorOfPointerTextBox.a); + xValue.color = new Color(chart_thisPointIsPartOf.color.r, chart_thisPointIsPartOf.color.g, chart_thisPointIsPartOf.color.b, alsoForceAlpha ? chart_thisPointIsPartOf.color.a : xValue.color.a); + yValue.color = new Color(chart_thisPointIsPartOf.color.r, chart_thisPointIsPartOf.color.g, chart_thisPointIsPartOf.color.b, alsoForceAlpha ? chart_thisPointIsPartOf.color.a : yValue.color.a); + } + } + } + + bool HasTextBox() + { + return (text != null && text != ""); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/PointOfInterest.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/PointOfInterest.cs.meta new file mode 100644 index 0000000..92c0903 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/PointOfInterest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1a53c3d7c3432844a878b6f098221fda +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities.meta new file mode 100644 index 0000000..7caec79 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: afd6e8e1c61d3a1449bce3b17b0d4efa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/DrawXXLChartInspector.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/DrawXXLChartInspector.cs new file mode 100644 index 0000000..b229d3f --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/DrawXXLChartInspector.cs @@ -0,0 +1,1294 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Internal Not For Manual Creation/Draw XXL Chart Inspector")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + [ExecuteInEditMode] + public class DrawXXLChartInspector : MonoBehaviour + { + public bool hasBeenManuallyCreated = true; + public bool hasBeenCreatedOutsidePlaymode; + public ChartDrawing chart_thisInspectorIsAttachedTo; + [SerializeField] InternalDXXL_LineSpecsForChartInspector[] specsForInspector_forEachDrawnLine = new InternalDXXL_LineSpecsForChartInspector[0]; + public bool theChartIsDrawnInScreenspace; + public Camera screenSpaceTargetCamera; + public bool chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight; + public bool nonScreenspaceDrawing_happensWith_drawConfigOf_hiddenByNearerObjects; +#if UNITY_EDITOR + [SerializeField] bool forceSceneViewCamToFollowChart = false; +#endif + static float default_sizeArbUnits_ofSceneViewCam = 0.6f; + [SerializeField] [Range(0.0f, 1.0f)] float sizeArbUnits_ofSceneViewCam = default_sizeArbUnits_ofSceneViewCam; + + [SerializeField] public bool hideHandles_andInsteadUseInspectorSlidersForZoomAndScroll = false; + [SerializeField] public bool sceneViewCamSection_isExpanded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool cursorSection_isExpanded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool axesSection_isExpanded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool otherSection_isExpanded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool csvExportSection_isExpanded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool clearButtonSection_isExpanded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + public float curr_cursorPosition_as0to1OfChartWidth; + bool cursorPos_hasBeenCalcedAtLeastOnce = false; + [SerializeField] float curr_cursorPosition_inChartspaceUnits; + float prev_cursorPosition_inChartspaceUnits; + [SerializeField] [Range(0.0f, 1.0f)] public float cursorPos0to1_raw = 0.5f; + [SerializeField] [Range(-0.025f, 0.025f)] public float cursorPos0to1_finetune = 0.0f; + [SerializeField] [Range(-0.001f, 0.001f)] public float cursorPos0to1_superFinetune = 0.0f; + + [SerializeField] [Range(0.0f, 1.0f)] float sizeOfDatapointVisualization = 0.3f; + [SerializeField] public bool alwaysEncapsulateAllValues = false; + + float xAxisLowEnd_inMomentOfComponentCreation; + float xAxisUpperEnd_inMomentOfComponentCreation; + float yAxisLowEnd_inMomentOfComponentCreation; + float yAxisUpperEnd_inMomentOfComponentCreation; + + [Range(0.001f, 1.0f)] public float curr_luminanceOfLineColors_accordingToSlider; //"0.001f" instead of "0.0f": The luminance jumps to "0.5" if the slider is at "0.0f", maybe due to a rounding error in "Mathf.Clamp01" + public float prev_luminanceOfLineColors_accordingToSlider; + public float prev_luminanceOfLineColors_accordingToChartSetting; + [SerializeField] string csvFileName = "" + InternalDXXL_ChartToCSVfileWriter.default_csvFileName; + public ChartLine.NamePosition lineNamePositions; + [Range(0.0f, 12.0f)] public float lineNames_sizeScaleFactor; + [SerializeField] int drawnSmallStraightLines_duringLastDrawRun; + bool isFirstUpdateCycleAfterGamePause = false; +#if UNITY_EDITOR + int mostCurrentFrameCountDuringGamePause = -10; + bool editorUpdateCallback_hasBeenRegistered = false; +#endif + + void Start() + { +#if UNITY_EDITOR + UnityEditor.EditorApplication.update += EditorUpdateCallback; + editorUpdateCallback_hasBeenRegistered = true; + mostCurrentFrameCountDuringGamePause = -10; +#endif + } + + void OnDestroy() + { +#if UNITY_EDITOR + if (editorUpdateCallback_hasBeenRegistered) + { + UnityEditor.EditorApplication.update -= EditorUpdateCallback; + editorUpdateCallback_hasBeenRegistered = false; + } + TrySetChartsNonScreenspacePosToValues_fromBeforeComponentInspectionPhase_caseComponentInspectionPhaseDrewToScreenspace(); +#endif + } + + void EditorUpdateCallback() + { +#if UNITY_EDITOR + + if ((UnityEditor.EditorApplication.isPlaying == false) || UnityEditor.EditorApplication.isPaused) + { + if (GUIUtility.hotControl != 0) //mouse button is held down on a handle + { + //this ensures that "OnDrawGizmos" is called at fluent regular intervals also during pauseState of the game. + //Without this the inspector sliders for "zoom" and "scroll" would be jittering: + //During pauseGame the "OnDrawGizmos" function is only called if something in the component changes, e.g. a slider position. + //The sliders for "zoom" and "scroll" have in some situations effect on the axis scaling also if they don't change, namely when the user drags them with their mouse to the side and then holds them at this sidePosition via keepMousePressed. + //Since in these situations "nothing in the editor changes" (the mouse position stays the same, and the mouseClickState stays the same) nothing would trigger "OnDrawGizmos", but in "OnDrawGizmos" happens the actual updating of the axis scaling. + //An alternative would be to make this "SetDirty" in "OnInspectorGUI" but then it's still jittery, because "OnInspectorGUI" is obviously called far less often than "EditorApplication.update", and also less often than the normal Update-Cylce during gameRunsPhases. + UnityEditor.EditorUtility.SetDirty(this); + } + } + + UtilitiesDXXL_Components.TryProceedOneSheduledFrameStep(); +#endif + } + + Vector3 nonScreenspaceChartPosition_beforeComponentInspectionPhaseThatDrawsToScreenspace; + Quaternion nonScreenspaceChartFixedRotation_beforeComponentInspectionPhaseThatDrawsToScreenspace; + float nonScreenspaceChartWidthWorldspace_beforeComponentInspectionPhaseThatDrawsToScreenspace; + float nonScreenspaceChartHeigthWorldspace_beforeComponentInspectionPhaseThatDrawsToScreenspace; + public void AssignChart(ChartDrawing chart_thisInspectorShouldBeAttachedTo) + { + chart_thisInspectorIsAttachedTo = chart_thisInspectorShouldBeAttachedTo; + FetchAxisScaleInMomentOfComponentCreation(); + + if (theChartIsDrawnInScreenspace) + { + nonScreenspaceChartPosition_beforeComponentInspectionPhaseThatDrawsToScreenspace = chart_thisInspectorIsAttachedTo.Position_worldspace; + nonScreenspaceChartFixedRotation_beforeComponentInspectionPhaseThatDrawsToScreenspace = chart_thisInspectorIsAttachedTo.fixedRotation; + nonScreenspaceChartWidthWorldspace_beforeComponentInspectionPhaseThatDrawsToScreenspace = chart_thisInspectorIsAttachedTo.Width_inWorldSpace; + nonScreenspaceChartHeigthWorldspace_beforeComponentInspectionPhaseThatDrawsToScreenspace = chart_thisInspectorIsAttachedTo.Height_inWorldSpace; + + if (screenSpaceTargetCamera == null) + { + Debug.LogError("Chart: CreateChartInspectionGameobject errorneous, because targetCamera is null."); + } + } + } + + void TrySetChartsNonScreenspacePosToValues_fromBeforeComponentInspectionPhase_caseComponentInspectionPhaseDrewToScreenspace() + { + if (theChartIsDrawnInScreenspace) + { + if (chart_thisInspectorIsAttachedTo != null) + { + chart_thisInspectorIsAttachedTo.Position_worldspace = nonScreenspaceChartPosition_beforeComponentInspectionPhaseThatDrawsToScreenspace; + chart_thisInspectorIsAttachedTo.fixedRotation = nonScreenspaceChartFixedRotation_beforeComponentInspectionPhaseThatDrawsToScreenspace; + chart_thisInspectorIsAttachedTo.Width_inWorldSpace = nonScreenspaceChartWidthWorldspace_beforeComponentInspectionPhaseThatDrawsToScreenspace; + chart_thisInspectorIsAttachedTo.Height_inWorldSpace = nonScreenspaceChartHeigthWorldspace_beforeComponentInspectionPhaseThatDrawsToScreenspace; + } + } + } + + void FetchAxisScaleInMomentOfComponentCreation() + { + if (UtilitiesDXXL_Math.FloatIsValid(chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis)) + { + xAxisLowEnd_inMomentOfComponentCreation = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis; + } + else + { + xAxisLowEnd_inMomentOfComponentCreation = -100.0f; + } + + if (UtilitiesDXXL_Math.FloatIsValid(chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis)) + { + xAxisUpperEnd_inMomentOfComponentCreation = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis; + } + else + { + xAxisUpperEnd_inMomentOfComponentCreation = 100.0f; + } + + if (UtilitiesDXXL_Math.FloatIsValid(chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis)) + { + yAxisLowEnd_inMomentOfComponentCreation = chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis; + } + else + { + yAxisLowEnd_inMomentOfComponentCreation = -100.0f; + } + + if (UtilitiesDXXL_Math.FloatIsValid(chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis)) + { + yAxisUpperEnd_inMomentOfComponentCreation = chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis; + } + else + { + yAxisUpperEnd_inMomentOfComponentCreation = 100.0f; + } + } + + void LateUpdate() + { +#if UNITY_EDITOR + if (TryDestroyThisComponentIfItWasManuallyCreated()) { return; } + if (TryDestroyComonent_ifChartGotLost()) { return; } + + if (this.enabled) + { + if (UnityEditor.EditorApplication.isPlaying && (UnityEditor.EditorApplication.isPaused == false)) + { + if (TrySkipDrawingBecauseItIsTheFirstFrameAfterAPausePhase()) { return; } + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + UtilitiesDXXL_Components.ExpandComponentInInspector(this); + + UtilitiesDXXL_DrawBasics.Set_usedLineDrawingMethod_reversible(DrawBasics.UsedUnityLineDrawingMethod.debugLines); + DrawChartAndCursor(); + UtilitiesDXXL_DrawBasics.Reverse_usedLineDrawingMethod(); + } + } +#endif + } + + void OnDrawGizmos() + { +#if UNITY_EDITOR + if (TryDestroyThisComponentIfItWasManuallyCreated()) { return; } + if (TryDestroyComonent_ifChartGotLost()) { return; } + + if (this.enabled) + { + if ((UnityEditor.EditorApplication.isPlaying == false) || UnityEditor.EditorApplication.isPaused) + { + UtilitiesDXXL_Components.currentVirtualOnDrawGizmoCycle_shouldRepaintAllViews = true; + UtilitiesDXXL_Components.ReportOnDrawGizmosCycleOfAMonoBehaviour(this.GetInstanceID()); + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + UtilitiesDXXL_Components.ExpandComponentInInspector(this); + + UtilitiesDXXL_DrawBasics.Set_usedLineDrawingMethod_reversible(DrawBasics.UsedUnityLineDrawingMethod.gizmoLines); //-> "debugLinesInPlayMode_gizmoLinesInEditModeAndPlaymodePauses" is not an option here, because "DXXLWrapperForUntiysBuildInDrawLines.ChooseDebugOrGizmoLines_dependingOnPlayModeState()" forces to debug lines in some cases even if "pause == true" + UtilitiesDXXL_DrawBasics.Set_gizmoMatrix_reversible(Matrix4x4.identity); + DrawChartAndCursor(); + UtilitiesDXXL_DrawBasics.Reverse_gizmoMatrix(); + UtilitiesDXXL_DrawBasics.Reverse_usedLineDrawingMethod(); + } + } + + TrySheduleAutomaticFrameStepAtTheStartOfPausePhases(); +#endif + } + + void DrawChartAndCursor() + { + long drawnLines_beforeCurrDrawRun = DXXLWrapperForUntiysBuildInDrawLines.DrawnLinesSinceStart; //using "DXXLWrapperForUntiyDebugDraw.DrawnLinesSinceStart" instead of "DXXLWrapperForUntiyDebugDraw.DrawnLinesSinceFrameStart" because if this is the only drawn thing inside the frame, then the following "DrawChart()" resets the "DrawnLinesSinceFrameStart"-counter (because it's the first drawn thing since "Time.frameCount" was incremented), so the herewith obtained "lineCounter_beforeDrawing" is not accurate anymore. + TrySetLuminanceOfLineColors(); + SetLineNamePositionsAndSize(); + RecalcCursorPosition(); + ScaleAxes(); //-> this can also call "RecalcCursorPosition()" again + + DrawTheChart(); + + TryNote_chartWorldSpacePosRotScale_beforeChangingItToScreenspace(); + try + { + if (theChartIsDrawnInScreenspace) { UtilitiesDXXL_ChartDrawing.SetPosRotScaleOfChart_toScreenspace(chart_thisInspectorIsAttachedTo, screenSpaceTargetCamera, chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, true); } + DrawCursor(); + TryDrawUnified45degAxisForHandles(); + SetTransformToChartPos(); + TryPlaceSceneviewCam(); + } + catch { } + TrySetBack_chartWorldSpacePosRotScale_afterUsingItInScreenspace(); + + RefillArraysWithCursorNeighboringDatapointsForEachLine(); + + drawnSmallStraightLines_duringLastDrawRun = (int)(DXXLWrapperForUntiysBuildInDrawLines.DrawnLinesSinceStart - drawnLines_beforeCurrDrawRun); + } + + void RecalcCursorPosition() + { + if (cursorPos_hasBeenCalcedAtLeastOnce) + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(prev_cursorPosition_inChartspaceUnits, curr_cursorPosition_inChartspaceUnits) == false) + { + //cursor pos has been set without slider, but via float number field: + ForceCursorSliders_toFitGivenChartspaceXPos(curr_cursorPosition_inChartspaceUnits); + } + } + + if (UtilitiesDXXL_Math.FloatIsInvalid(cursorPos0to1_raw)) { cursorPos0to1_raw = 0.5f; } + if (UtilitiesDXXL_Math.FloatIsInvalid(cursorPos0to1_finetune)) { cursorPos0to1_finetune = 0.0f; } + if (UtilitiesDXXL_Math.FloatIsInvalid(cursorPos0to1_superFinetune)) { cursorPos0to1_superFinetune = 0.0f; } + curr_cursorPosition_as0to1OfChartWidth = cursorPos0to1_raw + cursorPos0to1_finetune + cursorPos0to1_superFinetune; + curr_cursorPosition_as0to1OfChartWidth = Mathf.Clamp01(curr_cursorPosition_as0to1OfChartWidth); + if (UtilitiesDXXL_Math.FloatIsInvalid(curr_cursorPosition_as0to1OfChartWidth)) { curr_cursorPosition_as0to1OfChartWidth = 0.5f; } + curr_cursorPosition_inChartspaceUnits = ConvertXPos_from_0to1units_to_chartspaceUnits(curr_cursorPosition_as0to1OfChartWidth); + if (UtilitiesDXXL_Math.FloatIsInvalid(curr_cursorPosition_inChartspaceUnits)) { curr_cursorPosition_inChartspaceUnits = 0.0f; } + + TryRecalc_posThatIsNearestToCursor_forEachLine(); + prev_cursorPosition_inChartspaceUnits = curr_cursorPosition_inChartspaceUnits; + cursorPos_hasBeenCalcedAtLeastOnce = true; + } + + void ForceCursorSliders_toFitGivenChartspaceXPos(float new_cursorPosition_inChartspaceUnits) + { + float new_cursorPosition_as0to1OfChartWidth = ConvertXPos_from_chartspaceUnits_to_0to1units(new_cursorPosition_inChartspaceUnits); + ForceCursorSliders_toFitGiven0to1XPos(new_cursorPosition_as0to1OfChartWidth); + } + + public void ForceCursorSliders_toFitGiven0to1XPos(float new_cursorPosition_as0to1OfChartWidth) + { + new_cursorPosition_as0to1OfChartWidth = Mathf.Clamp01(new_cursorPosition_as0to1OfChartWidth); + + //Start with trying to change only the raw-slider: + cursorPos0to1_raw = new_cursorPosition_as0to1OfChartWidth - cursorPos0to1_finetune - cursorPos0to1_superFinetune; + + if ((cursorPos0to1_raw < 0.0f) || (cursorPos0to1_raw > 1.0f)) + { + //-> deplete the lower ranked finetune-sliders, if the raw slider overshot the 0to1-range + //-> if this would be done each time without the preceding if-check, then the finetune sliders would not be dragable for activated "alwaysEncapsulateAllValues" + cursorPos0to1_finetune = 0.0f; + cursorPos0to1_superFinetune = 0.0f; + cursorPos0to1_raw = new_cursorPosition_as0to1OfChartWidth; + } + } + + float ConvertXPos_from_chartspaceUnits_to_0to1units(float xPositionInChartspaceUnits_toConvert) + { + float lowerEndOfXAxis_to_upperEndOfXAxis_inChartspaceUnits = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis - chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis; + return ((xPositionInChartspaceUnits_toConvert - chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis) / lowerEndOfXAxis_to_upperEndOfXAxis_inChartspaceUnits); + } + + float ConvertXPos_from_0to1units_to_chartspaceUnits(float xPositionAs0to1OfChartWidth_toConvert) + { + float lowerEndOfXAxis_to_upperEndOfXAxis_inChartspaceUnits = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis - chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis; + return (chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis + lowerEndOfXAxis_to_upperEndOfXAxis_inChartspaceUnits * xPositionAs0to1OfChartWidth_toConvert); + } + + float ConvertXSpan_from_0to1units_to_chartspaceUnits(float xSpanAs0to1OfChartWidth_toConvert) + { + float lowerEndOfXAxis_to_upperEndOfXAxis_inChartspaceUnits = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis - chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis; + return (lowerEndOfXAxis_to_upperEndOfXAxis_inChartspaceUnits * xSpanAs0to1OfChartWidth_toConvert); + } + + float ConvertYSpan_from_0to1units_to_chartspaceUnits(float ySpanAs0to1OfChartWidth_toConvert) + { + float lowerEndOfYAxis_to_upperEndOfYAxis_inChartspaceUnits = chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis - chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis; + return (lowerEndOfYAxis_to_upperEndOfYAxis_inChartspaceUnits * ySpanAs0to1OfChartWidth_toConvert); + } + + void TryRecalc_posThatIsNearestToCursor_forEachLine() + { + bool cursorPosHasChanged = (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(curr_cursorPosition_inChartspaceUnits, prev_cursorPosition_inChartspaceUnits) == false); + if (cursorPosHasChanged || (cursorPos_hasBeenCalcedAtLeastOnce == false)) + { + for (int i = 0; i < specsForInspector_forEachDrawnLine.Length; i++) + { + specsForInspector_forEachDrawnLine[i].Recalc_posThatIsXNearestToCursor(curr_cursorPosition_inChartspaceUnits); + } + } + } + + public void ResetAxesScalingTo_stateInMomentOfComponentCreation() + { + chart_thisInspectorIsAttachedTo.xAxis.SetAxisScalingDuringInspectionComponentPhases(xAxisLowEnd_inMomentOfComponentCreation, xAxisUpperEnd_inMomentOfComponentCreation); + chart_thisInspectorIsAttachedTo.yAxis.SetAxisScalingDuringInspectionComponentPhases(yAxisLowEnd_inMomentOfComponentCreation, yAxisUpperEnd_inMomentOfComponentCreation); + +#if UNITY_EDITOR + UnityEditorInternal.InternalEditorUtility.RepaintAllViews(); +#endif + } + + public void ResetAxesScalingTo_encapsulateAllValues() + { + chart_thisInspectorIsAttachedTo.xAxis.GetAxisEndsIfAllNonHiddenValuesAreEncapsulated(out float lowerXAxisEnd_ifAllNonHiddenValuesAreEncapsulated, out float upperXAxisEnd_ifAllNonHiddenValuesAreEncapsulated); + chart_thisInspectorIsAttachedTo.xAxis.SetAxisScalingDuringInspectionComponentPhases(lowerXAxisEnd_ifAllNonHiddenValuesAreEncapsulated, upperXAxisEnd_ifAllNonHiddenValuesAreEncapsulated); + + chart_thisInspectorIsAttachedTo.yAxis.GetAxisEndsIfAllNonHiddenValuesAreEncapsulated(out float lowerYAxisEnd_ifAllNonHiddenValuesAreEncapsulated, out float upperYAxisEnd_ifAllNonHiddenValuesAreEncapsulated); + chart_thisInspectorIsAttachedTo.yAxis.SetAxisScalingDuringInspectionComponentPhases(lowerYAxisEnd_ifAllNonHiddenValuesAreEncapsulated, upperYAxisEnd_ifAllNonHiddenValuesAreEncapsulated); + + ForceCursorSliders_toFitGivenChartspaceXPos(curr_cursorPosition_inChartspaceUnits); + RecalcCursorPosition(); + +#if UNITY_EDITOR + UnityEditorInternal.InternalEditorUtility.RepaintAllViews(); +#endif + } + + //"Zoom" and "Scroll": + [SerializeField] [Range(-1.0f, 1.0f)] public float zoomForBothAxesToApply_fromInspectorSlider_m1_to_p1 = 0.0f; + [SerializeField] [Range(-1.0f, 1.0f)] public float xAxisZoomToApply_fromInspectorSlider_m1_to_p1 = 0.0f; + [SerializeField] [Range(-1.0f, 1.0f)] public float yAxisZoomToApply_fromInspectorSlider_m1_to_p1 = 0.0f; + [SerializeField] [Range(-1.0f, 1.0f)] public float xAxisScrollToApply_fromInspectorSlider_m1_to_p1 = 0.0f; + [SerializeField] [Range(-1.0f, 1.0f)] public float yAxisScrollToApply_fromInspectorSlider_m1_to_p1 = 0.0f; + public float xAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = 0.0f; + public float yAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = 0.0f; + public float bothAxesZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = 0.0f; + public float scrollSinceMouseDown_fromOnlyXDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection = 0.0f; + public float scrollSinceMouseDown_fromOnlyYDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection = 0.0f; + public float scrollSinceMouseDown_fromUnifiedHandleSlider_asTravelledWorldSpaceDistanceAlongChartsXDirection = 0.0f; + public float scrollSinceMouseDown_fromUnifiedHandleSlider_asTravelledWorldSpaceDistanceAlongChartsYDirection = 0.0f; + + static float zoomSpeed_forInspectorSlider = 0.04f; + static float scrollSpeed_forInspectorSlider = 0.08f; + static float max_displayedAxisSpan_factor = 10.0f; + static float min_displayedAxisSpan_inChartspaceUnits = 0.0002f; //a value of "0.0001f" has already once lead to "locked zoom" (probably due to float calculation rounding errors) + + static float zoomOutSpeedFactor_forHandleDrag = 2.0f; + static float zoomInSpeedFactor_forHandleDrag = 2.0f; //has to be bigger than 1 + bool zoomRespScroll_viaHandle_isInvalid; + + float xSpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits_duringMouseDown; + float xSpan_fromLowerAxisEnd_toCursor_inChartspaceUnits_duringMouseDown; + float xSpan_fromCursor_toUpperAxisEnd_inChartspaceUnits_duringMouseDown; + float xValueMarkingLowerEndOfTheAxis_duringMouseDown; + float xValueMarkingUpperEndOfTheAxis_duringMouseDown; + + float cursorVirtualYPosition_inChartspaceUnits_duringMouseDown; + float ySpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits_duringMouseDown; + float ySpan_fromLowerAxisEnd_toCursor_inChartspaceUnits_duringMouseDown; + float ySpan_fromCursor_toUpperAxisEnd_inChartspaceUnits_duringMouseDown; + float yValueMarkingLowerEndOfTheAxis_duringMouseDown; + float yValueMarkingUpperEndOfTheAxis_duringMouseDown; + + void ScaleAxes() + { + if (alwaysEncapsulateAllValues) + { + ResetAxesScalingTo_encapsulateAllValues(); + } + else + { + if (hideHandles_andInsteadUseInspectorSlidersForZoomAndScroll) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(zoomForBothAxesToApply_fromInspectorSlider_m1_to_p1) == false) + { + xAxisZoomToApply_fromInspectorSlider_m1_to_p1 = zoomForBothAxesToApply_fromInspectorSlider_m1_to_p1; + yAxisZoomToApply_fromInspectorSlider_m1_to_p1 = zoomForBothAxesToApply_fromInspectorSlider_m1_to_p1; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(xAxisZoomToApply_fromInspectorSlider_m1_to_p1) == false) { ApplyXAxisZoom_fromInspectorSlider(); } + if (UtilitiesDXXL_Math.ApproximatelyZero(xAxisScrollToApply_fromInspectorSlider_m1_to_p1) == false) { ApplyXAxisScroll_fromInspectorSlider(); } + if (UtilitiesDXXL_Math.ApproximatelyZero(yAxisZoomToApply_fromInspectorSlider_m1_to_p1) == false) { ApplyYAxisZoom_fromInspectorSlider(); } + if (UtilitiesDXXL_Math.ApproximatelyZero(yAxisScrollToApply_fromInspectorSlider_m1_to_p1) == false) { ApplyYAxisScroll_fromInspectorSlider(); } + } + else + { + if (UtilitiesDXXL_Math.ApproximatelyZero(bothAxesZoomSinceMouseDown_fromHandleSlider_m1_to_p1) == false) + { + xAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = bothAxesZoomSinceMouseDown_fromHandleSlider_m1_to_p1; + yAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1 = bothAxesZoomSinceMouseDown_fromHandleSlider_m1_to_p1; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(scrollSinceMouseDown_fromUnifiedHandleSlider_asTravelledWorldSpaceDistanceAlongChartsXDirection) == false) + { + scrollSinceMouseDown_fromOnlyXDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection = scrollSinceMouseDown_fromUnifiedHandleSlider_asTravelledWorldSpaceDistanceAlongChartsXDirection; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(scrollSinceMouseDown_fromUnifiedHandleSlider_asTravelledWorldSpaceDistanceAlongChartsYDirection) == false) + { + scrollSinceMouseDown_fromOnlyYDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection = scrollSinceMouseDown_fromUnifiedHandleSlider_asTravelledWorldSpaceDistanceAlongChartsYDirection; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(xAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1) == false) { ApplyXAxisZoom_fromHandle(); } + if (UtilitiesDXXL_Math.ApproximatelyZero(scrollSinceMouseDown_fromOnlyXDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection) == false) { ApplyXAxisScroll_fromHandle(); } + if (UtilitiesDXXL_Math.ApproximatelyZero(yAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1) == false) { ApplyYAxisZoom_fromHandle(); } + if (UtilitiesDXXL_Math.ApproximatelyZero(scrollSinceMouseDown_fromOnlyYDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection) == false) { ApplyYAxisScroll_fromHandle(); } + } + } + } + + public void SaveZoomAndScrollState_onMouseDown() + { + zoomRespScroll_viaHandle_isInvalid = false; + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis)) { ErrorLogForInvalidZoomRespScroll(); return; } + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis)) { ErrorLogForInvalidZoomRespScroll(); return; } + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis)) { ErrorLogForInvalidZoomRespScroll(); return; } + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis)) { ErrorLogForInvalidZoomRespScroll(); return; } + + xSpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits_duringMouseDown = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis - chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis; + xSpan_fromLowerAxisEnd_toCursor_inChartspaceUnits_duringMouseDown = curr_cursorPosition_inChartspaceUnits - chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis; + xSpan_fromCursor_toUpperAxisEnd_inChartspaceUnits_duringMouseDown = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis - curr_cursorPosition_inChartspaceUnits; + xValueMarkingLowerEndOfTheAxis_duringMouseDown = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis; + xValueMarkingUpperEndOfTheAxis_duringMouseDown = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis; + + cursorVirtualYPosition_inChartspaceUnits_duringMouseDown = Get_curr_cursorVirtualYPosition_inChartspaceUnits(); + ySpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits_duringMouseDown = chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis - chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis; + ySpan_fromLowerAxisEnd_toCursor_inChartspaceUnits_duringMouseDown = cursorVirtualYPosition_inChartspaceUnits_duringMouseDown - chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis; + ySpan_fromCursor_toUpperAxisEnd_inChartspaceUnits_duringMouseDown = chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis - cursorVirtualYPosition_inChartspaceUnits_duringMouseDown; + yValueMarkingLowerEndOfTheAxis_duringMouseDown = chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis; + yValueMarkingUpperEndOfTheAxis_duringMouseDown = chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis; + } + + void ErrorLogForInvalidZoomRespScroll() + { + zoomRespScroll_viaHandle_isInvalid = true; + Debug.LogError("Draw XXL: Chart handle zoom/scroll is invalid."); + } + + void ApplyXAxisZoom_fromHandle() + { + if (zoomRespScroll_viaHandle_isInvalid == false) + { + float zoomChangeFactor_unclamped; + if (xAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1 < 0.0f) + { + zoomChangeFactor_unclamped = 1.0f - zoomOutSpeedFactor_forHandleDrag * xAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1; //-> raises to higher thatn 1, since "xAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1" is negative here + } + else + { + zoomChangeFactor_unclamped = Mathf.Pow(zoomInSpeedFactor_forHandleDrag, (-xAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1)); + } + ApplyXAxisZoom(zoomChangeFactor_unclamped, xSpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits_duringMouseDown, xSpan_fromLowerAxisEnd_toCursor_inChartspaceUnits_duringMouseDown, xSpan_fromCursor_toUpperAxisEnd_inChartspaceUnits_duringMouseDown); + } + } + + void ApplyXAxisZoom_fromInspectorSlider() + { + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis)) { return; } + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis)) { return; } + + float old_xSpan_fromAxisLowerEnd_toUpperEnd = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis - chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis; + float old_xSpan_fromLowerAxisEnd_toCursor = curr_cursorPosition_inChartspaceUnits - chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis; + float old_xSpan_fromCursor_toUpperAxisEnd = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis - curr_cursorPosition_inChartspaceUnits; + + float zoomXAxis_sign = Mathf.Sign(xAxisZoomToApply_fromInspectorSlider_m1_to_p1); + float zoomXAxis_modulated = zoomXAxis_sign * (xAxisZoomToApply_fromInspectorSlider_m1_to_p1 * xAxisZoomToApply_fromInspectorSlider_m1_to_p1); + float zoomChangeFactor_unclamped = 1.0f - (zoomSpeed_forInspectorSlider * zoomXAxis_modulated); + + ApplyXAxisZoom(zoomChangeFactor_unclamped, old_xSpan_fromAxisLowerEnd_toUpperEnd, old_xSpan_fromLowerAxisEnd_toCursor, old_xSpan_fromCursor_toUpperAxisEnd); + } + + void ApplyXAxisZoom(float zoomChangeFactor_unclamped, float old_xSpan_fromAxisLowerEnd_toUpperEnd, float old_xSpan_fromLowerAxisEnd_toCursor, float old_xSpan_fromCursor_toUpperAxisEnd) + { + float new_xSpan_fromLowerToUpperAxisEnd_unclamped = old_xSpan_fromAxisLowerEnd_toUpperEnd * zoomChangeFactor_unclamped; + chart_thisInspectorIsAttachedTo.xAxis.GetAxisEndsIfAllNonHiddenValuesAreEncapsulated(out float lowerAxisEnd_ifAllNonHiddenValuesAreEncapsulated, out float upperAxisEnd_ifAllNonHiddenValuesAreEncapsulated); + float xSpan_fromAxisLowerEnd_toUpperEnd_ifAllNonHiddenValuesAreEncapsulated = upperAxisEnd_ifAllNonHiddenValuesAreEncapsulated - lowerAxisEnd_ifAllNonHiddenValuesAreEncapsulated; + float max_xSpan = max_displayedAxisSpan_factor * xSpan_fromAxisLowerEnd_toUpperEnd_ifAllNonHiddenValuesAreEncapsulated; + float new_xSpan_fromLowerToUpperAxisEnd_clamped = Mathf.Clamp(new_xSpan_fromLowerToUpperAxisEnd_unclamped, min_displayedAxisSpan_inChartspaceUnits, max_xSpan); + float zoomChangeFactor_clamped = zoomChangeFactor_unclamped * (new_xSpan_fromLowerToUpperAxisEnd_clamped / new_xSpan_fromLowerToUpperAxisEnd_unclamped); + + float new_xSpan_fromLowerAxisEnd_toCursor = old_xSpan_fromLowerAxisEnd_toCursor * zoomChangeFactor_clamped; + float new_xSpan_fromCursor_toUpperAxisEnd = old_xSpan_fromCursor_toUpperAxisEnd * zoomChangeFactor_clamped; + float new_valueOf_xAxisLowEnd = curr_cursorPosition_inChartspaceUnits - new_xSpan_fromLowerAxisEnd_toCursor; + float new_valueOf_xAxisUpperEnd = curr_cursorPosition_inChartspaceUnits + new_xSpan_fromCursor_toUpperAxisEnd; + + chart_thisInspectorIsAttachedTo.xAxis.SetAxisScalingDuringInspectionComponentPhases(new_valueOf_xAxisLowEnd, new_valueOf_xAxisUpperEnd); + } + + void ApplyYAxisZoom_fromHandle() + { + if (zoomRespScroll_viaHandle_isInvalid == false) + { + float zoomChangeFactor_unclamped; + if (yAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1 < 0.0f) + { + zoomChangeFactor_unclamped = 1.0f - zoomOutSpeedFactor_forHandleDrag * yAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1; //-> raises to higher thatn 1, since "yAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1" is negative here + } + else + { + zoomChangeFactor_unclamped = Mathf.Pow(zoomInSpeedFactor_forHandleDrag, (-yAxisZoomSinceMouseDown_fromHandleSlider_m1_to_p1)); + } + ApplyYAxisZoom(zoomChangeFactor_unclamped, cursorVirtualYPosition_inChartspaceUnits_duringMouseDown, ySpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits_duringMouseDown, ySpan_fromLowerAxisEnd_toCursor_inChartspaceUnits_duringMouseDown, ySpan_fromCursor_toUpperAxisEnd_inChartspaceUnits_duringMouseDown); + } + } + + void ApplyYAxisZoom_fromInspectorSlider() + { + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis)) { return; } + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis)) { return; } + + float curr_cursorVirtualYPosition_inChartspaceUnits = Get_curr_cursorVirtualYPosition_inChartspaceUnits(); + + float old_ySpan_fromAxisLowerEnd_toUpperEnd = chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis - chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis; + float old_ySpan_fromLowerAxisEnd_toCursor = curr_cursorVirtualYPosition_inChartspaceUnits - chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis; + float old_ySpan_fromCursor_toUpperAxisEnd = chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis - curr_cursorVirtualYPosition_inChartspaceUnits; + + float zoomYAxis_sign = Mathf.Sign(yAxisZoomToApply_fromInspectorSlider_m1_to_p1); + float zoomYAxis_modulated = zoomYAxis_sign * (yAxisZoomToApply_fromInspectorSlider_m1_to_p1 * yAxisZoomToApply_fromInspectorSlider_m1_to_p1); + float zoomChangeFactor_unclamped = 1.0f - (zoomSpeed_forInspectorSlider * zoomYAxis_modulated); + + ApplyYAxisZoom(zoomChangeFactor_unclamped, curr_cursorVirtualYPosition_inChartspaceUnits, old_ySpan_fromAxisLowerEnd_toUpperEnd, old_ySpan_fromLowerAxisEnd_toCursor, old_ySpan_fromCursor_toUpperAxisEnd); + } + + void ApplyYAxisZoom(float zoomChangeFactor_unclamped, float curr_cursorVirtualYPosition_inChartspaceUnits, float old_ySpan_fromAxisLowerEnd_toUpperEnd, float old_ySpan_fromLowerAxisEnd_toCursor, float old_ySpan_fromCursor_toUpperAxisEnd) + { + float new_ySpan_fromLowerToUpperAxisEnd_unclamped = old_ySpan_fromAxisLowerEnd_toUpperEnd * zoomChangeFactor_unclamped; + chart_thisInspectorIsAttachedTo.yAxis.GetAxisEndsIfAllNonHiddenValuesAreEncapsulated(out float lowerAxisEnd_ifAllNonHiddenValuesAreEncapsulated, out float upperAxisEnd_ifAllNonHiddenValuesAreEncapsulated); + float ySpan_fromAxisLowerEnd_toUpperEnd_ifAllNonHiddenValuesAreEncapsulated = upperAxisEnd_ifAllNonHiddenValuesAreEncapsulated - lowerAxisEnd_ifAllNonHiddenValuesAreEncapsulated; + float max_ySpan = max_displayedAxisSpan_factor * ySpan_fromAxisLowerEnd_toUpperEnd_ifAllNonHiddenValuesAreEncapsulated; + float new_ySpan_fromLowerToUpperAxisEnd_clamped = Mathf.Clamp(new_ySpan_fromLowerToUpperAxisEnd_unclamped, min_displayedAxisSpan_inChartspaceUnits, max_ySpan); + float zoomChangeFactor_clamped = zoomChangeFactor_unclamped * (new_ySpan_fromLowerToUpperAxisEnd_clamped / new_ySpan_fromLowerToUpperAxisEnd_unclamped); + + float new_ySpan_fromLowerAxisEnd_toCursor = old_ySpan_fromLowerAxisEnd_toCursor * zoomChangeFactor_clamped; + float new_ySpan_fromCursor_toUpperAxisEnd = old_ySpan_fromCursor_toUpperAxisEnd * zoomChangeFactor_clamped; + float new_valueOf_yAxisLowEnd = curr_cursorVirtualYPosition_inChartspaceUnits - new_ySpan_fromLowerAxisEnd_toCursor; + float new_valueOf_yAxisUpperEnd = curr_cursorVirtualYPosition_inChartspaceUnits + new_ySpan_fromCursor_toUpperAxisEnd; + + chart_thisInspectorIsAttachedTo.yAxis.SetAxisScalingDuringInspectionComponentPhases(new_valueOf_yAxisLowEnd, new_valueOf_yAxisUpperEnd); + } + + void ApplyXAxisScroll_fromHandle() + { + if (zoomRespScroll_viaHandle_isInvalid == false) + { + float xAxisScrollSinceMouseDown_fromHandleSlider_as0to1ofChart = scrollSinceMouseDown_fromOnlyXDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection / chart_thisInspectorIsAttachedTo.Width_inWorldSpace; + float xAxisScrollSinceMouseDown_fromHandleSlider_inChartspaceUnits = ConvertXSpan_from_0to1units_to_chartspaceUnits(xAxisScrollSinceMouseDown_fromHandleSlider_as0to1ofChart); + ApplyXAxisScroll(xAxisScrollSinceMouseDown_fromHandleSlider_inChartspaceUnits, xSpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits_duringMouseDown, xValueMarkingLowerEndOfTheAxis_duringMouseDown, xValueMarkingUpperEndOfTheAxis_duringMouseDown); + } + } + + void ApplyXAxisScroll_fromInspectorSlider() + { + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis)) { return; } + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis)) { return; } + + float scrollXAxis_sign = Mathf.Sign(xAxisScrollToApply_fromInspectorSlider_m1_to_p1); + float scrollXAxis_modulated = scrollXAxis_sign * (xAxisScrollToApply_fromInspectorSlider_m1_to_p1 * xAxisScrollToApply_fromInspectorSlider_m1_to_p1); + float xSpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits = chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis - chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis; + float chartWorldsizeAspect_inverse_heightToWidth = Get_chartWorldsizeAspect_inverse_heightToWidth(); //-> adapt scroll speed for charts with non-1 aspect and non-equal axis graduation, so that the scroll speed is homogenuous between the x and the y direction. + float scrollSpan_inChartspaceUnits = xSpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits * scrollXAxis_modulated * scrollSpeed_forInspectorSlider * chartWorldsizeAspect_inverse_heightToWidth; + + ApplyXAxisScroll(scrollSpan_inChartspaceUnits, xSpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits, chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingLowerEndOfTheAxis, chart_thisInspectorIsAttachedTo.xAxis.ValueMarkingUpperEndOfTheAxis); + } + + void ApplyXAxisScroll(float scrollSpan_inChartspaceUnits, float xSpan_fromAxisLowerEnd_toUpperEnd, float old_xValueMarkingLowerEndOfTheAxis, float old_xValueMarkingUpperEndOfTheAxis) + { + float newValueOf_xAxisLowEnd = old_xValueMarkingLowerEndOfTheAxis - scrollSpan_inChartspaceUnits; + float newValueOf_xAxisUpperEnd = old_xValueMarkingUpperEndOfTheAxis - scrollSpan_inChartspaceUnits; + ClampXScroll_soThatItDoesntMoveAwayFromTheDataValueArea(ref newValueOf_xAxisLowEnd, ref newValueOf_xAxisUpperEnd, xSpan_fromAxisLowerEnd_toUpperEnd); + + chart_thisInspectorIsAttachedTo.xAxis.SetAxisScalingDuringInspectionComponentPhases(newValueOf_xAxisLowEnd, newValueOf_xAxisUpperEnd); + ForceCursorSliders_toFitGivenChartspaceXPos(curr_cursorPosition_inChartspaceUnits); + RecalcCursorPosition(); + } + + void ClampXScroll_soThatItDoesntMoveAwayFromTheDataValueArea(ref float newValueOf_xAxisLowEnd, ref float newValueOf_xAxisUpperEnd, float xSpan_fromAxisLowerEnd_toUpperEnd) + { + if (newValueOf_xAxisLowEnd > chart_thisInspectorIsAttachedTo.overallMaxXValue_includingHiddenLines) + { + newValueOf_xAxisLowEnd = chart_thisInspectorIsAttachedTo.overallMaxXValue_includingHiddenLines; + newValueOf_xAxisUpperEnd = newValueOf_xAxisLowEnd + xSpan_fromAxisLowerEnd_toUpperEnd; + } + else + { + if (newValueOf_xAxisUpperEnd < chart_thisInspectorIsAttachedTo.overallMinXValue_includingHiddenLines) + { + newValueOf_xAxisUpperEnd = chart_thisInspectorIsAttachedTo.overallMinXValue_includingHiddenLines; + newValueOf_xAxisLowEnd = newValueOf_xAxisUpperEnd - xSpan_fromAxisLowerEnd_toUpperEnd; + } + } + } + + void ApplyYAxisScroll_fromHandle() + { + if (zoomRespScroll_viaHandle_isInvalid == false) + { + float yAxisScrollSinceMouseDown_fromHandleSlider_as0to1ofChart = scrollSinceMouseDown_fromOnlyYDimHandleSlider_asTravelledWorldSpaceDistanceAlongSliderDirection / chart_thisInspectorIsAttachedTo.Height_inWorldSpace; + float yAxisScrollSinceMouseDown_fromHandleSlider_inChartspaceUnits = ConvertYSpan_from_0to1units_to_chartspaceUnits(yAxisScrollSinceMouseDown_fromHandleSlider_as0to1ofChart); + ApplyYAxisScroll(yAxisScrollSinceMouseDown_fromHandleSlider_inChartspaceUnits, ySpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits_duringMouseDown, yValueMarkingLowerEndOfTheAxis_duringMouseDown, yValueMarkingUpperEndOfTheAxis_duringMouseDown); + } + } + + void ApplyYAxisScroll_fromInspectorSlider() + { + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis)) { return; } + if (UtilitiesDXXL_Math.FloatIsInvalid(chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis)) { return; } + + float scrollYAxis_sign = Mathf.Sign(yAxisScrollToApply_fromInspectorSlider_m1_to_p1); + float scrollYAxis_modulated = scrollYAxis_sign * (yAxisScrollToApply_fromInspectorSlider_m1_to_p1 * yAxisScrollToApply_fromInspectorSlider_m1_to_p1); + float ySpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits = chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis - chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis; + float scrollSpan_inChartspaceUnits = ySpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits * scrollYAxis_modulated * scrollSpeed_forInspectorSlider; + + ApplyYAxisScroll(scrollSpan_inChartspaceUnits, ySpan_fromAxisLowerEnd_toUpperEnd_inChartspaceUnits, chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis, chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis); + } + + void ApplyYAxisScroll(float scrollSpan_inChartspaceUnits, float ySpan_fromAxisLowerEnd_toUpperEnd, float old_yValueMarkingLowerEndOfTheAxis, float old_yValueMarkingUpperEndOfTheAxis) + { + float newValueOf_yAxisLowEnd = old_yValueMarkingLowerEndOfTheAxis - scrollSpan_inChartspaceUnits; + float newValueOf_yAxisUpperEnd = old_yValueMarkingUpperEndOfTheAxis - scrollSpan_inChartspaceUnits; + ClampYScroll_soThatItDoesntMoveAwayFromTheDataValueArea(ref newValueOf_yAxisLowEnd, ref newValueOf_yAxisUpperEnd, ySpan_fromAxisLowerEnd_toUpperEnd); + chart_thisInspectorIsAttachedTo.yAxis.SetAxisScalingDuringInspectionComponentPhases(newValueOf_yAxisLowEnd, newValueOf_yAxisUpperEnd); + } + + void ClampYScroll_soThatItDoesntMoveAwayFromTheDataValueArea(ref float newValueOf_yAxisLowEnd, ref float newValueOf_yAxisUpperEnd, float ySpan_fromAxisLowerEnd_toUpperEnd) + { + if (newValueOf_yAxisLowEnd > chart_thisInspectorIsAttachedTo.overallMaxYValue_includingHiddenLines) + { + newValueOf_yAxisLowEnd = chart_thisInspectorIsAttachedTo.overallMaxYValue_includingHiddenLines; + newValueOf_yAxisUpperEnd = newValueOf_yAxisLowEnd + ySpan_fromAxisLowerEnd_toUpperEnd; + } + else + { + if (newValueOf_yAxisUpperEnd < chart_thisInspectorIsAttachedTo.overallMinYValue_includingHiddenLines) + { + newValueOf_yAxisUpperEnd = chart_thisInspectorIsAttachedTo.overallMinYValue_includingHiddenLines; + newValueOf_yAxisLowEnd = newValueOf_yAxisUpperEnd - ySpan_fromAxisLowerEnd_toUpperEnd; + } + } + } + + float Get_curr_cursorVirtualYPosition_inChartspaceUnits() + { + int numberOf_allDisplayedLinesThatHaveTheirYPosInsideDrawnChartArea = 0; + float sumOfAll_cursorYPositionsInChartspace_forAllDisplayedLinesThatHaveTheirYPosInsideDrawnChartArea = 0.0f; + for (int i_line = 0; i_line < specsForInspector_forEachDrawnLine.Length; i_line++) + { + if (specsForInspector_forEachDrawnLine[i_line].currentHideLineState == false) + { + if ((specsForInspector_forEachDrawnLine[i_line].currentHideCursorXState_duringComponentInspectionPhase == false) || (specsForInspector_forEachDrawnLine[i_line].currentHideCursorYState_duringComponentInspectionPhase == false)) + { + if (specsForInspector_forEachDrawnLine[i_line].hasValidDatapointThatIsXNearestToCursor) + { + if (chart_thisInspectorIsAttachedTo.IsInsideDrawnChartArea(specsForInspector_forEachDrawnLine[i_line].posInChartspace_ofDatapointThatIsNearestToCursor)) + { + numberOf_allDisplayedLinesThatHaveTheirYPosInsideDrawnChartArea++; + sumOfAll_cursorYPositionsInChartspace_forAllDisplayedLinesThatHaveTheirYPosInsideDrawnChartArea = sumOfAll_cursorYPositionsInChartspace_forAllDisplayedLinesThatHaveTheirYPosInsideDrawnChartArea + specsForInspector_forEachDrawnLine[i_line].posInChartspace_ofDatapointThatIsNearestToCursor.y; + } + } + } + } + } + + if (numberOf_allDisplayedLinesThatHaveTheirYPosInsideDrawnChartArea == 0) + { + float middleOfYAxis = 0.5f * (chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingLowerEndOfTheAxis + chart_thisInspectorIsAttachedTo.yAxis.ValueMarkingUpperEndOfTheAxis); + return middleOfYAxis; + } + else + { + return (sumOfAll_cursorYPositionsInChartspace_forAllDisplayedLinesThatHaveTheirYPosInsideDrawnChartArea / (float)numberOf_allDisplayedLinesThatHaveTheirYPosInsideDrawnChartArea); + } + } + + float Get_chartWorldsizeAspect_inverse_heightToWidth() + { + if (theChartIsDrawnInScreenspace) + { + float charts_worldspaceHeight = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(screenSpaceTargetCamera, InternalDXXL_BoundsCamViewportSpace.viewportCenter, true, chart_thisInspectorIsAttachedTo.Height_relToCamViewportHeight); + float charts_worldspaceWidth; + if (chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight) + { + charts_worldspaceWidth = UtilitiesDXXL_Screenspace.HorizExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(screenSpaceTargetCamera, InternalDXXL_BoundsCamViewportSpace.viewportCenter, true, chart_thisInspectorIsAttachedTo.Width_relToCamViewport); + } + else + { + charts_worldspaceWidth = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(screenSpaceTargetCamera, InternalDXXL_BoundsCamViewportSpace.viewportCenter, true, chart_thisInspectorIsAttachedTo.Width_relToCamViewport); + } + return (charts_worldspaceHeight / charts_worldspaceWidth); + } + else + { + return (chart_thisInspectorIsAttachedTo.Height_inWorldSpace / chart_thisInspectorIsAttachedTo.Width_inWorldSpace); + } + } + + public float GetBacksnapSliderReferenceLength_inWorldspaceUnits() + { + return 0.2f * (chart_thisInspectorIsAttachedTo.Width_inWorldSpace + chart_thisInspectorIsAttachedTo.Height_inWorldSpace); + } + + void DrawTheChart() + { + if (theChartIsDrawnInScreenspace) + { + chart_thisInspectorIsAttachedTo.Internal_DrawScreenspace(screenSpaceTargetCamera, chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, 0.0f); + } + else + { + chart_thisInspectorIsAttachedTo.Internal_Draw(0.0f, nonScreenspaceDrawing_happensWith_drawConfigOf_hiddenByNearerObjects); + } + } + + Vector3 chartPosition_beforeScreenspaceDrawing; + Quaternion chartFixedRotation_beforeScreenspaceDrawing; + float chartWidthWorldspace_beforeScreenspaceDrawing; + float chartHeigthWorldspace_beforeScreenspaceDrawing; + ChartDrawing.RotationSource chartRotationSource_beforeScreenspaceDrawing; + + public void TryNote_chartWorldSpacePosRotScale_beforeChangingItToScreenspace() + { + if (theChartIsDrawnInScreenspace) + { + chartPosition_beforeScreenspaceDrawing = chart_thisInspectorIsAttachedTo.Position_worldspace; + chartFixedRotation_beforeScreenspaceDrawing = chart_thisInspectorIsAttachedTo.fixedRotation; + chartWidthWorldspace_beforeScreenspaceDrawing = chart_thisInspectorIsAttachedTo.Width_inWorldSpace; + chartHeigthWorldspace_beforeScreenspaceDrawing = chart_thisInspectorIsAttachedTo.Height_inWorldSpace; + chartRotationSource_beforeScreenspaceDrawing = chart_thisInspectorIsAttachedTo.rotationSource; + chart_thisInspectorIsAttachedTo.autoFlipAllText_toFitObsererCamera = false; + } + } + + public void TrySetBack_chartWorldSpacePosRotScale_afterUsingItInScreenspace() + { + if (theChartIsDrawnInScreenspace) + { + chart_thisInspectorIsAttachedTo.Position_worldspace = chartPosition_beforeScreenspaceDrawing; + chart_thisInspectorIsAttachedTo.fixedRotation = chartFixedRotation_beforeScreenspaceDrawing; + chart_thisInspectorIsAttachedTo.Width_inWorldSpace = chartWidthWorldspace_beforeScreenspaceDrawing; + chart_thisInspectorIsAttachedTo.Height_inWorldSpace = chartHeigthWorldspace_beforeScreenspaceDrawing; + chart_thisInspectorIsAttachedTo.rotationSource = chartRotationSource_beforeScreenspaceDrawing; + chart_thisInspectorIsAttachedTo.autoFlipAllText_toFitObsererCamera = true; + } + } + + void DrawCursor() + { + DrawVerticalCursorLine(); + DrawCursorNearestPointsOfLines(); + } + + void DrawVerticalCursorLine() + { + if (chart_thisInspectorIsAttachedTo.IsEmptyWithNoLinesToDraw == false) + { + bool cursorDrawing_is_hiddenByNearerObjects = CheckIfDrawingHappesWithConfigOf_hiddenByNearerObjects(); + + Vector3 lowerEndVertexOfSlidersVertLine = GetCursorPosOnLowerEndOfChart(); + Vector3 higherEndVertexOfSlidersVertLine = GetCursorPosOnHigherEndOfChart(); + Color color = chart_thisInspectorIsAttachedTo.color; + Line_fadeableAnimSpeed.InternalDraw(lowerEndVertexOfSlidersVertLine, higherEndVertexOfSlidersVertLine, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, 0.0f, cursorDrawing_is_hiddenByNearerObjects, false, false); + + Vector3 center_ofBasePlane = lowerEndVertexOfSlidersVertLine; + float height = GetHeightOfCursorPyramid(); + float width_ofBase = 0.0f; + float length_ofBase = 2.0f * height; + Vector3 normal_ofBaseTowardsApex = chart_thisInspectorIsAttachedTo.yAxis.AxisVector_normalized_inWorldSpace; + Vector3 up_insideBasePlane = chart_thisInspectorIsAttachedTo.xAxis.AxisVector_normalized_inWorldSpace; + DrawShapes.Pyramid(center_ofBasePlane, height, width_ofBase, length_ofBase, color, normal_ofBaseTowardsApex, up_insideBasePlane, DrawShapes.Shape2DType.circle, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, 0.0f, cursorDrawing_is_hiddenByNearerObjects); + + center_ofBasePlane = higherEndVertexOfSlidersVertLine; + normal_ofBaseTowardsApex = -chart_thisInspectorIsAttachedTo.yAxis.AxisVector_normalized_inWorldSpace; + DrawShapes.Pyramid(center_ofBasePlane, height, width_ofBase, length_ofBase, color, normal_ofBaseTowardsApex, up_insideBasePlane, DrawShapes.Shape2DType.circle, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, 0.0f, cursorDrawing_is_hiddenByNearerObjects); + } + } + + public Vector3 GetCursorPosOnLowerEndOfChart() + { + return (chart_thisInspectorIsAttachedTo.Position_worldspace + chart_thisInspectorIsAttachedTo.xAxis.AxisVector_inWorldSpace * curr_cursorPosition_as0to1OfChartWidth); + } + + public Vector3 GetCursorPosOnHigherEndOfChart() + { + return (GetCursorPosOnLowerEndOfChart() + chart_thisInspectorIsAttachedTo.yAxis.AxisVector_inWorldSpace); + } + + public float GetHeightOfCursorPyramid() + { + return (chart_thisInspectorIsAttachedTo.Height_inWorldSpace * 0.03f); + } + + void DrawCursorNearestPointsOfLines() + { + bool cursorDrawing_is_hiddenByNearerObjects = CheckIfDrawingHappesWithConfigOf_hiddenByNearerObjects(); + for (int i_line = 0; i_line < specsForInspector_forEachDrawnLine.Length; i_line++) + { + specsForInspector_forEachDrawnLine[i_line].DrawCursorNearestPoint(sizeOfDatapointVisualization, cursorDrawing_is_hiddenByNearerObjects); + } + } + + void TryDrawUnified45degAxisForHandles() + { +#if UNITY_EDITOR + if (hideHandles_andInsteadUseInspectorSlidersForZoomAndScroll == false) + { + if (UnityEditor.Selection.Contains(gameObject.GetInstanceID())) + { + Vector3 startOfLine = chart_thisInspectorIsAttachedTo.Position_worldspace; + Vector3 endOfLine = startOfLine + chart_thisInspectorIsAttachedTo.Get_unified45degAxis_forHandleSliders_normalized() * chart_thisInspectorIsAttachedTo.Get_unified45degAxis_length(); + bool hiddenByNearerObjects = CheckIfDrawingHappesWithConfigOf_hiddenByNearerObjects(); + DrawBasics.Line(startOfLine, endOfLine, chart_thisInspectorIsAttachedTo.color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, default(Vector3), false, 0.0f, 0.0f, 0.0f, 0.0f, hiddenByNearerObjects); + } + } +#endif + } + + bool CheckIfDrawingHappesWithConfigOf_hiddenByNearerObjects() + { + if (theChartIsDrawnInScreenspace) + { + return false; + } + else + { + return nonScreenspaceDrawing_happensWith_drawConfigOf_hiddenByNearerObjects; + } + } + + void RefillArraysWithCursorNeighboringDatapointsForEachLine() + { + if (CheckIf_reconstructWithNewLength_theArrayWithLineSpecsForEachLine()) + { + ReconstructWithNewLength_theArrayWithLineSpecsForEachLine(); + } + + for (int i = 0; i < specsForInspector_forEachDrawnLine.Length; i++) + { + specsForInspector_forEachDrawnLine[i].TryRefill_arrayWithNeighboringDatapointValues(); + } + } + + bool CheckIf_reconstructWithNewLength_theArrayWithLineSpecsForEachLine() + { + int current_numberOfAllHiddenAndUnhiddenLines_withAtLeastOneValidOrInvalidDataPoint = chart_thisInspectorIsAttachedTo.lines.Get_numberOf_allHiddenAndUnhiddenLines_withAtLeastOneValidOrInvalidDatapoint(false); + if (current_numberOfAllHiddenAndUnhiddenLines_withAtLeastOneValidOrInvalidDataPoint != specsForInspector_forEachDrawnLine.Length) + { + return true; + } + else + { + for (int i_line = 0; i_line < specsForInspector_forEachDrawnLine.Length; i_line++) + { + if (specsForInspector_forEachDrawnLine[i_line].line_theseSpecsBelongTo.IsHiddenOrUnhidden_butWithAtLeastOneValidOrInvalidDatapoint() == false) + { + return true; + } + } + } + return false; + } + + void ReconstructWithNewLength_theArrayWithLineSpecsForEachLine() + { + List currentlyActiveLines = chart_thisInspectorIsAttachedTo.lines.Get_all_hiddenAndUnhiddenLines_withAtLeastOneValidOrInvalidDatapoint(false); + specsForInspector_forEachDrawnLine = new InternalDXXL_LineSpecsForChartInspector[currentlyActiveLines.Count]; + bool firstNonHiddenLineHasAlreadyBeenFound = false; + for (int i = 0; i < specsForInspector_forEachDrawnLine.Length; i++) + { + specsForInspector_forEachDrawnLine[i] = currentlyActiveLines[i].lineSpecsForInspector; + specsForInspector_forEachDrawnLine[i].i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray = i; + specsForInspector_forEachDrawnLine[i].Recalc_posThatIsXNearestToCursor(curr_cursorPosition_inChartspaceUnits); + + if (firstNonHiddenLineHasAlreadyBeenFound == false) + { + if (specsForInspector_forEachDrawnLine[i].currentHideLineState == false) + { + specsForInspector_forEachDrawnLine[i].currentHideCursorXState_duringComponentInspectionPhase = false; + firstNonHiddenLineHasAlreadyBeenFound = true; + } + } + } + } + + void SetTransformToChartPos() + { + transform.position = chart_thisInspectorIsAttachedTo.Position_worldspace; + transform.rotation = chart_thisInspectorIsAttachedTo.InternalRotation; + transform.localScale = new Vector3(chart_thisInspectorIsAttachedTo.Width_inWorldSpace, chart_thisInspectorIsAttachedTo.Height_inWorldSpace, 1.0f); + } + + void TryPlaceSceneviewCam() + { +#if UNITY_EDITOR + UnityEditor.SceneView activeSceneView = null; + if (UnityEditor.SceneView.currentDrawingSceneView != null) + { + activeSceneView = UnityEditor.SceneView.currentDrawingSceneView; + } + else + { + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + activeSceneView = UnityEditor.SceneView.lastActiveSceneView; + } + } + + if (activeSceneView != null) + { + TrySetSceneViewCamToChart_dueToCheckedForceStayToggle(activeSceneView); + } +#endif + } + +#if UNITY_EDITOR + public void TrySetSceneViewCamToChart_dueToButtonClick() + { + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + TryNote_chartWorldSpacePosRotScale_beforeChangingItToScreenspace(); + try + { + if (theChartIsDrawnInScreenspace) { UtilitiesDXXL_ChartDrawing.SetPosRotScaleOfChart_toScreenspace(chart_thisInspectorIsAttachedTo, screenSpaceTargetCamera, chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, true); } + SetSceneViewCameraPos(UnityEditor.SceneView.lastActiveSceneView, false); + } + catch { } + TrySetBack_chartWorldSpacePosRotScale_afterUsingItInScreenspace(); + + UnityEditorInternal.InternalEditorUtility.RepaintAllViews(); + } + } + + void TrySetSceneViewCamToChart_dueToCheckedForceStayToggle(UnityEditor.SceneView activeSceneView) + { + if (forceSceneViewCamToFollowChart == true) + { + SetSceneViewCameraPos(activeSceneView, true); + } + } + + void SetSceneViewCameraPos(UnityEditor.SceneView concernedSceneView, bool useSliderValue_forDistanceToChart) + { + //could be refactored using "SceneView.Frame()" or "SceneView.FrameSelected()" + concernedSceneView.pivot = chart_thisInspectorIsAttachedTo.GetCenterPos(); + concernedSceneView.rotation = chart_thisInspectorIsAttachedTo.InternalRotation; + if (useSliderValue_forDistanceToChart) + { + concernedSceneView.size = chart_thisInspectorIsAttachedTo.GetDiagonalSize() * (0.04f + (1.0f - sizeArbUnits_ofSceneViewCam)); + } + else + { + concernedSceneView.size = chart_thisInspectorIsAttachedTo.GetDiagonalSize() * (0.04f + (1.0f - default_sizeArbUnits_ofSceneViewCam)); + } + } + +#endif + + public bool ContainsOnly1Line_hiddenOrUnhidden() + { + return (specsForInspector_forEachDrawnLine.Length == 1); + } + + public bool AllOtherLinesAreHidden(int i_requestingLine) + { + for (int i = 0; i < specsForInspector_forEachDrawnLine.Length; i++) + { + if (i != i_requestingLine) + { + if (specsForInspector_forEachDrawnLine[i].currentHideLineState == false) { return false; } + } + } + return true; + } + + public bool AllOtherCursorsAreHidden(int i_requestingLine) + { + for (int i = 0; i < specsForInspector_forEachDrawnLine.Length; i++) + { + if (i != i_requestingLine) + { + if (specsForInspector_forEachDrawnLine[i].currentHideCursorXState_duringComponentInspectionPhase == false) { return false; } + if (specsForInspector_forEachDrawnLine[i].currentHideCursorYState_duringComponentInspectionPhase == false) { return false; } + } + } + return true; + } + + public void HideAllOtherLines(int i_ofOnlyNonHiddenLine) + { + for (int i = 0; i < specsForInspector_forEachDrawnLine.Length; i++) + { + if (i == i_ofOnlyNonHiddenLine) + { + specsForInspector_forEachDrawnLine[i].currentHideLineState = false; + specsForInspector_forEachDrawnLine[i].currentHideCursorXState_duringComponentInspectionPhase = false; + specsForInspector_forEachDrawnLine[i].currentHideCursorYState_duringComponentInspectionPhase = false; + } + else + { + specsForInspector_forEachDrawnLine[i].currentHideLineState = true; + } + } + } + + public void HideAllOtherCursors(int i_ofOnlyNonCursorHiddenLine) + { + for (int i = 0; i < specsForInspector_forEachDrawnLine.Length; i++) + { + if (i == i_ofOnlyNonCursorHiddenLine) + { + specsForInspector_forEachDrawnLine[i].currentHideCursorXState_duringComponentInspectionPhase = false; + specsForInspector_forEachDrawnLine[i].currentHideCursorYState_duringComponentInspectionPhase = false; + } + else + { + specsForInspector_forEachDrawnLine[i].currentHideCursorXState_duringComponentInspectionPhase = true; + specsForInspector_forEachDrawnLine[i].currentHideCursorYState_duringComponentInspectionPhase = true; + } + } + } + public void UnhideAllLines() + { + for (int i = 0; i < specsForInspector_forEachDrawnLine.Length; i++) + { + specsForInspector_forEachDrawnLine[i].currentHideLineState = false; + } + } + + public void UnhideAllCursors(int i_singleLineThatHasXCursorEnabled) + { + for (int i = 0; i < specsForInspector_forEachDrawnLine.Length; i++) + { + if (i == i_singleLineThatHasXCursorEnabled) + { + specsForInspector_forEachDrawnLine[i].currentHideCursorXState_duringComponentInspectionPhase = false; + specsForInspector_forEachDrawnLine[i].currentHideCursorYState_duringComponentInspectionPhase = false; + } + else + { + specsForInspector_forEachDrawnLine[i].currentHideCursorXState_duringComponentInspectionPhase = true; + specsForInspector_forEachDrawnLine[i].currentHideCursorYState_duringComponentInspectionPhase = false; + } + } + } + + void TrySetLuminanceOfLineColors() + { + //Known issue: + //-> Calling "Undo" after changing the slider value will undo the luminance change, but the slider will not be set back to it's previous position. + //-> It may have something to do with Unitys "Undo Groups"...what is inside such a group? How can it be inspected? + //-> It seems in this case that the Undo-Actions sets back + //---> "prev_luminanceOfLineColors_accordingToChartSetting" + //---> "prev_luminanceOfLineColors_accordingToSlider" + //---> "curr_luminanceOfLineColors_accordingToSlider" + //---> The color values of the lines + //-> But it does not set back the property value of "chart_thisInspectorIsAttachedTo.LuminanceOfLineColors". So this unchanged "chart_thisInspectorIsAttachedTo.LuminanceOfLineColors" will revert the slider to the position before the undo, but will not revert the colorChangeMadeByUndo. + //-> If it is done multiple times this can lead to line colors that get shifted out of the Luminance0to1-Range and stay white/black onFutureLuminanceChanges. + + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(prev_luminanceOfLineColors_accordingToChartSetting, chart_thisInspectorIsAttachedTo.LuminanceOfLineColors)) + { + //luminance has not been set via API call: + if (false == UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(prev_luminanceOfLineColors_accordingToSlider, curr_luminanceOfLineColors_accordingToSlider)) + { + //luminance has been set via slider: + chart_thisInspectorIsAttachedTo.LuminanceOfLineColors = curr_luminanceOfLineColors_accordingToSlider; + prev_luminanceOfLineColors_accordingToSlider = curr_luminanceOfLineColors_accordingToSlider; + } + } + else + { + //luminance has been set via API call: + curr_luminanceOfLineColors_accordingToSlider = chart_thisInspectorIsAttachedTo.LuminanceOfLineColors; //-> "Clamp01" has already been made inside "chart_thisInspectorIsAttachedTo.LuminanceOfLineColors" + prev_luminanceOfLineColors_accordingToSlider = curr_luminanceOfLineColors_accordingToSlider; + } + prev_luminanceOfLineColors_accordingToChartSetting = chart_thisInspectorIsAttachedTo.LuminanceOfLineColors; + } + + void SetLineNamePositionsAndSize() + { + //-> not yet caring to set back the previous values of the lines after deletion of component, if the values have been different from line to line. + chart_thisInspectorIsAttachedTo.SetLineNamesPositions(lineNamePositions); + chart_thisInspectorIsAttachedTo.SetLineNamesSize(lineNames_sizeScaleFactor); + } + + public bool DatapointVisualizerOfLineAreInvisible(int i_concernedLine) + { + return (specsForInspector_forEachDrawnLine[i_concernedLine].dataPointVisualization == ChartLine.DataPointVisualization.invisible); + } + + public void ExportCSVFile(string fileName) + { + chart_thisInspectorIsAttachedTo.ExportToCSVfile(fileName); + } + + public int Get_maxDisplayedPointOfInterestTextBoxesPerSide() + { + return chart_thisInspectorIsAttachedTo.MaxDisplayedPointOfInterestTextBoxesPerSide; + } + + public void Set_maxDisplayedPointOfInterestTextBoxesPerSide(int newValue) + { + chart_thisInspectorIsAttachedTo.MaxDisplayedPointOfInterestTextBoxesPerSide = newValue; + } + + public void ClearLineData() + { + chart_thisInspectorIsAttachedTo.Clear(); + } + + bool TrySkipDrawingBecauseItIsTheFirstFrameAfterAPausePhase() + { + //returns "doSkipDrawing" + + //-> this prevents drawing in the first frame after pause phases, to prevent the additional frozen overdraw during pause phases, caused by using "Debug.DrawLine()", which doesn't get cleared during pause phases. + //-> see also "TrySheduleAutomaticFrameStepAtTheStartOfPausePhases()" + //-> for more details: See documentation of "DrawCharts.chartInspectorComponentsAutomaticallyProceedOneFrameStepOnPauseStarts_toPreventFrozenOverlayDraw" + //-> it also preservers the ability of the user to use the "Step"-functionality via the right one of the three play/pause buttons on top of the Unity window. + + //-> addendum: It seems that this function isn't necessary at all, because if you click on "Step" during a pausePhase, then one "Update/LateUpdate"-cycle is executed (as if there would be a short phase of "pause == false"), but "UnityEditor.EditorApplication.isPaused" doesn't become "false" in this step-frame. So the "LateUpdate()" of this class will anyway not call this "TrySkipDrawingBecauseItIsTheFirstFrameAfterAPausePhase()" function. But it doesn't harm, and it is maybe a good preparation if Unity version appear that DO set "UnityEditor.EditorApplication.isPaused" to "false" during this Step-Update-Cyle. + + if (isFirstUpdateCycleAfterGamePause) + { + isFirstUpdateCycleAfterGamePause = false; + return true; + } + else + { + isFirstUpdateCycleAfterGamePause = false; + return false; + } + } + + void TrySheduleAutomaticFrameStepAtTheStartOfPausePhases() + { +#if UNITY_EDITOR + if (UnityEditor.EditorApplication.isPlaying && UnityEditor.EditorApplication.isPaused) + { + isFirstUpdateCycleAfterGamePause = true; //-> prepare for upcoming Update-cycles + + //-> the additional frame gives the component the chance to skip drawing with "Debug.DrawLine()" in the frame before pause phases, so there are no frozen uncleared debugLines present during the pause phase + //-> see also "TrySkipDrawingBecauseItIsTheFirstFrameAfterAPausePhase()" + //-> for more details: See documentation of "DrawCharts.chartInspectorComponentsAutomaticallyProceedOneFrameStepOnPauseStarts_toPreventFrozenOverlayDraw" + if (mostCurrentFrameCountDuringGamePause <= (Time.frameCount - 2)) + { + //-> is first arrival after pausing the game + //-> at least two Update cycles happened since the previous game pause (or alternatively the playmode has been startet with "pause" already activated) + //-> cannot arrive here after proceeding only a single frame step between two pause phases + //-> related topic: "DXXLWrapperForUntiysBuildInDrawLines.ChooseDebugOrGizmoLines_dependingOnPlayModeState()" + //("Time.frameCount" doesn't increase during pause phases) + UtilitiesDXXL_Components.frameCount_forWhichAnEditorFrameStep_hasBeenSheduled_byAChart = Time.frameCount; //-> sheduling, because calling "UnityEditor.EditorApplication.Step()" from here causes Unity to print "recursive GUI rendering" errors + } + mostCurrentFrameCountDuringGamePause = Time.frameCount; + } +#endif + } + + bool TryDestroyThisComponentIfItWasManuallyCreated() + { + //returns "hasBeenDestroyed", which is the same as "shouldStopExecutingTheCallingFunction" +#if UNITY_EDITOR + if (hasBeenManuallyCreated == true) + { + Debug.LogError("Do not create 'Draw XXL Chart Inspector' manually. Instead call 'CreateChartInspectionGameobject()' from script on the chart you want to inspect."); + if (editorUpdateCallback_hasBeenRegistered) + { + UnityEditor.EditorApplication.update -= EditorUpdateCallback; + editorUpdateCallback_hasBeenRegistered = false; + } + + DeleteThisInspectorComponent(); + return true; + } + else + { + return false; + } +#else + return true; +#endif + } + + bool TryDestroyComonent_ifChartGotLost() + { + //returns "shouldStopExecutingTheCallingFunction" + //losing the chart reference happens in some cases, e.g. when a chart inspector has been created outside playmode and then playmode is entered, which destroys the referenced "chart_thisInspectorIsAttachedTo" + + if (chart_thisInspectorIsAttachedTo == null) + { +#if UNITY_EDITOR + if (transform.childCount == 0) + { + if (transform.parent == null) + { + Component[] otherComponentsOnThisGameobject = GetComponents(); //this is expensive, but it is only in the rare case where a user has taken the auto-generated ChartInspectorGameobject and attached own additional components or did parenting of some sort. And it indicates a state that anyway should be resolved and should not be permanently there. + if (otherComponentsOnThisGameobject != null) + { + if (otherComponentsOnThisGameobject.Length <= 2) //only 2 components: "Transform" and "Draw XXL Chart Inspector" + { + //This is the expected case: The gameobject that hosts the chartInspectionComponent has not been modified by the user, that means no other components have been added and no parenting has been applied. + //-> the whole gameobject can be safely destroyed, and doesn't remain in the chart as a forgotten object that does nothing + DeleteNotOnlyThisInspectorComponentButAlsoTheHostingGameobject(); + } + } + else + { + UtilitiesDXXL_Log.PrintErrorCode("82"); + } + } + } +#else + DeleteThisInspectorComponent(); +#endif + return true; + } + else + { + return false; + } + } + + void DeleteThisInspectorComponent() + { + if (Application.isPlaying) + { + Destroy(this); + } + else + { + DestroyImmediate(this); + } + } + + void DeleteNotOnlyThisInspectorComponentButAlsoTheHostingGameobject() + { + //Debug.Log("Draw XXL Chart Inspector gameobject has been automatically deleted because the referenced ChartDrawing got lost."); //is this auto-delete case too frequent to spam the users log with this message? + if (Application.isPlaying) + { + Destroy(this.gameObject); + } + else + { + DestroyImmediate(this.gameObject); + } + } + + public bool CheckIfReferencedChartGotLost() + { + return (chart_thisInspectorIsAttachedTo == null); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/DrawXXLChartInspector.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/DrawXXLChartInspector.cs.meta new file mode 100644 index 0000000..e18a305 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/DrawXXLChartInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b23e7ea809c2b0b49909def88736de81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_ChartToCSVfileWriter.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_ChartToCSVfileWriter.cs new file mode 100644 index 0000000..7d7699e --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_ChartToCSVfileWriter.cs @@ -0,0 +1,124 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + using System.IO; + + public class InternalDXXL_ChartToCSVfileWriter + { + public static string default_csvFileName = "DrawXXL_chart"; + + public void ExportToCSVfile(ChartLines lines, string fileName) + { + if (fileName == null || fileName == "") + { + fileName = default_csvFileName; + } + + string pathPlusFileNameInclFileTypeEnding = Create_pathPlusFileNameInclFileTypeEnding(fileName); + + int maxFilesWithSameName = 1000000; + bool hasFoundValidFilename = false; + int sequentialNumberOfSameFilename = -1; + for (int i = 0; i < maxFilesWithSameName; i++) + { + if (File.Exists(pathPlusFileNameInclFileTypeEnding)) + { + sequentialNumberOfSameFilename = i + 1; + pathPlusFileNameInclFileTypeEnding = Create_pathPlusFileNameInclFileTypeEnding(fileName + "(" + sequentialNumberOfSameFilename + ")"); + } + else + { + hasFoundValidFilename = true; + break; + } + } + + if (hasFoundValidFilename == false) + { + Debug.LogError("Generating CSV file failed: Too many files with same name (of '" + fileName + "')."); + return; + } + + StreamWriter streamWriter = null; + try + { + List allLinesWithAtLeastOneDataPoint_validOrInvalid = lines.Get_all_hiddenAndUnhiddenLines_withAtLeastOneValidOrInvalidDatapoint(out int numberOfDatapoints_inLongestLine, false); + streamWriter = new StreamWriter(pathPlusFileNameInclFileTypeEnding); + + //Line names: + for (int i_line = 0; i_line < allLinesWithAtLeastOneDataPoint_validOrInvalid.Count; i_line++) + { + string lineName = allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].GetNameCompound(false); + if (i_line < (allLinesWithAtLeastOneDataPoint_validOrInvalid.Count - 1)) + { + streamWriter.Write("\"x of " + lineName + "\",\"y of " + lineName + "\","); + } + else + { + streamWriter.WriteLine("\"x of " + lineName + "\",\"y of " + lineName + "\""); + } + } + + //data points: + for (int i_datapoint = 0; i_datapoint < numberOfDatapoints_inLongestLine; i_datapoint++) + { + for (int i_line = 0; i_line < allLinesWithAtLeastOneDataPoint_validOrInvalid.Count; i_line++) + { + if (i_datapoint < allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].dataPoints.Count) + { + if (i_line < (allLinesWithAtLeastOneDataPoint_validOrInvalid.Count - 1)) + { + streamWriter.Write("\"" + allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].dataPoints[i_datapoint].xValue + "\",\"" + allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].dataPoints[i_datapoint].yValue + "\","); + } + else + { + streamWriter.WriteLine("\"" + allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].dataPoints[i_datapoint].xValue + "\",\"" + allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].dataPoints[i_datapoint].yValue + "\""); + } + } + else + { + if (i_line < (allLinesWithAtLeastOneDataPoint_validOrInvalid.Count - 1)) + { + streamWriter.Write(",,"); + } + else + { + streamWriter.WriteLine(","); + } + } + } + } + } + catch + { + Debug.LogError("Writing CSV file failed."); + } + finally + { + try + { + streamWriter.Close(); + if (sequentialNumberOfSameFilename == (-1)) + { + Debug.Log("The file '" + fileName + ".csv' was generated."); + } + else + { + Debug.Log("The file '" + fileName + "(" + sequentialNumberOfSameFilename + ").csv' was generated."); + } + } + catch + { + Debug.LogError("Closing the new CSV file failed."); + } + } + } + + string Create_pathPlusFileNameInclFileTypeEnding(string fileName) + { + return (Application.dataPath + "/" + fileName + ".csv"); + } + + } +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_ChartToCSVfileWriter.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_ChartToCSVfileWriter.cs.meta new file mode 100644 index 0000000..a9eeec6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_ChartToCSVfileWriter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71041864ca5542b429191d71a08545b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_DataPointOfChartLine.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_DataPointOfChartLine.cs new file mode 100644 index 0000000..326c51e --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_DataPointOfChartLine.cs @@ -0,0 +1,389 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class InternalDXXL_DataPointOfChartLine + { + public enum ValidState { isValid, isNaN_atX, isNaN_atY, isPositiveInfinity_atX, isPositiveInfinity_atY, isNegativeInfinity_atX, isNegativeInfinity_atY, isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList } + + ///[Set during point creation]: + public float xValue; //-> is only expected to be "invalid" when using an "AddXYValue()"-function (which doesn't use the automatic x-value-source). So it is not expected for complexer data types (like Vector/Quaternion/Color, which consist of more than 1 line), and also it is not expected for anything that comes from "AddValues_eachIndexIsALine" where many lines are grouped. + public float yValue; + public ValidState validState; //if both values (x and y) are "NaN" (or Infintiy) then this is set to the "_atX" variants. + public int i_ofThisPointInsideContainingLine; + public ChartLine line_thisPointIsPartOf; + public bool hasLittleEmphasizingCircleAroundPoint = false; + public bool forceConnectionLineToLowAlpha; + + ///[Set during drawing]: + public bool isInsideChartRect; + public bool isInsideChartsXSpan; + public bool isDrawn; + public int i_ofPrecedingPointFromWhichLineCanBeDrawn; + public Vector3 positionInWorldSpace; + public Vector3 positionInWorldSpace_atYHeightOfValidPrecedingPoint; + public Vector3 positionInWorldSpace_atYHeightOfLowerEndOf_rgbColorUnderlay; + public Vector3 positionInWorldSpace_atYHeightOfUpperEndOf_rgbColorUnderlay; + + //Others: + static float alphaFactor_indicatingVertConnectionLines = 0.2f; + static float alphaFactor_indicatingNonExistingValues = 0.25f; + + public void DetermineIfAndHowPointIsDrawn(float valueMarkingLowerEndOf_XAxis, float valueMarkingUpperEndOf_XAxis, float valueMarkingLowerEndOf_YAxis, float valueMarkingUpperEndOf_YAxis, int i_ofTheMostCurrentDrawnPoint, bool thereHaveBeenValidPointsOutsideTheDrawnChartArea_sinceMostCurrentDrawnPoint) + { + if (validState == ValidState.isValid) + { + isInsideChartRect = true; + if (xValue < valueMarkingLowerEndOf_XAxis) { isInsideChartRect = false; } + if (xValue > valueMarkingUpperEndOf_XAxis) { isInsideChartRect = false; } + if (yValue < valueMarkingLowerEndOf_YAxis) { isInsideChartRect = false; } + if (yValue > valueMarkingUpperEndOf_YAxis) { isInsideChartRect = false; } + bool isInDrawnArea = isInsideChartRect || line_thisPointIsPartOf.Chart_thisLineIsPartOf.drawValuesOutsideOfChartArea; + isDrawn = isInDrawnArea; + i_ofPrecedingPointFromWhichLineCanBeDrawn = i_ofTheMostCurrentDrawnPoint; + if ((line_thisPointIsPartOf.Chart_thisLineIsPartOf.drawValuesOutsideOfChartArea == false) && thereHaveBeenValidPointsOutsideTheDrawnChartArea_sinceMostCurrentDrawnPoint) + { + i_ofPrecedingPointFromWhichLineCanBeDrawn = -1; + } + positionInWorldSpace = line_thisPointIsPartOf.Chart_thisLineIsPartOf.ChartSpace_to_WorldSpace(new Vector2(xValue, yValue)); + } + else + { + isInsideChartRect = false; + isDrawn = false; + } + } + + public void DetermineIfAndHowPointIsDrawn_forRGBColorUnderlay(float valueMarkingLowerEndOf_XAxis, float valueMarkingUpperEndOf_XAxis, float valueMarkingLowerEndOf_YAxis, float valueMarkingUpperEndOf_YAxis) + { + //-> is only called for valid datapoints + isInsideChartsXSpan = true; + if (xValue < valueMarkingLowerEndOf_XAxis) { isInsideChartsXSpan = false; } + if (xValue > valueMarkingUpperEndOf_XAxis) { isInsideChartsXSpan = false; } + float yGap_toXAxis = 0.01f * (valueMarkingUpperEndOf_YAxis - valueMarkingLowerEndOf_YAxis); + positionInWorldSpace_atYHeightOfLowerEndOf_rgbColorUnderlay = line_thisPointIsPartOf.Chart_thisLineIsPartOf.ChartSpace_to_WorldSpace(new Vector2(xValue, valueMarkingLowerEndOf_YAxis + yGap_toXAxis)); + positionInWorldSpace_atYHeightOfUpperEndOf_rgbColorUnderlay = line_thisPointIsPartOf.Chart_thisLineIsPartOf.ChartSpace_to_WorldSpace(new Vector2(xValue, valueMarkingUpperEndOf_YAxis)); + } + + public void DrawConnectionLineFromPrecedingPoint(Vector3 worldPos_ofPrecedingDrawnPoint, float yValue_ofPrecedingDrawnPoint_inChartSpace, bool lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, float absLineWidth_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects) + { + switch (line_thisPointIsPartOf.lineConnectionsType) + { + case ChartLine.LineConnectionsType.straightFromPointToPoint: + DrawLineFromPrecedingToCurrPoint(worldPos_ofPrecedingDrawnPoint, lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, absLineWidth_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.LineConnectionsType.horizPlateauTillNextPoint: + DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent(worldPos_ofPrecedingDrawnPoint, yValue_ofPrecedingDrawnPoint_inChartSpace, lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, absLineWidth_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.LineConnectionsType.invisible: + break; + default: + break; + } + } + + void DrawLineFromPrecedingToCurrPoint(Vector3 worldPos_ofPrecedingDrawnPoint, bool lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, float absLineWidth_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects) + { + if (lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase || forceConnectionLineToLowAlpha) + { + DrawLineFromPrecedingToCurrPoint_lowAlphaIndicatingNonExistingValues(worldPos_ofPrecedingDrawnPoint, durationInSec, hiddenByNearerObjects); + } + else + { + DrawLineFromPrecedingToCurrPoint_fullAlpha(worldPos_ofPrecedingDrawnPoint, absLineWidth_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects); + } + } + + void DrawLineFromPrecedingToCurrPoint_fullAlpha(Vector3 worldPos_ofPrecedingDrawnPoint, float absLineWidth_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects) + { + Line_fadeableAnimSpeed.InternalDraw(worldPos_ofPrecedingDrawnPoint, positionInWorldSpace, line_thisPointIsPartOf.Color, absLineWidth_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + void DrawLineFromPrecedingToCurrPoint_lowAlphaIndicatingNonExistingValues(Vector3 worldPos_ofPrecedingDrawnPoint, float durationInSec, bool hiddenByNearerObjects) + { + Color color_loweredAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(line_thisPointIsPartOf.Color, alphaFactor_indicatingNonExistingValues); + Line_fadeableAnimSpeed.InternalDraw(worldPos_ofPrecedingDrawnPoint, positionInWorldSpace, color_loweredAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + void DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent(Vector3 worldPos_ofPrecedingDrawnPoint, float yValue_ofPrecedingDrawnPoint_inChartSpace, bool lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, float absLineWidth_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects) + { + if (lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase || forceConnectionLineToLowAlpha) + { + DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent_lowAlphaConfigIndicatingNonExistingValues(worldPos_ofPrecedingDrawnPoint, yValue_ofPrecedingDrawnPoint_inChartSpace, durationInSec, hiddenByNearerObjects); + } + else + { + DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent_defaultAlphaConfig(worldPos_ofPrecedingDrawnPoint, yValue_ofPrecedingDrawnPoint_inChartSpace, absLineWidth_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects); + } + } + + void DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent_defaultAlphaConfig(Vector3 worldPos_ofPrecedingDrawnPoint, float yValue_ofPrecedingDrawnPoint_inChartSpace, float absLineWidth_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects) + { + //horiz Line: + CalcWorldPosAtYHeightOfValidPrecedingPoint(yValue_ofPrecedingDrawnPoint_inChartSpace); + Line_fadeableAnimSpeed.InternalDraw(worldPos_ofPrecedingDrawnPoint, positionInWorldSpace_atYHeightOfValidPrecedingPoint, line_thisPointIsPartOf.Color, absLineWidth_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //vert Line: + Color color_ofVertConnectionLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(line_thisPointIsPartOf.Color, alphaFactor_indicatingVertConnectionLines); + Line_fadeableAnimSpeed.InternalDraw(positionInWorldSpace_atYHeightOfValidPrecedingPoint, positionInWorldSpace, color_ofVertConnectionLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + void DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent_lowAlphaConfigIndicatingNonExistingValues(Vector3 worldPos_ofPrecedingDrawnPoint, float yValue_ofPrecedingDrawnPoint_inChartSpace, float durationInSec, bool hiddenByNearerObjects) + { + //horiz Line: + CalcWorldPosAtYHeightOfValidPrecedingPoint(yValue_ofPrecedingDrawnPoint_inChartSpace); + Color colorHoriz_loweredAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(line_thisPointIsPartOf.Color, alphaFactor_indicatingNonExistingValues); + Line_fadeableAnimSpeed.InternalDraw(worldPos_ofPrecedingDrawnPoint, positionInWorldSpace_atYHeightOfValidPrecedingPoint, colorHoriz_loweredAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //vert Line: + Color color_ofVertConnectionLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(line_thisPointIsPartOf.Color, alphaFactor_indicatingVertConnectionLines); + Color colorVert_loweredAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofVertConnectionLine, 0.5f); + Line_fadeableAnimSpeed.InternalDraw(positionInWorldSpace_atYHeightOfValidPrecedingPoint, positionInWorldSpace, colorVert_loweredAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + void CalcWorldPosAtYHeightOfValidPrecedingPoint(float yValue_ofPrecedingDrawnPoint_inChartSpace) + { + positionInWorldSpace_atYHeightOfValidPrecedingPoint = line_thisPointIsPartOf.Chart_thisLineIsPartOf.ChartSpace_to_WorldSpace(new Vector2(xValue, yValue_ofPrecedingDrawnPoint_inChartSpace)); + } + + public void DrawPointVisualization(float absSizeOfPointVisualization_inWorldSpace, float absLineWidth_forLineItself_worldSpace, float absLineWidth_forPointVisualisators_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects) + { + TryDrawLittleEmphasizingCircleAroundPoint(absLineWidth_forLineItself_worldSpace, durationInSec, hiddenByNearerObjects); + if (validState == ValidState.isValid) + { + DrawVerticalFillLineFromXAxisToPoint(durationInSec, hiddenByNearerObjects); + float halfAbsSizeOfPointVisualization_inWorldSpace; + bool filledWithSpokes; + int numberOfCornersOfStarShape; + switch (line_thisPointIsPartOf.dataPointVisualization) + { + case ChartLine.DataPointVisualization.invisible: + break; + case ChartLine.DataPointVisualization.cross: + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + //horiz crossline: + Vector3 leftCrossEnd_worldSpace = positionInWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsSizeOfPointVisualization_inWorldSpace; + Vector3 rightCrossEnd_worldSpace = positionInWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsSizeOfPointVisualization_inWorldSpace; + Line_fadeableAnimSpeed.InternalDraw(leftCrossEnd_worldSpace, rightCrossEnd_worldSpace, line_thisPointIsPartOf.Color, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //vert crossline: + Vector3 lowerCrossEnd_worldSpace = positionInWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsSizeOfPointVisualization_inWorldSpace; + Vector3 upperCrossEnd_worldSpace = positionInWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsSizeOfPointVisualization_inWorldSpace; + Line_fadeableAnimSpeed.InternalDraw(lowerCrossEnd_worldSpace, upperCrossEnd_worldSpace, line_thisPointIsPartOf.Color, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + break; + case ChartLine.DataPointVisualization.cross45deg: + float halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace * UtilitiesDXXL_Math.inverseSqrtOf2_precalced; + //horiz crossline: + Vector3 lowLeftCrossEnd_worldSpace = positionInWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace; + Vector3 topRightCrossEnd_worldSpace = positionInWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace; + Line_fadeableAnimSpeed.InternalDraw(lowLeftCrossEnd_worldSpace, topRightCrossEnd_worldSpace, line_thisPointIsPartOf.Color, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //vert crossline: + Vector3 topLeftCrossEnd_worldSpace = positionInWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace; + Vector3 lowRightCrossEnd_worldSpace = positionInWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace; + Line_fadeableAnimSpeed.InternalDraw(topLeftCrossEnd_worldSpace, lowRightCrossEnd_worldSpace, line_thisPointIsPartOf.Color, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + break; + case ChartLine.DataPointVisualization.square: + filledWithSpokes = false; + DrawShapes.Square(positionInWorldSpace, absSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.squareCrossed: + filledWithSpokes = true; + DrawShapes.Square(positionInWorldSpace, absSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.triangle: + filledWithSpokes = false; + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + DrawShapes.Triangle(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.triangleCrossed: + filledWithSpokes = true; + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + DrawShapes.Triangle(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.pentagon: + filledWithSpokes = false; + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + DrawShapes.Pentagon(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.pentagonCrossed: + filledWithSpokes = true; + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + DrawShapes.Pentagon(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.circle: + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + filledWithSpokes = false; + DrawShapes.Decagon(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.circleFilled: + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + filledWithSpokes = true; + DrawShapes.Decagon(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.star4corners: + filledWithSpokes = false; + numberOfCornersOfStarShape = 4; + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + DrawShapes.Star(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, numberOfCornersOfStarShape, 0.5f, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.star4CornersCrossed: + filledWithSpokes = true; + numberOfCornersOfStarShape = 4; + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + DrawShapes.Star(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, numberOfCornersOfStarShape, 0.5f, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.star5corners: + filledWithSpokes = false; + numberOfCornersOfStarShape = 5; + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + DrawShapes.Star(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, numberOfCornersOfStarShape, 0.5f, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.star5CornersCrossed: + filledWithSpokes = true; + numberOfCornersOfStarShape = 5; + halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace; + DrawShapes.Star(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, numberOfCornersOfStarShape, 0.5f, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.heart: + float heartIconSize = absSizeOfPointVisualization_inWorldSpace * 1.25f; + int strokeWidth_asPPMofSize_ofHeartIcon = CalcIconWidth_asPPMofSize(heartIconSize, absLineWidth_forPointVisualisators_worldSpace); + DrawBasics.Icon(positionInWorldSpace, DrawBasics.IconType.heart, line_thisPointIsPartOf.Color, heartIconSize, null, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, strokeWidth_asPPMofSize_ofHeartIcon, false, durationInSec, hiddenByNearerObjects); + break; + case ChartLine.DataPointVisualization.customIconSymbol: + float iconSize = absSizeOfPointVisualization_inWorldSpace * 1.35f; + int strokeWidth_asPPMofSize = CalcIconWidth_asPPMofSize(iconSize, absLineWidth_forPointVisualisators_worldSpace); + DrawBasics.Icon(positionInWorldSpace, line_thisPointIsPartOf.customIconAsDatapointVisualization, line_thisPointIsPartOf.Color, iconSize, null, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, strokeWidth_asPPMofSize, false, durationInSec, hiddenByNearerObjects); + break; + default: + break; + } + } + } + + int CalcIconWidth_asPPMofSize(float iconSize, float absLineWidth_forPointVisualisators_worldSpace) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(absLineWidth_forPointVisualisators_worldSpace)) + { + return 0; + } + else + { + return Mathf.RoundToInt((absLineWidth_forPointVisualisators_worldSpace / iconSize) * 1000000.0f); + } + } + + void DrawVerticalFillLineFromXAxisToPoint(float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(line_thisPointIsPartOf.Alpha_ofVerticalAreaFillLines) == false) + { + if (line_thisPointIsPartOf.Alpha_ofVerticalAreaFillLines > 0.0f) + { + Color colorOfVertLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Alpha_ofVerticalAreaFillLines); + Vector2 positionsVertProjectionOntoXAxis_inChartSpace = new Vector2(xValue, line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.ValueMarkingLowerEndOfTheAxis); + Vector3 positionsVertProjectionOntoXAxis_inWorldSpace = line_thisPointIsPartOf.Chart_thisLineIsPartOf.ChartSpace_to_WorldSpace(positionsVertProjectionOntoXAxis_inChartSpace); + Line_fadeableAnimSpeed.InternalDraw(positionInWorldSpace, positionsVertProjectionOntoXAxis_inWorldSpace, colorOfVertLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + + void TryDrawLittleEmphasizingCircleAroundPoint(float absLineWidth_worldSpace, float durationInSec, bool hiddenByNearerObjects) + { + if (hasLittleEmphasizingCircleAroundPoint) + { + float radius = line_thisPointIsPartOf.Chart_thisLineIsPartOf.Height_inWorldSpace * 0.005f + 0.5f * absLineWidth_worldSpace; + DrawShapes.Decagon(positionInWorldSpace, radius, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + } + + public bool HasAPrecedingPointFromWhichLineCanBeDrawn() + { + //needs "DetermineIfAndHowPointIsDrawn" called beforehand + return (i_ofPrecedingPointFromWhichLineCanBeDrawn >= 0); + } + + public string GetInvalidTypeString() + { + switch (validState) + { + case ValidState.isValid: + return "Is valid: " + GetStringTheDisplaysTheXandYvalue(); + case ValidState.isNaN_atX: + return GetStringTheDisplaysTheXandYvalue(); + case ValidState.isNaN_atY: + return GetStringTheDisplaysTheXandYvalue(); + case ValidState.isPositiveInfinity_atX: + return GetStringTheDisplaysTheXandYvalue(); + case ValidState.isPositiveInfinity_atY: + return GetStringTheDisplaysTheXandYvalue(); + case ValidState.isNegativeInfinity_atX: + return GetStringTheDisplaysTheXandYvalue(); + case ValidState.isNegativeInfinity_atY: + return GetStringTheDisplaysTheXandYvalue(); + case ValidState.isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList: + return "Collection index didn't exist at 'AddValues_eachIndexIsALine()'-call (Length/Count was too small)."; + default: + return "[ ValidState of " + validState + " not implemented]"; + } + } + + string GetStringTheDisplaysTheXandYvalue() + { + return "x = " + xValue + " / y = " + yValue; + } + + public static ValidState GetValidStateOf_datapointToBeCreated(bool newDatapoint_isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList, float xValue, float yValue) + { + ValidState validStateOfNewDataPoint = ValidState.isValid; + if (newDatapoint_isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList) + { + validStateOfNewDataPoint = ValidState.isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList; + } + else + { + if (float.IsNaN(xValue)) + { + validStateOfNewDataPoint = ValidState.isNaN_atX; + } + else + { + if (float.IsPositiveInfinity(xValue)) + { + validStateOfNewDataPoint = ValidState.isPositiveInfinity_atX; + } + else + { + if (float.IsNegativeInfinity(xValue)) + { + validStateOfNewDataPoint = ValidState.isNegativeInfinity_atX; + } + else + { + if (float.IsNaN(yValue)) + { + validStateOfNewDataPoint = ValidState.isNaN_atY; + } + else + { + if (float.IsPositiveInfinity(yValue)) + { + validStateOfNewDataPoint = ValidState.isPositiveInfinity_atY; + } + else + { + if (float.IsNegativeInfinity(yValue)) + { + validStateOfNewDataPoint = ValidState.isNegativeInfinity_atY; + } + } + } + } + } + } + } + return validStateOfNewDataPoint; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_DataPointOfChartLine.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_DataPointOfChartLine.cs.meta new file mode 100644 index 0000000..f0f4f62 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_DataPointOfChartLine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ea7c7f5c3b5bf064d9a53823137fecd3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLine.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLine.cs new file mode 100644 index 0000000..bca5b6c --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLine.cs @@ -0,0 +1,107 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class InternalDXXL_HorizontalThresholdLine + { + float yPosition; + bool lineItselfCountsToLowerArea; + ChartLine line_thisThresholdIsPartOf; + + public InternalDXXL_HorizontalThresholdLine(float yPosition, ChartLine line_thisThresholdIsPartOf, bool lineItselfCountsToLowerArea) + { + this.yPosition = yPosition; + this.line_thisThresholdIsPartOf = line_thisThresholdIsPartOf; + this.lineItselfCountsToLowerArea = lineItselfCountsToLowerArea; + } + + public PointOfInterest CheckIntersection(InternalDXXL_DataPointOfChartLine previousDataPoint, InternalDXXL_DataPointOfChartLine currDataPoint) + { + if (previousDataPoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid && currDataPoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + if (lineItselfCountsToLowerArea) + { + //lineItselfCountsTo-LOWER-area: + if (previousDataPoint.yValue <= yPosition) + { + if (currDataPoint.yValue > yPosition) + { + return CreateIntersectionPoint(previousDataPoint, currDataPoint); + } + } + else + { + if (currDataPoint.yValue <= yPosition) + { + return CreateIntersectionPoint(previousDataPoint, currDataPoint); + } + } + } + else + { + //lineItselfCountsTo-HIGHER-area: + if (previousDataPoint.yValue < yPosition) + { + if (currDataPoint.yValue >= yPosition) + { + return CreateIntersectionPoint(previousDataPoint, currDataPoint); + } + } + else + { + if (currDataPoint.yValue < yPosition) + { + return CreateIntersectionPoint(previousDataPoint, currDataPoint); + } + } + } + } + return null; + } + + PointOfInterest CreateIntersectionPoint(InternalDXXL_DataPointOfChartLine previousDataPoint, InternalDXXL_DataPointOfChartLine currDataPoint) + { + previousDataPoint.hasLittleEmphasizingCircleAroundPoint = true; + currDataPoint.hasLittleEmphasizingCircleAroundPoint = true; + + float x_ofIntersectionPos; + if (line_thisThresholdIsPartOf.lineConnectionsType == ChartLine.LineConnectionsType.horizPlateauTillNextPoint) + { + x_ofIntersectionPos = currDataPoint.xValue; + } + else + { + InternalDXXL_Line2D line2D_betweenDataPoints = new InternalDXXL_Line2D(); + Vector2 previousDataPoint_asV2 = new Vector2(previousDataPoint.xValue, previousDataPoint.yValue); + Vector2 currDataPoint_asV2 = new Vector2(currDataPoint.xValue, currDataPoint.yValue); + line2D_betweenDataPoints.Recalc_line_throughTwoPoints_returnSteepForVertLines(previousDataPoint_asV2, currDataPoint_asV2); + x_ofIntersectionPos = line2D_betweenDataPoints.GetXatY(yPosition); + } + + Color colorOfGeneratedIntersectionPoints = UtilitiesDXXL_Colors.GetSimilarColorWithSlightlyOtherBrightnessValue(line_thisThresholdIsPartOf.Color); + colorOfGeneratedIntersectionPoints.a = 1.0f; + + string notificationText; + if (previousDataPoint.yValue < currDataPoint.yValue) + { + Color risingFlankColor = Color.Lerp(UtilitiesDXXL_Colors.green_boolTrue, colorOfGeneratedIntersectionPoints, 0.18f); + notificationText = "Line '" + line_thisThresholdIsPartOf.Name + "':
" + DrawText.MarkupIcon(DrawBasics.IconType.arrowUp) + "Rising flank intersects threshold at
x = " + x_ofIntersectionPos + " / y = " + yPosition + "
Data point before intersection:
x = " + previousDataPoint.xValue + " / y = " + previousDataPoint.yValue + "
Data point after intersection:
x = " + currDataPoint.xValue + " / y = " + currDataPoint.yValue; + } + else + { + Color fallingFlankColor = Color.Lerp(UtilitiesDXXL_Colors.red_boolFalse, colorOfGeneratedIntersectionPoints, 0.18f); + notificationText = "Line '" + line_thisThresholdIsPartOf.Name + "':
" + DrawText.MarkupIcon(DrawBasics.IconType.arrowDown) + "Falling flank intersects threshold at
x = " + x_ofIntersectionPos + " / y = " + yPosition + "
Data point before intersection:
x = " + previousDataPoint.xValue + " / y = " + previousDataPoint.yValue + "
Data point after intersection:
x = " + currDataPoint.xValue + " / y = " + currDataPoint.yValue; + } + + PointOfInterest pointOfInterest_thatIndicatesTheThresholdCrossing = new PointOfInterest(x_ofIntersectionPos, yPosition, colorOfGeneratedIntersectionPoints, line_thisThresholdIsPartOf.Chart_thisLineIsPartOf, line_thisThresholdIsPartOf, notificationText); + pointOfInterest_thatIndicatesTheThresholdCrossing.drawTextBoxIfPointIsOutsideOfChartArea = true; + pointOfInterest_thatIndicatesTheThresholdCrossing.isDeletedOnClear = true; + pointOfInterest_thatIndicatesTheThresholdCrossing.forceColorOfParent = false; + pointOfInterest_thatIndicatesTheThresholdCrossing.xValue.lineStyle = DrawBasics.LineStyle.invisible; + pointOfInterest_thatIndicatesTheThresholdCrossing.yValue.lineStyle = DrawBasics.LineStyle.invisible; + return pointOfInterest_thatIndicatesTheThresholdCrossing; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLine.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLine.cs.meta new file mode 100644 index 0000000..5fba372 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38f65caec75b17548b15445629b00abb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLineInitializer.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLineInitializer.cs new file mode 100644 index 0000000..c00aae2 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLineInitializer.cs @@ -0,0 +1,8 @@ +namespace DrawXXL +{ + public struct InternalDXXL_HorizontalThresholdLineInitializer + { + public float yPositionOfThresholdToCreate; + public bool lineItselfCountsToLowerArea; + } +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLineInitializer.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLineInitializer.cs.meta new file mode 100644 index 0000000..43dca35 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_HorizontalThresholdLineInitializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5cb7905e96a371f46b115fe814ce96c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_LineSpecsForChartInspector.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_LineSpecsForChartInspector.cs new file mode 100644 index 0000000..75cbaac --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_LineSpecsForChartInspector.cs @@ -0,0 +1,247 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + + [Serializable] + public class InternalDXXL_LineSpecsForChartInspector + { + static int default_numberOfDisplayedDatapointsInArray = 7; + public static bool lineCompoundNames_haveSpaces_betweenTheNamePartConnectingMinus = true; + + public ChartLine line_theseSpecsBelongTo; + public bool currentHideLineState; + public bool currentHideCursorXState_duringComponentInspectionPhase = true; + public bool currentHideCursorYState_duringComponentInspectionPhase = false; + public Color lineColor; + public ChartLine.LineConnectionsType connectionsType; + public ChartLine.DataPointVisualization dataPointVisualization; + [Range(0.002f, 0.3f)] public float dataPointVisualization_size; + [Range(0.0f, 1.0f)] public float alpha_ofVertFillLines; + [Range(0.0f, 0.2f)] public float lineWidth; + public string linesCompoundName; + [SerializeField] int numberOfDisplayedDatapointsInArray = default_numberOfDisplayedDatapointsInArray; + [SerializeField] InternalDXXL_NeighboringDatapointForChartInspector[] neighboringDatapointValues; + [SerializeField] int i_insideShortenedForInspectorArray_markingTheValueAtCursor; + [SerializeField] bool lineSection_isExpanded = false; + [SerializeField] bool datapointValuesSection_isExpanded = false; + int i_ofValueInsideLinesDatapointListThatIsXNearestToCursor; + public bool hasValidDatapointThatIsXNearestToCursor = false; + public Vector2 posInChartspace_ofDatapointThatIsNearestToCursor; + public int i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray; + + public void TryRefill_arrayWithNeighboringDatapointValues() + { + TryReconstruct_arrayWithNeighboringDatapointValues(); + if (lineSection_isExpanded && datapointValuesSection_isExpanded) + { + for (int i_currentlyFilledSlot_inShortenedInspectorArray = 0; i_currentlyFilledSlot_inShortenedInspectorArray < neighboringDatapointValues.Length; i_currentlyFilledSlot_inShortenedInspectorArray++) + { + if (hasValidDatapointThatIsXNearestToCursor) + { + int slotsDiffernceToCursorSlot = i_currentlyFilledSlot_inShortenedInspectorArray - i_insideShortenedForInspectorArray_markingTheValueAtCursor; + int i_insideLinesDatapointList = i_ofValueInsideLinesDatapointListThatIsXNearestToCursor + slotsDiffernceToCursorSlot; + if (i_insideLinesDatapointList < 0 || i_insideLinesDatapointList >= line_theseSpecsBelongTo.dataPoints.Count) + { + neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].x = float.NaN; + neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].y = float.NaN; + neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].deltaSincePrecedingY = float.NaN; + } + else + { + neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].x = line_theseSpecsBelongTo.dataPoints[i_insideLinesDatapointList].xValue; + neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].y = line_theseSpecsBelongTo.dataPoints[i_insideLinesDatapointList].yValue; + + if (i_insideLinesDatapointList < 1) + { + neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].deltaSincePrecedingY = float.NaN; + } + else + { + neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].deltaSincePrecedingY = line_theseSpecsBelongTo.dataPoints[i_insideLinesDatapointList].yValue - line_theseSpecsBelongTo.dataPoints[i_insideLinesDatapointList - 1].yValue; + } + } + } + else + { + //Obtainment of "i_ofValueInsideLinesDatapointListThatIsXNearestToCursor" failed: + neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].x = float.NaN; + neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].y = float.NaN; + neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].deltaSincePrecedingY = float.NaN; + } + } + } + } + + void TryReconstruct_arrayWithNeighboringDatapointValues() + { + numberOfDisplayedDatapointsInArray = Mathf.Max(numberOfDisplayedDatapointsInArray, 3); + numberOfDisplayedDatapointsInArray = Mathf.Min(numberOfDisplayedDatapointsInArray, 200); //-> why not exporting to CSV if many datapoints are needed? The editor will have performance problems with higher values + if (numberOfDisplayedDatapointsInArray != neighboringDatapointValues.Length) { Reconstruct_arrayWithNeighboringDatapointValues(); } + } + + public void Reconstruct_arrayWithNeighboringDatapointValues() + { + neighboringDatapointValues = new InternalDXXL_NeighboringDatapointForChartInspector[numberOfDisplayedDatapointsInArray]; + i_insideShortenedForInspectorArray_markingTheValueAtCursor = Mathf.RoundToInt(0.5f * (neighboringDatapointValues.Length - 1)); + for (int i = 0; i < neighboringDatapointValues.Length; i++) + { + neighboringDatapointValues[i] = new InternalDXXL_NeighboringDatapointForChartInspector(); + } + } + + public void Recalc_posThatIsXNearestToCursor(float xValueOfCursor_inChartspace) + { + Calc_i_ofValueInsideLinesDatapointListThatIsXNearestToCursor(xValueOfCursor_inChartspace); + hasValidDatapointThatIsXNearestToCursor = (i_ofValueInsideLinesDatapointListThatIsXNearestToCursor >= 0); + if (hasValidDatapointThatIsXNearestToCursor) + { + posInChartspace_ofDatapointThatIsNearestToCursor = new Vector2(line_theseSpecsBelongTo.dataPoints[i_ofValueInsideLinesDatapointListThatIsXNearestToCursor].xValue, line_theseSpecsBelongTo.dataPoints[i_ofValueInsideLinesDatapointListThatIsXNearestToCursor].yValue); + } + else + { + posInChartspace_ofDatapointThatIsNearestToCursor = new Vector2(xValueOfCursor_inChartspace, 0.5f); + } + } + + void Calc_i_ofValueInsideLinesDatapointListThatIsXNearestToCursor(float xValueOfCursor_inChartspace) + { + if (line_theseSpecsBelongTo.AllXValuesCameFromAutomaticSource) + { + //performance saving assumption: the x values always rise + int i_nearestBelowCursor = -1; + int i_nearestAboveCursor = line_theseSpecsBelongTo.dataPoints.Count; + RestrictPossibleCandidates(10000, out i_nearestBelowCursor, out i_nearestAboveCursor, i_nearestBelowCursor, i_nearestAboveCursor, xValueOfCursor_inChartspace); + RestrictPossibleCandidates(1000, out i_nearestBelowCursor, out i_nearestAboveCursor, i_nearestBelowCursor, i_nearestAboveCursor, xValueOfCursor_inChartspace); + RestrictPossibleCandidates(100, out i_nearestBelowCursor, out i_nearestAboveCursor, i_nearestBelowCursor, i_nearestAboveCursor, xValueOfCursor_inChartspace); + RestrictPossibleCandidates(10, out i_nearestBelowCursor, out i_nearestAboveCursor, i_nearestBelowCursor, i_nearestAboveCursor, xValueOfCursor_inChartspace); + + if ((i_nearestBelowCursor < 0) && (i_nearestAboveCursor >= line_theseSpecsBelongTo.dataPoints.Count)) + { + //pre-checks that restrict the datapoint candidates failed: + i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = Get_i_datapointThatIsXNearestToCursor_viaBruteForceCheckAllDatapoints(xValueOfCursor_inChartspace); + } + else + { + if (i_nearestBelowCursor == i_nearestAboveCursor) { i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = i_nearestBelowCursor; return; } + + //cursor is left of whole line: + if (i_nearestAboveCursor <= 0) { i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = 0; return; } + + //cursor is right of whole line: + if (i_nearestBelowCursor >= (line_theseSpecsBelongTo.dataPoints.Count - 1)) { i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = (line_theseSpecsBelongTo.dataPoints.Count - 1); return; } + + i_nearestBelowCursor = Mathf.Max(i_nearestBelowCursor, 0); + i_nearestAboveCursor = Mathf.Min(i_nearestAboveCursor, (line_theseSpecsBelongTo.dataPoints.Count - 1)); + i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = Get_i_datapointThatIsXNearestToCursor_ofDatapointSpan(xValueOfCursor_inChartspace, i_nearestBelowCursor, i_nearestAboveCursor); + } + } + else + { + //no assumption that the x values always rise: + i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = Get_i_datapointThatIsXNearestToCursor_viaBruteForceCheckAllDatapoints(xValueOfCursor_inChartspace); + } + } + + void RestrictPossibleCandidates(int indexDistanceBetweenEachCheckedDatapoint, out int i_nearestBelowCursor, out int i_nearestAboveCursor, int i_nearestBelowCursor_atStartOfCheck, int i_nearestAboveCursor_atStartOfCheck, float xValueOfCursor_inChartspace) + { + i_nearestBelowCursor = i_nearestBelowCursor_atStartOfCheck; + i_nearestAboveCursor = i_nearestAboveCursor_atStartOfCheck; + + indexDistanceBetweenEachCheckedDatapoint = Mathf.Max(indexDistanceBetweenEachCheckedDatapoint, 1); + for (int i_currentlyCheckedDatapoint = i_nearestBelowCursor_atStartOfCheck; i_currentlyCheckedDatapoint <= i_nearestAboveCursor_atStartOfCheck;) + { + if (i_currentlyCheckedDatapoint >= 0 && i_currentlyCheckedDatapoint < line_theseSpecsBelongTo.dataPoints.Count) + { + if (line_theseSpecsBelongTo.dataPoints[i_currentlyCheckedDatapoint].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + if (line_theseSpecsBelongTo.dataPoints[i_currentlyCheckedDatapoint].xValue < xValueOfCursor_inChartspace) + { + i_nearestBelowCursor = i_currentlyCheckedDatapoint; + } + else + { + i_nearestAboveCursor = i_currentlyCheckedDatapoint; + break; + } + } + } + i_currentlyCheckedDatapoint = i_currentlyCheckedDatapoint + indexDistanceBetweenEachCheckedDatapoint; + } + } + + int Get_i_datapointThatIsXNearestToCursor_viaBruteForceCheckAllDatapoints(float xValueOfCursor_inChartspace) + { + return Get_i_datapointThatIsXNearestToCursor_ofDatapointSpan(xValueOfCursor_inChartspace, 0, line_theseSpecsBelongTo.dataPoints.Count - 1); + } + + int Get_i_datapointThatIsXNearestToCursor_ofDatapointSpan(float xValueOfCursor_inChartspace, int i_lowSpanEnd, int i_highSpanEnd) + { + //Debug.Log("span: " + (i_highSpanEnd - i_lowSpanEnd) + " i_lowSpanEnd : "+ i_lowSpanEnd + " i_highSpanEnd: "+ i_highSpanEnd); + int i_ofCurrentlyNearest = -1; + float absDistance_ofCurrentlyNearest = float.PositiveInfinity; + for (int i_currentlyCheckedDatapoint = i_lowSpanEnd; i_currentlyCheckedDatapoint <= i_highSpanEnd; i_currentlyCheckedDatapoint++) + { + if (line_theseSpecsBelongTo.dataPoints[i_currentlyCheckedDatapoint].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + //some aggressive inlining: + float absDistanceToCursor = line_theseSpecsBelongTo.dataPoints[i_currentlyCheckedDatapoint].xValue - xValueOfCursor_inChartspace; + if (absDistanceToCursor < 0.0f) + { + absDistanceToCursor = -absDistanceToCursor; + } + + if (absDistanceToCursor < absDistance_ofCurrentlyNearest) + { + absDistance_ofCurrentlyNearest = absDistanceToCursor; + i_ofCurrentlyNearest = i_currentlyCheckedDatapoint; + } + } + } + return i_ofCurrentlyNearest; + } + + public void DrawCursorNearestPoint(float sizeOfDatapointVisualization, bool hiddenByNearerObjects) + { + if (currentHideLineState == false) + { + if ((currentHideCursorXState_duringComponentInspectionPhase == false) || (currentHideCursorYState_duringComponentInspectionPhase == false)) + { + if (hasValidDatapointThatIsXNearestToCursor) + { + ChartDrawing parentChart = line_theseSpecsBelongTo.Chart_thisLineIsPartOf; + if (parentChart.IsInsideDrawnChartArea(posInChartspace_ofDatapointThatIsNearestToCursor) || parentChart.drawValuesOutsideOfChartArea) + { + Vector3 position_worldSpace = parentChart.ChartSpace_to_WorldSpace(posInChartspace_ofDatapointThatIsNearestToCursor); + float sizeOfMarkingCross = parentChart.Height_inWorldSpace * (0.01f + 0.6f * sizeOfDatapointVisualization); + Color datapointColor = line_theseSpecsBelongTo.Color; + DrawBasics.Point(position_worldSpace, datapointColor, sizeOfMarkingCross, parentChart.InternalRotation, 0.0f, null, datapointColor, false, false, true, 0.0f, hiddenByNearerObjects); + + float circleRadius = 0.14f * sizeOfMarkingCross; + DrawShapes.Decagon(position_worldSpace, circleRadius, datapointColor, parentChart.InternalRotation, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, 0.0f, hiddenByNearerObjects); + + float textSize = 0.3f * sizeOfMarkingCross; + float dimensionSpecifyingTextSize = textSize * 0.5f; + Color color_ofDimensionSpecifier = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(datapointColor, 0.4f); + + if (currentHideCursorYState_duringComponentInspectionPhase == false) + { + UtilitiesDXXL_Text.WriteFramed(" y=", position_worldSpace, color_ofDimensionSpecifier, dimensionSpecifyingTextSize, parentChart.InternalRotation, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, parentChart.autoFlipAllText_toFitObsererCamera, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Text.WriteFramed(" " + posInChartspace_ofDatapointThatIsNearestToCursor.y, position_worldSpace, datapointColor, textSize, parentChart.InternalRotation, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, parentChart.autoFlipAllText_toFitObsererCamera, 0.0f, hiddenByNearerObjects); + } + + if (currentHideCursorXState_duringComponentInspectionPhase == false) + { + Vector3 textDir_forXText_normalized = parentChart.yAxis.AxisVector_normalized_inWorldSpace; + Vector3 textUp_forXText_normalized = -parentChart.xAxis.AxisVector_normalized_inWorldSpace; + UtilitiesDXXL_Text.Write(" x=", position_worldSpace, color_ofDimensionSpecifier, dimensionSpecifyingTextSize, textDir_forXText_normalized, textUp_forXText_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, parentChart.autoFlipAllText_toFitObsererCamera, 0.0f, hiddenByNearerObjects, false, false, true); + UtilitiesDXXL_Text.Write(" " + posInChartspace_ofDatapointThatIsNearestToCursor.x, position_worldSpace, datapointColor, textSize, textDir_forXText_normalized, textUp_forXText_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, parentChart.autoFlipAllText_toFitObsererCamera, 0.0f, hiddenByNearerObjects, false, false, true); + } + } + } + } + } + } + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_LineSpecsForChartInspector.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_LineSpecsForChartInspector.cs.meta new file mode 100644 index 0000000..99779fc --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_LineSpecsForChartInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17d8a010df19ac94abcdc1b898f79166 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_NeighboringDatapointForChartInspector.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_NeighboringDatapointForChartInspector.cs new file mode 100644 index 0000000..1e3436b --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_NeighboringDatapointForChartInspector.cs @@ -0,0 +1,12 @@ +namespace DrawXXL +{ + using System; + + [Serializable] + public struct InternalDXXL_NeighboringDatapointForChartInspector + { + public float x; + public float y; + public float deltaSincePrecedingY; + } +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_NeighboringDatapointForChartInspector.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_NeighboringDatapointForChartInspector.cs.meta new file mode 100644 index 0000000..236b5e0 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_NeighboringDatapointForChartInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e0462d2ff3fca04fb36e93d040db7a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPoint.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPoint.cs new file mode 100644 index 0000000..9a70728 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPoint.cs @@ -0,0 +1,9 @@ +namespace DrawXXL +{ + public class InternalDXXL_TurningPoint //This is "class" instead of "struct" because it should be nullable + { + public PointOfInterest pointOfInterest_thatRepresentsThisTurningPoint; + public bool isTheEndOfAPlateau; + public bool isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight; + } +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPoint.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPoint.cs.meta new file mode 100644 index 0000000..a03d87c --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPoint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bff8d6ed15c7bc947a984463baadaa55 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPointDetector.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPointDetector.cs new file mode 100644 index 0000000..3f7b64b --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPointDetector.cs @@ -0,0 +1,393 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class InternalDXXL_TurningPointDetector + { + List allUpperTurningPoints = new List(); + List allLowerTurningPoints = new List(); + List turningPoints_thatHighlightOnlyTheOverallHighestYValue = new List(); + List turningPoints_thatHighlightOnlyTheOverallLowestYValue = new List(); + + int i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau; + int i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau; + int i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau; + int i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau; + int i_ofPrecedingDatapoint; + + ChartLine line_thisDetectorIsPartOf; + + public InternalDXXL_TurningPointDetector(ChartLine line_thisDetectorIsPartOf) + { + this.line_thisDetectorIsPartOf = line_thisDetectorIsPartOf; + DiscardPrecedingPointsFromComparison(); + } + + public void Clear() + { + allUpperTurningPoints.Clear(); + allLowerTurningPoints.Clear(); + turningPoints_thatHighlightOnlyTheOverallHighestYValue.Clear(); + turningPoints_thatHighlightOnlyTheOverallLowestYValue.Clear(); + DiscardPrecedingPointsFromComparison(); + } + + public void DiscardPrecedingPointsFromComparison() + { + i_ofPrecedingDatapoint = -1; + i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau = -1; + i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau = -1; + i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau = -1; + i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau = -1; + } + + public void AddNewDatapoint(int i_newDatapoint) + { + if (line_thisDetectorIsPartOf.dataPoints[i_newDatapoint].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid) + { + if (i_ofPrecedingDatapoint >= 0) + { + CheckMaxPlateau(i_newDatapoint); + CheckMinPlateau(i_newDatapoint); + } + i_ofPrecedingDatapoint = i_newDatapoint; + } + else + { + //New datapoint is invalid: + DiscardPrecedingPointsFromComparison(); + } + } + + void CheckMaxPlateau(int i_newDatapoint) + { + if (line_thisDetectorIsPartOf.dataPoints[i_newDatapoint].yValue > line_thisDetectorIsPartOf.dataPoints[i_ofPrecedingDatapoint].yValue) + { + i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau = i_newDatapoint; + i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau = i_newDatapoint; + } + else + { + if (line_thisDetectorIsPartOf.dataPoints[i_newDatapoint].yValue == line_thisDetectorIsPartOf.dataPoints[i_ofPrecedingDatapoint].yValue) + { + i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau = i_newDatapoint; + } + else + { + if (i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau > 0) + { + CreateTurningPoint_atMaxPlateau(); + } + i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau = -1; + i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau = -1; + } + } + } + + void CreateTurningPoint_atMaxPlateau() + { + bool isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest = (i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau != i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau); + //string labelText_atVertLine = isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest ? "start of max" : null; //->would be too packed in many situations + InternalDXXL_TurningPoint turningPoint_atStartOfMaxPlateau = CreateTurningPoint(i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau, "max", false); + InternalDXXL_TurningPoint turningPoint_atEndOfMaxPlateau = null; + if (isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest) + { + turningPoint_atEndOfMaxPlateau = CreateTurningPoint(i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau, null, true); + } + + bool addToListWithOverallHighestTurningPoints = CompareWith_overallHighestValues(); + + allUpperTurningPoints.Add(turningPoint_atStartOfMaxPlateau); + if (addToListWithOverallHighestTurningPoints) { turningPoints_thatHighlightOnlyTheOverallHighestYValue.Add(turningPoint_atStartOfMaxPlateau); } + line_thisDetectorIsPartOf.AddPointOfInterest(turningPoint_atStartOfMaxPlateau.pointOfInterest_thatRepresentsThisTurningPoint); + + if (turningPoint_atEndOfMaxPlateau != null) + { + allUpperTurningPoints.Add(turningPoint_atEndOfMaxPlateau); + if (addToListWithOverallHighestTurningPoints) { turningPoints_thatHighlightOnlyTheOverallHighestYValue.Add(turningPoint_atEndOfMaxPlateau); } + line_thisDetectorIsPartOf.AddPointOfInterest(turningPoint_atEndOfMaxPlateau.pointOfInterest_thatRepresentsThisTurningPoint); + } + } + + bool CompareWith_overallHighestValues() + { + if (turningPoints_thatHighlightOnlyTheOverallHighestYValue.Count > 0) + { + if (line_thisDetectorIsPartOf.dataPoints[i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau].yValue > turningPoints_thatHighlightOnlyTheOverallHighestYValue[0].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position) + { + turningPoints_thatHighlightOnlyTheOverallHighestYValue.Clear(); + return true; + } + else + { + if (line_thisDetectorIsPartOf.dataPoints[i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau].yValue == turningPoints_thatHighlightOnlyTheOverallHighestYValue[0].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position) + { + return true; + } + else + { + return false; + } + } + } + else + { + return true; + } + } + + void CheckMinPlateau(int i_newDatapoint) + { + if (line_thisDetectorIsPartOf.dataPoints[i_newDatapoint].yValue < line_thisDetectorIsPartOf.dataPoints[i_ofPrecedingDatapoint].yValue) + { + i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau = i_newDatapoint; + i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau = i_newDatapoint; + } + else + { + if (line_thisDetectorIsPartOf.dataPoints[i_newDatapoint].yValue == line_thisDetectorIsPartOf.dataPoints[i_ofPrecedingDatapoint].yValue) + { + i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau = i_newDatapoint; + } + else + { + if (i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau > 0) + { + CreateTurningPointOf_atMinPlateau(); + } + i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau = -1; + i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau = -1; + } + } + } + + void CreateTurningPointOf_atMinPlateau() + { + bool isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest = (i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau != i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau); + //string labelText_atVertLine = isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest ? "start of min" : null;//->would be too packed in many situations + InternalDXXL_TurningPoint turningPoint_atStartOfMinPlateau = CreateTurningPoint(i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau, "min", false); + InternalDXXL_TurningPoint turningPoint_atEndOfMinPlateau = null; + if (isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest) + { + turningPoint_atEndOfMinPlateau = CreateTurningPoint(i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau, null, true); + } + + bool addToListWithOverallLowestTurningPoints = CompareWith_overallLowestValues(); + + allLowerTurningPoints.Add(turningPoint_atStartOfMinPlateau); + if (addToListWithOverallLowestTurningPoints) { turningPoints_thatHighlightOnlyTheOverallLowestYValue.Add(turningPoint_atStartOfMinPlateau); } + line_thisDetectorIsPartOf.AddPointOfInterest(turningPoint_atStartOfMinPlateau.pointOfInterest_thatRepresentsThisTurningPoint); + + if (turningPoint_atEndOfMinPlateau != null) + { + allLowerTurningPoints.Add(turningPoint_atEndOfMinPlateau); + if (addToListWithOverallLowestTurningPoints) { turningPoints_thatHighlightOnlyTheOverallLowestYValue.Add(turningPoint_atEndOfMinPlateau); } + line_thisDetectorIsPartOf.AddPointOfInterest(turningPoint_atEndOfMinPlateau.pointOfInterest_thatRepresentsThisTurningPoint); + } + } + + bool CompareWith_overallLowestValues() + { + if (turningPoints_thatHighlightOnlyTheOverallLowestYValue.Count > 0) + { + if (line_thisDetectorIsPartOf.dataPoints[i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau].yValue < turningPoints_thatHighlightOnlyTheOverallLowestYValue[0].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position) + { + turningPoints_thatHighlightOnlyTheOverallLowestYValue.Clear(); + return true; + } + else + { + if (line_thisDetectorIsPartOf.dataPoints[i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau].yValue == turningPoints_thatHighlightOnlyTheOverallLowestYValue[0].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position) + { + return true; + } + else + { + return false; + } + } + } + else + { + return true; + } + } + + InternalDXXL_TurningPoint CreateTurningPoint(int i_ofDatapointWhereToCreate, string labelText_atHorizLine, bool isEndOfPlateau) + { + float position_x = line_thisDetectorIsPartOf.dataPoints[i_ofDatapointWhereToCreate].xValue; + float position_y = line_thisDetectorIsPartOf.dataPoints[i_ofDatapointWhereToCreate].yValue; + PointOfInterest createdPointOfInterest = new PointOfInterest(position_x, position_y, DrawBasics.defaultColor, line_thisDetectorIsPartOf.Chart_thisLineIsPartOf, line_thisDetectorIsPartOf, null); + createdPointOfInterest.drawTextBoxIfPointIsOutsideOfChartArea = false; + createdPointOfInterest.isDeletedOnClear = true; + createdPointOfInterest.forceColorOfParent = true; + //createdPointOfInterest.xValue.labelText = labelText_atVertLine; + createdPointOfInterest.xValue.labelText = null; + createdPointOfInterest.xValue.drawCoordinateAsText = true; + createdPointOfInterest.xValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.axisToPoint; + createdPointOfInterest.xValue.linestylePatternScaleFactor = 0.8f; + createdPointOfInterest.yValue.labelText = labelText_atHorizLine + " = " + line_thisDetectorIsPartOf.dataPoints[i_ofDatapointWhereToCreate].yValue; + createdPointOfInterest.yValue.drawCoordinateAsText = false; + createdPointOfInterest.yValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.axisToPoint; + + InternalDXXL_TurningPoint createdTurningPoint = new InternalDXXL_TurningPoint(); + createdTurningPoint.pointOfInterest_thatRepresentsThisTurningPoint = createdPointOfInterest; + createdTurningPoint.isTheEndOfAPlateau = isEndOfPlateau; + + return createdTurningPoint; + } + + public void SetIfVisualizationIsDisplayed() + { + SetIfVisualizationOfYMaximumTurningPointsIsDisplayed(); + SetIfVisualizationOfYMinimumTurningPointsIsDisplayed(); + SetIfVisualizationOfSingleHighestValueIsDisplayed(); + SetIfVisualizationOfSingleLowestValueIsDisplayed(); + } + + void SetIfVisualizationOfYMaximumTurningPointsIsDisplayed() + { + if (line_thisDetectorIsPartOf.markAllYMaximumTurningPoints) + { + SetVisibleState_forListOf_pointsOfInterest(true, allUpperTurningPoints, true, false); + } + else + { + SetVisibleState_forListOf_pointsOfInterest(false, allUpperTurningPoints, true, false); + } + } + + void SetIfVisualizationOfYMinimumTurningPointsIsDisplayed() + { + if (line_thisDetectorIsPartOf.markAllYMinimumTurningPoints) + { + SetVisibleState_forListOf_pointsOfInterest(true, allLowerTurningPoints, false, false); + } + else + { + SetVisibleState_forListOf_pointsOfInterest(false, allLowerTurningPoints, false, false); + } + } + + void SetIfVisualizationOfSingleHighestValueIsDisplayed() + { + if (line_thisDetectorIsPartOf.markAllYMaximumTurningPoints == false) + { + //-> all turningPoints are turned to invisible, if arriving here + if (UtilitiesDXXL_Math.ApproximatelyZero(line_thisDetectorIsPartOf.alpha_ofMaxiumumYValueMarker) == false) + { + SetVisibleState_forListOf_pointsOfInterest(true, turningPoints_thatHighlightOnlyTheOverallHighestYValue, true, true); + } + } + } + + void SetIfVisualizationOfSingleLowestValueIsDisplayed() + { + if (line_thisDetectorIsPartOf.markAllYMinimumTurningPoints == false) + { + //-> all turningPoints are turned to invisible, if arriving here + if (UtilitiesDXXL_Math.ApproximatelyZero(line_thisDetectorIsPartOf.alpha_ofMinimumYValueMarker) == false) + { + SetVisibleState_forListOf_pointsOfInterest(true, turningPoints_thatHighlightOnlyTheOverallLowestYValue, false, true); + } + } + } + + void SetVisibleState_forListOf_pointsOfInterest(bool shouldBeVisible, List concernedTurningPoints, bool isHighTurningPoint_notLow, bool forceInvisibleIfItIsNotTheMostExtremePointOfTheWholeLine) + { + if (shouldBeVisible) + { + MarkPointsIfTheyAre_theMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight(concernedTurningPoints); + for (int i = 0; i < concernedTurningPoints.Count; i++) + { + if (isHighTurningPoint_notLow) + { + //high turning points: + if (forceInvisibleIfItIsNotTheMostExtremePointOfTheWholeLine) + { + //-> The first and the last datapoint or datapoints beside invalid values can be more extreme but don't count as turning points + float yOfTurningPoint = concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position; + if (yOfTurningPoint < line_thisDetectorIsPartOf.HighestYValue) { continue; } + } + concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.xValue.color = new Color(1, 1, 1, line_thisDetectorIsPartOf.alpha_ofMaxiumumYValueMarker); //-> only for setting alpha. The actual color gets forced from lineParent + concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.color = new Color(1, 1, 1, line_thisDetectorIsPartOf.alpha_ofMaxiumumYValueMarker); //-> only for setting alpha. The actual color gets forced from lineParent + } + else + { + //low turning points: + if (forceInvisibleIfItIsNotTheMostExtremePointOfTheWholeLine) + { + //-> The first and the last datapoint or datapoints beside invalid values can be more extreme but don't count as turning points + float yOfTurningPoint = concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position; + if (yOfTurningPoint > line_thisDetectorIsPartOf.LowestYValue) { continue; } + } + concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.xValue.color = new Color(1, 1, 1, line_thisDetectorIsPartOf.alpha_ofMinimumYValueMarker); //-> only for setting alpha. The actual color gets forced from lineParent + concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.color = new Color(1, 1, 1, line_thisDetectorIsPartOf.alpha_ofMinimumYValueMarker); //-> only for setting alpha. The actual color gets forced from lineParent + } + + DrawBasics.LineStyle linestyle_forHorizLine = DrawBasics.LineStyle.solid; + if (concernedTurningPoints[i].isTheEndOfAPlateau) { linestyle_forHorizLine = DrawBasics.LineStyle.invisible; } + if (concernedTurningPoints[i].isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight == false) { linestyle_forHorizLine = DrawBasics.LineStyle.invisible; } //-> This prevents multiple points at the same yHeight from adding up their alpha from the horizontal low alpha turningPointMarkerLines until it is almost alpha=1 and is not distinguishable anymore from the dataLine itself. + if (line_thisDetectorIsPartOf.disableMinMaxYVisualizers_dueTo_lineRepresentsBoolValues) { linestyle_forHorizLine = DrawBasics.LineStyle.invisible; } + + concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.xValue.lineStyle = DrawBasics.LineStyle.dashed; + concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.lineStyle = linestyle_forHorizLine; + } + } + else + { + for (int i = 0; i < concernedTurningPoints.Count; i++) + { + concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.xValue.lineStyle = DrawBasics.LineStyle.invisible; + concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.lineStyle = DrawBasics.LineStyle.invisible; + } + } + } + + void MarkPointsIfTheyAre_theMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight(List concernedTurningPoints) + { + for (int i_currCheckedTurningPoint = 0; i_currCheckedTurningPoint < concernedTurningPoints.Count; i_currCheckedTurningPoint++) + { + if (concernedTurningPoints[i_currCheckedTurningPoint].isTheEndOfAPlateau) + { + concernedTurningPoints[i_currCheckedTurningPoint].isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight = false; + continue; + } + else + { + concernedTurningPoints[i_currCheckedTurningPoint].isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight = true; + } + + for (int i_currLowerComparedTurningPoint = 0; i_currLowerComparedTurningPoint < i_currCheckedTurningPoint; i_currLowerComparedTurningPoint++) + { + if (concernedTurningPoints[i_currLowerComparedTurningPoint].isTheEndOfAPlateau) + { + continue; + } + else + { + float y_ofCurrCheckedTurningPoint = concernedTurningPoints[i_currCheckedTurningPoint].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position; + float y_ofCurrLowerComparedTurningPoint = concernedTurningPoints[i_currLowerComparedTurningPoint].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position; + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(y_ofCurrCheckedTurningPoint, y_ofCurrLowerComparedTurningPoint)) + { + float x_ofCurrCheckedTurningPoint = concernedTurningPoints[i_currCheckedTurningPoint].pointOfInterest_thatRepresentsThisTurningPoint.xValue.position; + float x_ofCurrLowerComparedTurningPoint = concernedTurningPoints[i_currLowerComparedTurningPoint].pointOfInterest_thatRepresentsThisTurningPoint.xValue.position; + if (x_ofCurrCheckedTurningPoint > x_ofCurrLowerComparedTurningPoint) + { + concernedTurningPoints[i_currLowerComparedTurningPoint].isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight = false; + } + else + { + concernedTurningPoints[i_currCheckedTurningPoint].isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight = false; + break; + } + } + } + } + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPointDetector.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPointDetector.cs.meta new file mode 100644 index 0000000..d55cdec --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/InternalDXXL_TurningPointDetector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7190062bd9564f4eb7527ea9c08d402 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartDrawing.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartDrawing.cs new file mode 100644 index 0000000..a2751ed --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartDrawing.cs @@ -0,0 +1,1399 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_ChartDrawing + { + public delegate float FlexibleGetYValueFromCollection(T yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject); + + + /// Lists: + /// ------- + /// ------- + /// ------- + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfFloats_preAllocated = GetYValueFrom_listOfFloats; + static float GetYValueFrom_listOfFloats(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue]; + } + + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfInts_preAllocated = GetYValueFrom_listOfInts; + static float GetYValueFrom_listOfInts(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return (float)yValues[i_slotWhereToObtainTheValue]; + } + + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfVector2s_xComponent_preAllocated = GetYValueFrom_listOfVector2s_xComponent; + static float GetYValueFrom_listOfVector2s_xComponent(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].x; + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfVector2s_yComponent_preAllocated = GetYValueFrom_listOfVector2s_yComponent; + static float GetYValueFrom_listOfVector2s_yComponent(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].y; + } + + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfVector3s_xComponent_preAllocated = GetYValueFrom_listOfVector3s_xComponent; + static float GetYValueFrom_listOfVector3s_xComponent(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].x; + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfVector3s_yComponent_preAllocated = GetYValueFrom_listOfVector3s_yComponent; + static float GetYValueFrom_listOfVector3s_yComponent(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].y; + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfVector3s_zComponent_preAllocated = GetYValueFrom_listOfVector3s_zComponent; + static float GetYValueFrom_listOfVector3s_zComponent(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].z; + } + + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfQuaternions_eulerXComponent_preAllocated = GetYValueFrom_listOfQuaternions_eulerXComponent; + static float GetYValueFrom_listOfQuaternions_eulerXComponent(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.x; + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfQuaternions_eulerYComponent_preAllocated = GetYValueFrom_listOfQuaternions_eulerYComponent; + static float GetYValueFrom_listOfQuaternions_eulerYComponent(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.y; + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfQuaternions_eulerZComponent_preAllocated = GetYValueFrom_listOfQuaternions_eulerZComponent; + static float GetYValueFrom_listOfQuaternions_eulerZComponent(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.z; + } + + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfBools_preAllocated = GetYValueFrom_listOfBools; + static float GetYValueFrom_listOfBools(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + if (yValues[i_slotWhereToObtainTheValue] == true) + { + return 1.0f; + } + else + { + return 0.0f; + } + } + + + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_localPosition_x_preAllocated = GetYValueFrom_listOfGameobjects_localPosition_x; + static float GetYValueFrom_listOfGameobjects_localPosition_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localPosition.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_localPosition_y_preAllocated = GetYValueFrom_listOfGameobjects_localPosition_y; + static float GetYValueFrom_listOfGameobjects_localPosition_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localPosition.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_localPosition_z_preAllocated = GetYValueFrom_listOfGameobjects_localPosition_z; + static float GetYValueFrom_listOfGameobjects_localPosition_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localPosition.z; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_localEulerAngle_x_preAllocated = GetYValueFrom_listOfGameobjects_localEulerAngle_x; + static float GetYValueFrom_listOfGameobjects_localEulerAngle_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localEulerAngles.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_localEulerAngle_y_preAllocated = GetYValueFrom_listOfGameobjects_localEulerAngle_y; + static float GetYValueFrom_listOfGameobjects_localEulerAngle_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localEulerAngles.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_localEulerAngle_z_preAllocated = GetYValueFrom_listOfGameobjects_localEulerAngle_z; + static float GetYValueFrom_listOfGameobjects_localEulerAngle_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localEulerAngles.z; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_localScale_x_preAllocated = GetYValueFrom_listOfGameobjects_localScale_x; + static float GetYValueFrom_listOfGameobjects_localScale_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localScale.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_localScale_y_preAllocated = GetYValueFrom_listOfGameobjects_localScale_y; + static float GetYValueFrom_listOfGameobjects_localScale_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localScale.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_localScale_z_preAllocated = GetYValueFrom_listOfGameobjects_localScale_z; + static float GetYValueFrom_listOfGameobjects_localScale_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localScale.z; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_globalPosition_x_preAllocated = GetYValueFrom_listOfGameobjects_globalPosition_x; + static float GetYValueFrom_listOfGameobjects_globalPosition_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.position.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_globalPosition_y_preAllocated = GetYValueFrom_listOfGameobjects_globalPosition_y; + static float GetYValueFrom_listOfGameobjects_globalPosition_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.position.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_globalPosition_z_preAllocated = GetYValueFrom_listOfGameobjects_globalPosition_z; + static float GetYValueFrom_listOfGameobjects_globalPosition_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.position.z; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_globalEulerAngle_x_preAllocated = GetYValueFrom_listOfGameobjects_globalEulerAngle_x; + static float GetYValueFrom_listOfGameobjects_globalEulerAngle_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.eulerAngles.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_globalEulerAngle_y_preAllocated = GetYValueFrom_listOfGameobjects_globalEulerAngle_y; + static float GetYValueFrom_listOfGameobjects_globalEulerAngle_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.eulerAngles.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_globalEulerAngle_z_preAllocated = GetYValueFrom_listOfGameobjects_globalEulerAngle_z; + static float GetYValueFrom_listOfGameobjects_globalEulerAngle_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.eulerAngles.z; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_lossyScale_x_preAllocated = GetYValueFrom_listOfGameobjects_lossyScale_x; + static float GetYValueFrom_listOfGameobjects_lossyScale_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.lossyScale.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_lossyScale_y_preAllocated = GetYValueFrom_listOfGameobjects_lossyScale_y; + static float GetYValueFrom_listOfGameobjects_lossyScale_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.lossyScale.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfGameobjects_lossyScale_z_preAllocated = GetYValueFrom_listOfGameobjects_lossyScale_z; + static float GetYValueFrom_listOfGameobjects_lossyScale_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.lossyScale.z; + } + } + + + + + + + + + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_localPosition_x_preAllocated = GetYValueFrom_listOfTransforms_localPosition_x; + static float GetYValueFrom_listOfTransforms_localPosition_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localPosition.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_localPosition_y_preAllocated = GetYValueFrom_listOfTransforms_localPosition_y; + static float GetYValueFrom_listOfTransforms_localPosition_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localPosition.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_localPosition_z_preAllocated = GetYValueFrom_listOfTransforms_localPosition_z; + static float GetYValueFrom_listOfTransforms_localPosition_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localPosition.z; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_localEulerAngle_x_preAllocated = GetYValueFrom_listOfTransforms_localEulerAngle_x; + static float GetYValueFrom_listOfTransforms_localEulerAngle_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localEulerAngles.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_localEulerAngle_y_preAllocated = GetYValueFrom_listOfTransforms_localEulerAngle_y; + static float GetYValueFrom_listOfTransforms_localEulerAngle_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localEulerAngles.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_localEulerAngle_z_preAllocated = GetYValueFrom_listOfTransforms_localEulerAngle_z; + static float GetYValueFrom_listOfTransforms_localEulerAngle_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localEulerAngles.z; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_localScale_x_preAllocated = GetYValueFrom_listOfTransforms_localScale_x; + static float GetYValueFrom_listOfTransforms_localScale_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localScale.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_localScale_y_preAllocated = GetYValueFrom_listOfTransforms_localScale_y; + static float GetYValueFrom_listOfTransforms_localScale_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localScale.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_localScale_z_preAllocated = GetYValueFrom_listOfTransforms_localScale_z; + static float GetYValueFrom_listOfTransforms_localScale_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localScale.z; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_globalPosition_x_preAllocated = GetYValueFrom_listOfTransforms_globalPosition_x; + static float GetYValueFrom_listOfTransforms_globalPosition_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].position.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_globalPosition_y_preAllocated = GetYValueFrom_listOfTransforms_globalPosition_y; + static float GetYValueFrom_listOfTransforms_globalPosition_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].position.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_globalPosition_z_preAllocated = GetYValueFrom_listOfTransforms_globalPosition_z; + static float GetYValueFrom_listOfTransforms_globalPosition_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].position.z; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_globalEulerAngle_x_preAllocated = GetYValueFrom_listOfTransforms_globalEulerAngle_x; + static float GetYValueFrom_listOfTransforms_globalEulerAngle_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_globalEulerAngle_y_preAllocated = GetYValueFrom_listOfTransforms_globalEulerAngle_y; + static float GetYValueFrom_listOfTransforms_globalEulerAngle_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_globalEulerAngle_z_preAllocated = GetYValueFrom_listOfTransforms_globalEulerAngle_z; + static float GetYValueFrom_listOfTransforms_globalEulerAngle_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.z; + } + } + + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_lossyScale_x_preAllocated = GetYValueFrom_listOfTransforms_lossyScale_x; + static float GetYValueFrom_listOfTransforms_lossyScale_x(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].lossyScale.x; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_lossyScale_y_preAllocated = GetYValueFrom_listOfTransforms_lossyScale_y; + static float GetYValueFrom_listOfTransforms_lossyScale_y(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].lossyScale.y; + } + } + public static FlexibleGetYValueFromCollection> GetYValueFrom_listOfTransforms_lossyScale_z_preAllocated = GetYValueFrom_listOfTransforms_lossyScale_z; + static float GetYValueFrom_listOfTransforms_lossyScale_z(List yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].lossyScale.z; + } + } + + + /// Arrays: + /// ------- + /// ------- + /// ------- + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfFloats_preAllocated = GetYValueFrom_arrayOfFloats; + static float GetYValueFrom_arrayOfFloats(float[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue]; + } + + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfInts_preAllocated = GetYValueFrom_arrayOfInts; + static float GetYValueFrom_arrayOfInts(int[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return (float)yValues[i_slotWhereToObtainTheValue]; + } + + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfVector2s_xComponent_preAllocated = GetYValueFrom_arrayOfVector2s_xComponent; + static float GetYValueFrom_arrayOfVector2s_xComponent(Vector2[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].x; + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfVector2s_yComponent_preAllocated = GetYValueFrom_arrayOfVector2s_yComponent; + static float GetYValueFrom_arrayOfVector2s_yComponent(Vector2[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].y; + } + + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfVector3s_xComponent_preAllocated = GetYValueFrom_arrayOfVector3s_xComponent; + static float GetYValueFrom_arrayOfVector3s_xComponent(Vector3[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].x; + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfVector3s_yComponent_preAllocated = GetYValueFrom_arrayOfVector3s_yComponent; + static float GetYValueFrom_arrayOfVector3s_yComponent(Vector3[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].y; + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfVector3s_zComponent_preAllocated = GetYValueFrom_arrayOfVector3s_zComponent; + static float GetYValueFrom_arrayOfVector3s_zComponent(Vector3[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].z; + } + + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfQuaternions_eulerXComponent_preAllocated = GetYValueFrom_arrayOfQuaternions_eulerXComponent; + static float GetYValueFrom_arrayOfQuaternions_eulerXComponent(Quaternion[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.x; + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfQuaternions_eulerYComponent_preAllocated = GetYValueFrom_arrayOfQuaternions_eulerYComponent; + static float GetYValueFrom_arrayOfQuaternions_eulerYComponent(Quaternion[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.y; + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfQuaternions_eulerZComponent_preAllocated = GetYValueFrom_arrayOfQuaternions_eulerZComponent; + static float GetYValueFrom_arrayOfQuaternions_eulerZComponent(Quaternion[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.z; + } + + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfBools_preAllocated = GetYValueFrom_arrayOfBools; + static float GetYValueFrom_arrayOfBools(bool[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = null; + if (yValues[i_slotWhereToObtainTheValue] == true) + { + return 1.0f; + } + else + { + return 0.0f; + } + } + + + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_localPosition_x_preAllocated = GetYValueFrom_arrayOfGameobjects_localPosition_x; + static float GetYValueFrom_arrayOfGameobjects_localPosition_x(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localPosition.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_localPosition_y_preAllocated = GetYValueFrom_arrayOfGameobjects_localPosition_y; + static float GetYValueFrom_arrayOfGameobjects_localPosition_y(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localPosition.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_localPosition_z_preAllocated = GetYValueFrom_arrayOfGameobjects_localPosition_z; + static float GetYValueFrom_arrayOfGameobjects_localPosition_z(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localPosition.z; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_localEulerAngle_x_preAllocated = GetYValueFrom_arrayOfGameobjects_localEulerAngle_x; + static float GetYValueFrom_arrayOfGameobjects_localEulerAngle_x(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localEulerAngles.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_localEulerAngle_y_preAllocated = GetYValueFrom_arrayOfGameobjects_localEulerAngle_y; + static float GetYValueFrom_arrayOfGameobjects_localEulerAngle_y(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localEulerAngles.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_localEulerAngle_z_preAllocated = GetYValueFrom_arrayOfGameobjects_localEulerAngle_z; + static float GetYValueFrom_arrayOfGameobjects_localEulerAngle_z(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localEulerAngles.z; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_localScale_x_preAllocated = GetYValueFrom_arrayOfGameobjects_localScale_x; + static float GetYValueFrom_arrayOfGameobjects_localScale_x(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localScale.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_localScale_y_preAllocated = GetYValueFrom_arrayOfGameobjects_localScale_y; + static float GetYValueFrom_arrayOfGameobjects_localScale_y(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localScale.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_localScale_z_preAllocated = GetYValueFrom_arrayOfGameobjects_localScale_z; + static float GetYValueFrom_arrayOfGameobjects_localScale_z(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.localScale.z; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_globalPosition_x_preAllocated = GetYValueFrom_arrayOfGameobjects_globalPosition_x; + static float GetYValueFrom_arrayOfGameobjects_globalPosition_x(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.position.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_globalPosition_y_preAllocated = GetYValueFrom_arrayOfGameobjects_globalPosition_y; + static float GetYValueFrom_arrayOfGameobjects_globalPosition_y(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.position.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_globalPosition_z_preAllocated = GetYValueFrom_arrayOfGameobjects_globalPosition_z; + static float GetYValueFrom_arrayOfGameobjects_globalPosition_z(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.position.z; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_globalEulerAngle_x_preAllocated = GetYValueFrom_arrayOfGameobjects_globalEulerAngle_x; + static float GetYValueFrom_arrayOfGameobjects_globalEulerAngle_x(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.eulerAngles.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_globalEulerAngle_y_preAllocated = GetYValueFrom_arrayOfGameobjects_globalEulerAngle_y; + static float GetYValueFrom_arrayOfGameobjects_globalEulerAngle_y(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.eulerAngles.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_globalEulerAngle_z_preAllocated = GetYValueFrom_arrayOfGameobjects_globalEulerAngle_z; + static float GetYValueFrom_arrayOfGameobjects_globalEulerAngle_z(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.eulerAngles.z; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_lossyScale_x_preAllocated = GetYValueFrom_arrayOfGameobjects_lossyScale_x; + static float GetYValueFrom_arrayOfGameobjects_lossyScale_x(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.lossyScale.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_lossyScale_y_preAllocated = GetYValueFrom_arrayOfGameobjects_lossyScale_y; + static float GetYValueFrom_arrayOfGameobjects_lossyScale_y(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.lossyScale.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfGameobjects_lossyScale_z_preAllocated = GetYValueFrom_arrayOfGameobjects_lossyScale_z; + static float GetYValueFrom_arrayOfGameobjects_lossyScale_z(GameObject[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: GameObject is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue]; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].transform.lossyScale.z; + } + } + + + + + + + + + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_localPosition_x_preAllocated = GetYValueFrom_arrayOfTransforms_localPosition_x; + static float GetYValueFrom_arrayOfTransforms_localPosition_x(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localPosition.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_localPosition_y_preAllocated = GetYValueFrom_arrayOfTransforms_localPosition_y; + static float GetYValueFrom_arrayOfTransforms_localPosition_y(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localPosition.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_localPosition_z_preAllocated = GetYValueFrom_arrayOfTransforms_localPosition_z; + static float GetYValueFrom_arrayOfTransforms_localPosition_z(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localPosition (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localPosition.z; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_localEulerAngle_x_preAllocated = GetYValueFrom_arrayOfTransforms_localEulerAngle_x; + static float GetYValueFrom_arrayOfTransforms_localEulerAngle_x(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localEulerAngles.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_localEulerAngle_y_preAllocated = GetYValueFrom_arrayOfTransforms_localEulerAngle_y; + static float GetYValueFrom_arrayOfTransforms_localEulerAngle_y(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localEulerAngles.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_localEulerAngle_z_preAllocated = GetYValueFrom_arrayOfTransforms_localEulerAngle_z; + static float GetYValueFrom_arrayOfTransforms_localEulerAngle_z(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localEulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localEulerAngles.z; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_localScale_x_preAllocated = GetYValueFrom_arrayOfTransforms_localScale_x; + static float GetYValueFrom_arrayOfTransforms_localScale_x(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localScale.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_localScale_y_preAllocated = GetYValueFrom_arrayOfTransforms_localScale_y; + static float GetYValueFrom_arrayOfTransforms_localScale_y(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localScale.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_localScale_z_preAllocated = GetYValueFrom_arrayOfTransforms_localScale_z; + static float GetYValueFrom_arrayOfTransforms_localScale_z(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "localScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].localScale.z; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_globalPosition_x_preAllocated = GetYValueFrom_arrayOfTransforms_globalPosition_x; + static float GetYValueFrom_arrayOfTransforms_globalPosition_x(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].position.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_globalPosition_y_preAllocated = GetYValueFrom_arrayOfTransforms_globalPosition_y; + static float GetYValueFrom_arrayOfTransforms_globalPosition_y(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].position.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_globalPosition_z_preAllocated = GetYValueFrom_arrayOfTransforms_globalPosition_z; + static float GetYValueFrom_arrayOfTransforms_globalPosition_z(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)position (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].position.z; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_globalEulerAngle_x_preAllocated = GetYValueFrom_arrayOfTransforms_globalEulerAngle_x; + static float GetYValueFrom_arrayOfTransforms_globalEulerAngle_x(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_globalEulerAngle_y_preAllocated = GetYValueFrom_arrayOfTransforms_globalEulerAngle_y; + static float GetYValueFrom_arrayOfTransforms_globalEulerAngle_y(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_globalEulerAngle_z_preAllocated = GetYValueFrom_arrayOfTransforms_globalEulerAngle_z; + static float GetYValueFrom_arrayOfTransforms_globalEulerAngle_z(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "(global)eulerAngles (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].eulerAngles.z; + } + } + + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_lossyScale_x_preAllocated = GetYValueFrom_arrayOfTransforms_lossyScale_x; + static float GetYValueFrom_arrayOfTransforms_lossyScale_x(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].lossyScale.x; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_lossyScale_y_preAllocated = GetYValueFrom_arrayOfTransforms_lossyScale_y; + static float GetYValueFrom_arrayOfTransforms_lossyScale_y(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].lossyScale.y; + } + } + public static FlexibleGetYValueFromCollection GetYValueFrom_arrayOfTransforms_lossyScale_z_preAllocated = GetYValueFrom_arrayOfTransforms_lossyScale_z; + static float GetYValueFrom_arrayOfTransforms_lossyScale_z(Transform[] yValues, int i_slotWhereToObtainTheValue, out GameObject gameobjectThatIsTheSourceOfTheValues, out string lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject) + { + if (yValues[i_slotWhereToObtainTheValue] == null) + { + gameobjectThatIsTheSourceOfTheValues = null; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of: Transform is null)"; + return float.NaN; + } + else + { + gameobjectThatIsTheSourceOfTheValues = yValues[i_slotWhereToObtainTheValue].gameObject; + lineNameExtraInfoOfConcernedLine_ifValueSourceIsGameobject = "lossyScale (of " + gameobjectThatIsTheSourceOfTheValues.name + ")"; + return yValues[i_slotWhereToObtainTheValue].lossyScale.z; + } + } + + + ///Other: + public static void SetPosRotScaleOfChart_toScreenspace(ChartDrawing concernedChart, Camera targetCamera, bool chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, bool andApplyFixedRotationToInternalRotation) + { + concernedChart.Position_worldspace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, concernedChart.position_inCamViewportspace, false); + concernedChart.fixedRotation = targetCamera.transform.rotation; + concernedChart.rotationSource = ChartDrawing.RotationSource.userDefinedFixedRotation; + concernedChart.Height_inWorldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, InternalDXXL_BoundsCamViewportSpace.viewportCenter, true, concernedChart.Height_relToCamViewportHeight); + if (chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight) + { + concernedChart.Width_inWorldSpace = UtilitiesDXXL_Screenspace.HorizExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, InternalDXXL_BoundsCamViewportSpace.viewportCenter, true, concernedChart.Width_relToCamViewport); + } + else + { + concernedChart.Width_inWorldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, InternalDXXL_BoundsCamViewportSpace.viewportCenter, true, concernedChart.Width_relToCamViewport); + } + + if (andApplyFixedRotationToInternalRotation) + { + concernedChart.ApplyInternalRotation(); + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartDrawing.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartDrawing.cs.meta new file mode 100644 index 0000000..69b34d0 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartDrawing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a7bf68dbb34f7c041bb4f776bea9575f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartLine.cs b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartLine.cs new file mode 100644 index 0000000..a7f6b19 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartLine.cs @@ -0,0 +1,163 @@ +namespace DrawXXL +{ + public class UtilitiesDXXL_ChartLine + { + public delegate bool IsDrawnBecause_theSingleComponentOfMulticomponentData_thisLineRepresents_isEnabledChecker(DataComponentsThatAreDrawn dataComponentsThatAreDrawn); + + //Non-multiComponentData: + public static bool DoDrawBecauseLineDoesntRepresentMultiComponentData(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return true; + } + + //Vector2: + public static bool DrawIf_vector2_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.vector2_x; + } + public static bool DrawIf_vector2_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.vector2_y; + } + + //Vector3: + public static bool DrawIf_vector3_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.vector3_x; + } + public static bool DrawIf_vector3_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.vector3_y; + } + public static bool DrawIf_vector3_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.vector3_z; + } + + //Vector4: + public static bool DrawIf_vector4_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.vector4_x; + } + public static bool DrawIf_vector4_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.vector4_y; + } + public static bool DrawIf_vector4_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.vector4_z; + } + public static bool DrawIf_vector4_w_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.vector4_w; + } + + //Color: + public static bool DrawIf_color_r_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.color_r; + } + public static bool DrawIf_color_g_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.color_g; + } + public static bool DrawIf_color_b_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.color_b; + } + public static bool DrawIf_color_a_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.color_a; + } + + //Rotation: + public static bool DrawIf_rotation_eulerX_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.rotation_eulerX; + } + public static bool DrawIf_rotation_eulerY_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.rotation_eulerY; + } + public static bool DrawIf_rotation_eulerZ_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.rotation_eulerZ; + } + + //Transform: + public static bool DrawIf_localPosition_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.localPosition_x; + } + public static bool DrawIf_localPosition_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.localPosition_y; + } + public static bool DrawIf_localPosition_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.localPosition_z; + } + public static bool DrawIf_localEulerAngle_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.localEulerAngle_x; + } + public static bool DrawIf_localEulerAngle_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.localEulerAngle_y; + } + public static bool DrawIf_localEulerAngle_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.localEulerAngle_z; + } + public static bool DrawIf_localScale_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.localScale_x; + } + public static bool DrawIf_localScale_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.localScale_y; + } + public static bool DrawIf_localScale_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.localScale_z; + } + public static bool DrawIf_globalPosition_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.globalPosition_x; + } + public static bool DrawIf_globalPosition_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.globalPosition_y; + } + public static bool DrawIf_globalPosition_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.globalPosition_z; + } + public static bool DrawIf_globalEulerAngle_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.globalEulerAngle_x; + } + public static bool DrawIf_globalEulerAngle_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.globalEulerAngle_y; + } + public static bool DrawIf_globalEulerAngle_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.globalEulerAngle_z; + } + public static bool DrawIf_lossyScale_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.lossyScale_x; + } + public static bool DrawIf_lossyScale_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.lossyScale_y; + } + public static bool DrawIf_lossyScale_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn) + { + return dataComponentsThatAreDrawn.lossyScale_z; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartLine.cs.meta b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartLine.cs.meta new file mode 100644 index 0000000..94723e6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/line charts/internal utilities/UtilitiesDXXL_ChartLine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c62dec88fec09a3458a145bf8261f5c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/pie charts.meta b/Runtime/DrawDebugLibrary/charts/pie charts.meta new file mode 100644 index 0000000..0e24d45 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/pie charts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c35c0bee2a8b75c4d88f55da8ac32278 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/pie charts/PieChartDrawing.cs b/Runtime/DrawDebugLibrary/charts/pie charts/PieChartDrawing.cs new file mode 100644 index 0000000..c78ebdc --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/pie charts/PieChartDrawing.cs @@ -0,0 +1,932 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class PieChartDrawing + { + public enum RotationSource + { + screen, + screen_butVerticalInWorldSpace, + userDefinedFixedRotation + } + public RotationSource rotationSource = RotationSource.screen; + + public int internal_indexNumberOfPremadeChart = -1; //-> this is used internally for the automatic layout of the premade chart, whose position hasn't been explicitly set by the user. + private Vector3 position_worldspace = Vector3.zero; + public Vector3 Position_worldspace + { + get + { + if (internal_indexNumberOfPremadeChart == (-1)) + { + return position_worldspace; + } + else + { + return DrawCharts.GetAutoLayoutedPositionOfPremadePieChart(this); + } + } + set + { + position_worldspace = value; + internal_indexNumberOfPremadeChart = -1; //-> if a user sets the position, then the chart is not affected anymore by the automatic layouting of the premade charts. + } + } + + public Quaternion fixedRotation = Quaternion.identity; + public Quaternion internalRotation = Quaternion.identity; //This is the internally used rotation. The user should use "fixedRotation" instead. "fixedRotation" does nothing but getting filled into this before drawing if "rotationSource=userDefinedFixedRotation" + private float size_ofPieCircleDiameter = 1.0f; + public float Size_ofPieCircleDiameter + { + get { return size_ofPieCircleDiameter; } + set { size_ofPieCircleDiameter = Mathf.Clamp(value, 0.001f, 100000.0f); } + } + + public Vector2 position_inCamViewportspace = new Vector2(0.41f, 0.41f); + private float size_ofPieCircleDiameter_relToCamViewport = 0.45f; + public float Size_ofPieCircleDiameter_relToCamViewport + { + get { return size_ofPieCircleDiameter_relToCamViewport; } + set { size_ofPieCircleDiameter_relToCamViewport = Mathf.Clamp(value, 0.01f, 2.0f); } + } + + private Vector3 right_normalized; + public Vector3 Right_normalized + { + get { return right_normalized; } + set { Debug.LogError("Setting 'Right_normalized' directly is not supported. Use 'rotationSource' and 'fixedRotation' instead."); } + } + + private Vector3 up_normalized; + public Vector3 Up_normalized + { + get { return up_normalized; } + set { Debug.LogError("Setting 'Up_normalized' directly is not supported. Use 'rotationSource' and 'fixedRotation' instead."); } + } + + private Vector3 forward_normalized; + public Vector3 Forward_normalized + { + get { return forward_normalized; } + set { Debug.LogError("Setting 'Forward_normalized' directly is not supported. Use 'rotationSource' and 'fixedRotation' instead."); } + } + + public float mostRecent_vertDistance_fromCircleCenter_toUpperBounderySquare = 0.0f; + + public enum SegmentSorting + { + decreasingSize_clockwise, + decreasingSize_counterClockwise, + creationOrder_clockwise, + creationOrder_counterClockwise + } + public SegmentSorting segmentSorting = SegmentSorting.decreasingSize_clockwise; + public float angleDegCCfromUp_whereMainSegmentStarts = 0.0f; + private string title; + private string title_insideMarkup; + public string Title + { + get { return title; } + set + { + title = value; + title_insideMarkup = "" + title + ""; + } + } + public string subTitle; + static float default_luminanceOfSegmentColors = 0.5f; + private float luminanceOfSegmentColors = default_luminanceOfSegmentColors; + public float LuminanceOfSegmentColors + { + get { return luminanceOfSegmentColors; } + set + { + value = Mathf.Clamp01(value); + ReassignLuminanceToSegmentColors(luminanceOfSegmentColors, value); + luminanceOfSegmentColors = value; + } + } + + public Color color = DrawBasics.defaultColor; + private float relSize_ofSegmentsNameTexts = 1.0f; + public float RelSize_ofSegmentsNameTexts + { + get { return relSize_ofSegmentsNameTexts; } + set { relSize_ofSegmentsNameTexts = Mathf.Clamp(value, 0.01f, 10.0f); } + } + + public int postDecimalPositions_ofPercentageDisplay = 1; + + public bool trackNegativeValues = false; //The pie chart cannot display negative values. Though it is possible that the value of a segment ends up in the negative area, e.g. by adding negative values via "AddValue()" or frequent calling of "DecrementValue()". The chart will not display segments with negative values, but it can keep track of negative values. Example: The "DecrementValue()" function is called five times on a segment. So the value is at "-5". If "trackNegativeValues" is true, then it needs 6 calls of "IncrementValue()" for the segment value to reach "1" (the first value where it can be displayed again in the chart). If "trackNegativeValues" is set to "false" then all negative values are discarded and it needs only one call of "IncrementValue" to reach the segment value of "1". + private float percentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection = 1.0f; + public float PercentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection + { + get { return percentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection; } + set { percentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection = Mathf.Clamp(value, 0.01f, 99.0f); } + } + + List segments_inCreationOrder = new List(); + List segments_orderedForDrawing = new List(); + List segments_orderedWithDecreasingSize = new List(); + List angleSpans_thatAreAlreadyCoveredWithText = new List(); + PieChartSegment combinedOthersSegment; + + public bool mentionZeroSegmentsInLegend = true; //This determines if empty segments with value of 0 are displayed in the text legend column on the right side of the chart. + public bool showSegmentNames = true; + public bool showSegmentValues = true; + public bool showSegmentPercentages = true; + public bool autoFlipAllText_toFitObsererCamera = true; + + public PieChartDrawing(string title = null) + { + Title = title; + combinedOthersSegment = new PieChartSegment("Others", this, 1000000); + combinedOthersSegment.color = SeededColorGenerator.ForceApproxLuminance(Color.gray, default_luminanceOfSegmentColors); + } + + public void Draw(float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingPieChart = this; + + ApplyInternalRotation(); // <-"DXXLWrapperForUntiyDebugDraw.CheckIfDrawingIsCurrentlySkipped" uses the here applied rotation already in it's fallback + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + float sum_ofAllNonNegativeSegments = Get_sum_ofAllNonNegativeSegments(); + bool sum_ofAllNonNegativeSegments_isZero = UtilitiesDXXL_Math.ApproximatelyZero(sum_ofAllNonNegativeSegments); + TryDrawNotificationForEmptyChart(sum_ofAllNonNegativeSegments_isZero, durationInSec, hiddenByNearerObjects); + bool mentionOthersSection_inRightTextColumn = RecalcSegmentsDrawProperties(sum_ofAllNonNegativeSegments); + if (sum_ofAllNonNegativeSegments_isZero == false) { SortSegmentsForDrawing(); } + float vertOffset_ofNextTextBlock_fromRightColumnsTop = DrawSegments(mentionOthersSection_inRightTextColumn, durationInSec, hiddenByNearerObjects); + + float size_ofPieCircleRadius = 0.5f * size_ofPieCircleDiameter; + float distance_circleCenter_toLeftBorder = size_ofPieCircleRadius + size_ofPieCircleRadius * 1.0f * relSize_ofSegmentsNameTexts; + float distance_circleCenter_toRightBorder = size_ofPieCircleRadius + size_ofPieCircleRadius * 2.25f * relSize_ofSegmentsNameTexts; + float distance_circleCenter_toLowEndOfTitleTexts = size_ofPieCircleRadius + size_ofPieCircleRadius * 0.65f * relSize_ofSegmentsNameTexts; + float vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText = distance_circleCenter_toLowEndOfTitleTexts; + mostRecent_vertDistance_fromCircleCenter_toUpperBounderySquare = TryDrawChartTitles(distance_circleCenter_toLeftBorder, distance_circleCenter_toRightBorder, vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText, durationInSec, hiddenByNearerObjects); + DrawBoundarySquare(vertOffset_ofNextTextBlock_fromRightColumnsTop, distance_circleCenter_toLowEndOfTitleTexts, distance_circleCenter_toLeftBorder, distance_circleCenter_toRightBorder, size_ofPieCircleRadius, durationInSec, hiddenByNearerObjects); + DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingPieChart = null; + } + + public void DrawScreenspace(bool chartSize_isDefinedRelTo_cameraWidth_notCameraHeight = false, float durationInSec = 0.0f) + { + if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "PieChartDrawing.DrawScreenspace") == false) { return; } + DrawScreenspace(automaticallyFoundCamera, chartSize_isDefinedRelTo_cameraWidth_notCameraHeight, durationInSec); + } + + public void DrawScreenspace(Camera targetCamera, bool chartSize_isDefinedRelTo_cameraWidth_notCameraHeight = false, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_DrawScreenspacePieChart.Add(new DrawScreenspacePieChart(targetCamera, chartSize_isDefinedRelTo_cameraWidth_notCameraHeight , durationInSec, this)); + return; + } + + Vector3 chartPosition_beforeScreenspaceDrawing = Position_worldspace; + Quaternion fixedChartRotation_beforeScreenspaceDrawing = fixedRotation; + float size_ofPieCircleDiameter_beforeScreenspaceDrawing = size_ofPieCircleDiameter; + RotationSource rotationSource_beforeScreenspaceDrawing = rotationSource; + autoFlipAllText_toFitObsererCamera = false; + + try + { + Position_worldspace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, position_inCamViewportspace, false); + fixedRotation = targetCamera.transform.rotation; + rotationSource = RotationSource.userDefinedFixedRotation; + if (chartSize_isDefinedRelTo_cameraWidth_notCameraHeight) + { + size_ofPieCircleDiameter = UtilitiesDXXL_Screenspace.HorizExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, InternalDXXL_BoundsCamViewportSpace.viewportCenter, true, size_ofPieCircleDiameter_relToCamViewport); + } + else + { + size_ofPieCircleDiameter = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, InternalDXXL_BoundsCamViewportSpace.viewportCenter, true, size_ofPieCircleDiameter_relToCamViewport); + } + Draw(durationInSec, false); + } + catch { } + + Position_worldspace = chartPosition_beforeScreenspaceDrawing; + fixedRotation = fixedChartRotation_beforeScreenspaceDrawing; + size_ofPieCircleDiameter = size_ofPieCircleDiameter_beforeScreenspaceDrawing; + rotationSource = rotationSource_beforeScreenspaceDrawing; + autoFlipAllText_toFitObsererCamera = true; + } + + void ApplyInternalRotation() + { + Vector3 observerCamForward_normalized; + Vector3 observerCamUp_normalized; + Vector3 observerCamRight_normalized; + Vector3 cam_to_lineCenter; + + switch (rotationSource) + { + case RotationSource.screen: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, Position_worldspace, Vector3.zero, null); + internalRotation = Quaternion.LookRotation(observerCamForward_normalized, observerCamUp_normalized); + break; + case RotationSource.screen_butVerticalInWorldSpace: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, Position_worldspace, Vector3.zero, null); + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.GetUpAndTextDir_withoutCallerSpecifiedPreference_independentFromTooShortLineDir_alignedVertical(out Vector3 chartUp_normalized, out Vector3 chartRight_normalized, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + Vector3 chartForward_normalized = Vector3.Cross(chartRight_normalized, chartUp_normalized); + internalRotation = Quaternion.LookRotation(chartForward_normalized, chartUp_normalized); + break; + case RotationSource.userDefinedFixedRotation: + internalRotation = fixedRotation; + break; + default: + internalRotation = fixedRotation; + Debug.LogError("rotationSource of '" + rotationSource + "' not implemented."); + break; + } + + right_normalized = internalRotation * Vector3.right; + up_normalized = internalRotation * Vector3.up; + forward_normalized = internalRotation * Vector3.forward; + } + + float Get_sum_ofAllNonNegativeSegments() + { + float sum_ofAllNonNegativeSegments = 0.0f; + for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++) + { + if (segments_inCreationOrder[i_segment].ValueAsFloat > 0.0f) + { + sum_ofAllNonNegativeSegments = sum_ofAllNonNegativeSegments + segments_inCreationOrder[i_segment].ValueAsFloat; + } + } + return sum_ofAllNonNegativeSegments; + } + + void TryDrawNotificationForEmptyChart(bool sum_ofAllNonNegativeSegments_isZero, float durationInSec, bool hiddenByNearerObjects) + { + if (sum_ofAllNonNegativeSegments_isZero) + { + float autoLineBreakWidth_ofNoNonZeroSegmentsText = 1.8f * size_ofPieCircleDiameter; + float size_ofNoNonZeroSegmentsText = 0.057f * size_ofPieCircleDiameter; + UtilitiesDXXL_Text.Write("
This pie chart doesn't contain
any segment with a value bigger
than 0.
", Position_worldspace, color, size_ofNoNonZeroSegmentsText, right_normalized, up_normalized, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth_ofNoNonZeroSegmentsText, autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + + bool RecalcSegmentsDrawProperties(float sum_ofAllNonNegativeSegments) + { + for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++) + { + segments_inCreationOrder[i_segment].CalcPercentage(sum_ofAllNonNegativeSegments); + } + + int numberOfSegments_inCombinedOthersSection = 0; + int numberOfNonZeroSegments_inCombinedOthersSection = 0; + for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++) + { + if (segments_inCreationOrder[i_segment].isTooSmallToBeDrawn) + { + numberOfSegments_inCombinedOthersSection++; + if (segments_inCreationOrder[i_segment].ValueAsFloat > 0.0f) + { + numberOfNonZeroSegments_inCombinedOthersSection++; + } + } + } + + combinedOthersSegment.SetValue(0.0f); + combinedOthersSegment.isTooSmallToBeDrawn = true; + bool mentionOthersSection_inRightTextColumn; + + if (numberOfSegments_inCombinedOthersSection <= 1) + { + mentionOthersSection_inRightTextColumn = false; + for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++) + { + segments_inCreationOrder[i_segment].textInRightColumn_shouldBeInsideTheOthersSection = false; + if (segments_inCreationOrder[i_segment].angleDeg_insidePie > 0.0f) + { + segments_inCreationOrder[i_segment].isTooSmallToBeDrawn = false; + } + } + } + else + { + //-> "othersSection" contains at least two other segments + //-> (but all these contained segments may be 0) + + for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++) + { + if (segments_inCreationOrder[i_segment].isTooSmallToBeDrawn) + { + if (segments_inCreationOrder[i_segment].ValueAsFloat > 0.0f) + { + combinedOthersSegment.AddValue(segments_inCreationOrder[i_segment].ValueAsFloat); + } + } + } + + combinedOthersSegment.CalcPercentage(sum_ofAllNonNegativeSegments); + if (combinedOthersSegment.angleDeg_insidePie > 0.0f) + { + combinedOthersSegment.isTooSmallToBeDrawn = false; //-> this overwrites "percentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection" + mentionOthersSection_inRightTextColumn = true; + } + else + { + if (mentionZeroSegmentsInLegend) + { + mentionOthersSection_inRightTextColumn = true; + } + else + { + mentionOthersSection_inRightTextColumn = false; + } + } + + if (mentionZeroSegmentsInLegend) + { + combinedOthersSegment.name = "" + numberOfSegments_inCombinedOthersSection + " Others"; + } + else + { + combinedOthersSegment.name = "" + numberOfNonZeroSegments_inCombinedOthersSection + " Others"; + } + } + + return mentionOthersSection_inRightTextColumn; + } + + float DrawSegments(bool mentionOthersSection_inRightTextColumn, float durationInSec, bool hiddenByNearerObjects) + { + //-> the order of calling of the following functions matters, because + // 1) The elements are z-fighting. Later calls are drawn on top of earlier calls. + // 2) The earlier calls fill class members inside "PieChartSegment" that are used by the later calls. + + Color color_ofLastDrawnSegment = TryDrawCircledLines(durationInSec, hiddenByNearerObjects); + TryDrawStraightSegmentBorderLines(color_ofLastDrawnSegment, durationInSec, hiddenByNearerObjects); + PrepareTextDrawing(); + TryDrawTextsBesideSegments(durationInSec, hiddenByNearerObjects); + float vertOffset_ofNextTextBlock_fromRightColumnsTop = TryDrawTextsInRightColumn(mentionOthersSection_inRightTextColumn, durationInSec, hiddenByNearerObjects); + return vertOffset_ofNextTextBlock_fromRightColumnsTop; + } + + Color TryDrawCircledLines(float durationInSec, bool hiddenByNearerObjects) + { + Color color_ofPrecedingSegment = default; + float startingAngleDegCCFromUp_ofCurrSegment = angleDegCCfromUp_whereMainSegmentStarts; + for (int i_segment = 0; i_segment < segments_orderedForDrawing.Count; i_segment++) + { + startingAngleDegCCFromUp_ofCurrSegment = segments_orderedForDrawing[i_segment].TryDrawCircledLines(startingAngleDegCCFromUp_ofCurrSegment, durationInSec, hiddenByNearerObjects); + if (segments_orderedForDrawing[i_segment].isTooSmallToBeDrawn == false) { color_ofPrecedingSegment = segments_orderedForDrawing[i_segment].color; } + } + combinedOthersSegment.TryDrawCircledLines(startingAngleDegCCFromUp_ofCurrSegment, durationInSec, hiddenByNearerObjects); + if (combinedOthersSegment.isTooSmallToBeDrawn == false) { color_ofPrecedingSegment = combinedOthersSegment.color; } + return color_ofPrecedingSegment; + } + + void TryDrawStraightSegmentBorderLines(Color color_ofLastDrawnSegment, float durationInSec, bool hiddenByNearerObjects) + { + Color color_ofPrecedingSegment = color_ofLastDrawnSegment; + for (int i_segment = 0; i_segment < segments_orderedForDrawing.Count; i_segment++) + { + segments_orderedForDrawing[i_segment].TryDrawStraightSegmentBorderLine(color_ofPrecedingSegment, durationInSec, hiddenByNearerObjects); + if (segments_orderedForDrawing[i_segment].isTooSmallToBeDrawn == false) { color_ofPrecedingSegment = segments_orderedForDrawing[i_segment].color; } + } + combinedOthersSegment.TryDrawStraightSegmentBorderLine(color_ofPrecedingSegment, durationInSec, hiddenByNearerObjects); + } + + void PrepareTextDrawing() + { + for (int i_segment = 0; i_segment < segments_orderedForDrawing.Count; i_segment++) + { + segments_orderedForDrawing[i_segment].PrepareTextDrawing(); + } + combinedOthersSegment.PrepareTextDrawing(); + } + + void TryDrawTextsBesideSegments(float durationInSec, bool hiddenByNearerObjects) + { + angleSpans_thatAreAlreadyCoveredWithText.Clear(); + for (int i_segment = 0; i_segment < segments_orderedWithDecreasingSize.Count; i_segment++) + { + if (segments_orderedWithDecreasingSize[i_segment].isTooSmallToBeDrawn) + { + segments_orderedWithDecreasingSize[i_segment].ReportThat_textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall(); + } + else + { + segments_orderedWithDecreasingSize[i_segment].TryDrawTextBesideSegment(durationInSec, hiddenByNearerObjects); + } + } + + if (combinedOthersSegment.ValueAsFloat > 0.0f) + { + combinedOthersSegment.TryDrawTextBesideSegment(durationInSec, hiddenByNearerObjects); + } + else + { + combinedOthersSegment.ReportThat_textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall(); + } + } + + float TryDrawTextsInRightColumn(bool mentionOthersSection_inRightTextColumn, float durationInSec, bool hiddenByNearerObjects) + { + float vertOffset_ofNextTextBlock_fromRightColumnsTop = 0.0f; + for (int i_segment = 0; i_segment < segments_orderedForDrawing.Count; i_segment++) + { + if (mentionOthersSection_inRightTextColumn == false) { segments_orderedForDrawing[i_segment].textInRightColumn_shouldBeInsideTheOthersSection = false; } //-> this is for the case where the othersSection would contain only 1 segment, and therefore this segment gets drawn instead of the otherSection. Without this it would not appear in the right column + vertOffset_ofNextTextBlock_fromRightColumnsTop = segments_orderedForDrawing[i_segment].TryDrawTextInRightColumnOutsideOthersSection(false, vertOffset_ofNextTextBlock_fromRightColumnsTop, durationInSec, hiddenByNearerObjects); + } + + if (mentionOthersSection_inRightTextColumn) + { + //-> others section contains at least two other segments + //-> at least one contained segment ist non-zero OR "mentionZeroSegmentsInLegend" is activated + + vertOffset_ofNextTextBlock_fromRightColumnsTop = combinedOthersSegment.TryDrawTextInRightColumnOutsideOthersSection(true, vertOffset_ofNextTextBlock_fromRightColumnsTop, durationInSec, hiddenByNearerObjects); + for (int i_segment = 0; i_segment < segments_orderedForDrawing.Count; i_segment++) + { + vertOffset_ofNextTextBlock_fromRightColumnsTop = segments_orderedForDrawing[i_segment].TryDrawTextInRightColumnInsideOthersSection(vertOffset_ofNextTextBlock_fromRightColumnsTop, combinedOthersSegment.color, durationInSec, hiddenByNearerObjects); + } + } + return vertOffset_ofNextTextBlock_fromRightColumnsTop; + } + + float TryDrawChartTitles(float distance_circleCenter_toLeftBorder, float distance_circleCenter_toRightBorder, float vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText, float durationInSec, bool hiddenByNearerObjects) + { + float widthOfBoundarySquare = distance_circleCenter_toLeftBorder + distance_circleCenter_toRightBorder; + float halfWidthOfBoundarySquare = 0.5f * widthOfBoundarySquare; + float autoLineBreakWidth = 0.9f * widthOfBoundarySquare; + + if (subTitle != null && subTitle != "") + { + float size_ofSubTitleText = 0.06f * size_ofPieCircleDiameter; + Vector3 lowCenterPos_ofNextTitleText = Position_worldspace + up_normalized * vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText + right_normalized * ((-distance_circleCenter_toLeftBorder) + halfWidthOfBoundarySquare); + UtilitiesDXXL_Text.Write(subTitle, lowCenterPos_ofNextTitleText, color, size_ofSubTitleText, right_normalized, up_normalized, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true); + vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText = vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText + (DrawText.parsedTextSpecs.height_wholeTextBlock + size_ofSubTitleText); + } + + if (title != null && title != "") + { + float size_ofTitleText = 0.18f * size_ofPieCircleDiameter; + Vector3 lowCenterPos_ofNextTitleText = Position_worldspace + up_normalized * vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText + right_normalized * ((-distance_circleCenter_toLeftBorder) + halfWidthOfBoundarySquare); + UtilitiesDXXL_Text.Write(title_insideMarkup, lowCenterPos_ofNextTitleText, color, size_ofTitleText, right_normalized, up_normalized, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true); + vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText = vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText + DrawText.parsedTextSpecs.height_wholeTextBlock; + } + + return vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText; + } + + void DrawBoundarySquare(float vertOffset_ofNextTextBlock_fromRightColumnsTop, float distance_circleCenter_toLowEndOfTitleTexts, float distance_circleCenter_toLeftBorder, float distance_circleCenter_toRightBorder, float size_ofPieCircleRadius, float durationInSec, bool hiddenByNearerObjects) + { + float offset_fromCircleCenter_toLowestPosOfRightColumn = Get_vertOffset_fromCircleCenter_toTopRightPosOfRightColumn() + vertOffset_ofNextTextBlock_fromRightColumnsTop; + float offset_fromCircleCenter_toLowestPosOfRightColumnInclOffset = offset_fromCircleCenter_toLowestPosOfRightColumn - size_ofPieCircleRadius * 0.25f * relSize_ofSegmentsNameTexts; + float minOffset_fromCircleCenter_toLowerBounderySquare = (-distance_circleCenter_toLowEndOfTitleTexts); //-> naming confusion: It contains "min", but the "min" would only be correct if the value would be an abs/positive value. Since this offset is always negative, it is actually the "max" value, but this would be an unintuitive name as well. + + Vector3 circleCenter_to_upperBorderOfBoundarySquare = up_normalized * mostRecent_vertDistance_fromCircleCenter_toUpperBounderySquare; + Vector3 circleCenter_to_lowerBorderOfBoundarySquare = up_normalized * Mathf.Min(minOffset_fromCircleCenter_toLowerBounderySquare, offset_fromCircleCenter_toLowestPosOfRightColumnInclOffset);//-> since the searched value is always a negative one this is actually looking for the "max-negative". + Vector3 circleCenter_to_leftBorderOfBoundarySquare = right_normalized * (-distance_circleCenter_toLeftBorder); + Vector3 circleCenter_to_rightBorderOfBoundarySquare = right_normalized * distance_circleCenter_toRightBorder; + + Vector3 topLeftCorner_ofBoundarySquare = Position_worldspace + circleCenter_to_upperBorderOfBoundarySquare + circleCenter_to_leftBorderOfBoundarySquare; + Vector3 topRightCorner_ofBoundarySquare = Position_worldspace + circleCenter_to_upperBorderOfBoundarySquare + circleCenter_to_rightBorderOfBoundarySquare; + Vector3 lowLeftCorner_ofBoundarySquare = Position_worldspace + circleCenter_to_lowerBorderOfBoundarySquare + circleCenter_to_leftBorderOfBoundarySquare; + Vector3 lowRightCorner_ofBoundarySquare = Position_worldspace + circleCenter_to_lowerBorderOfBoundarySquare + circleCenter_to_rightBorderOfBoundarySquare; + + Line_fadeableAnimSpeed.InternalDraw(topLeftCorner_ofBoundarySquare, topRightCorner_ofBoundarySquare, 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(topRightCorner_ofBoundarySquare, lowRightCorner_ofBoundarySquare, 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(lowRightCorner_ofBoundarySquare, lowLeftCorner_ofBoundarySquare, 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(lowLeftCorner_ofBoundarySquare, topLeftCorner_ofBoundarySquare, 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 void AddValue(string segmentName, float addedValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + GetSegment(segmentName, true).AddValue(addedValue); + } + } + + public void AddValue(string segmentName, int addedValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + GetSegment(segmentName, true).AddValue(addedValue); + } + } + + public void AddValueToAllSegments(float addedValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + for (int i = 0; i < segments_inCreationOrder.Count; i++) + { + segments_inCreationOrder[i].AddValue(addedValue); + } + } + } + + public void AddValueToAllSegments(int addedValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + for (int i = 0; i < segments_inCreationOrder.Count; i++) + { + segments_inCreationOrder[i].AddValue(addedValue); + } + } + } + + public void IncrementValue(string segmentName) + { + GetSegment(segmentName, true).AddValue(1); + } + + public void IncrementValuesOfAllSegments() + { + for (int i = 0; i < segments_inCreationOrder.Count; i++) + { + segments_inCreationOrder[i].AddValue(1); + } + } + + public void DecrementValue(string segmentName) + { + GetSegment(segmentName, true).AddValue(-1); + } + + public void DecrementValuesOfAllSegments() + { + for (int i = 0; i < segments_inCreationOrder.Count; i++) + { + segments_inCreationOrder[i].AddValue(-1); + } + } + + public void SetValue(string segmentName, float newValue) + { + GetSegment(segmentName, true).SetValue(newValue); + } + + public void SetValueOfAllSegments(float newValue) + { + for (int i = 0; i < segments_inCreationOrder.Count; i++) + { + segments_inCreationOrder[i].SetValue(newValue); + } + } + + public void SetValue(string segmentName, int newValue) + { + GetSegment(segmentName, true).SetValue(newValue); + } + + public void SetValueOfAllSegments(int newValue) + { + for (int i = 0; i < segments_inCreationOrder.Count; i++) + { + segments_inCreationOrder[i].SetValue(newValue); + } + } + + public void AddValues_eachIndexIsASegment(List valuesToAdd) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + for (int i = 0; i < valuesToAdd.Count; i++) + { + GetSegment("i=" + i, true).AddValue(valuesToAdd[i]); + } + } + } + + public void AddValues_eachIndexIsASegment(float[] valuesToAdd) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + for (int i = 0; i < valuesToAdd.Length; i++) + { + GetSegment("i=" + i, true).AddValue(valuesToAdd[i]); + } + } + } + + public void AddValues_eachIndexIsASegment(List valuesToAdd) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + for (int i = 0; i < valuesToAdd.Count; i++) + { + GetSegment("i=" + i, true).AddValue(valuesToAdd[i]); + } + } + } + + public void AddValues_eachIndexIsASegment(int[] valuesToAdd) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + for (int i = 0; i < valuesToAdd.Length; i++) + { + GetSegment("i=" + i, true).AddValue(valuesToAdd[i]); + } + } + } + + public void IncrementValues_eachIndexIsASegment(List incrementedListSlots) + { + for (int i = 0; i < incrementedListSlots.Count; i++) + { + if (incrementedListSlots[i] == true) + { + IncrementValue("i=" + i); + } + } + } + + public void IncrementValues_eachIndexIsASegment(bool[] incrementedArraySlots) + { + for (int i = 0; i < incrementedArraySlots.Length; i++) + { + if (incrementedArraySlots[i] == true) + { + IncrementValue("i=" + i); + } + } + } + + public void DecrementValues_eachIndexIsASegment(List decrementedListSlots) + { + for (int i = 0; i < decrementedListSlots.Count; i++) + { + if (decrementedListSlots[i] == true) + { + DecrementValue("i=" + i); + } + } + } + + public void DecrementValues_eachIndexIsASegment(bool[] decrementedArraySlots) + { + for (int i = 0; i < decrementedArraySlots.Length; i++) + { + if (decrementedArraySlots[i] == true) + { + DecrementValue("i=" + i); + } + } + } + + public void SetValues_eachIndexIsASegment(List valuesToSet) + { + for (int i = 0; i < valuesToSet.Count; i++) + { + GetSegment("i=" + i, true).SetValue(valuesToSet[i]); + } + } + + public void SetValues_eachIndexIsASegment(float[] valuesToSet) + { + for (int i = 0; i < valuesToSet.Length; i++) + { + GetSegment("i=" + i, true).SetValue(valuesToSet[i]); + } + } + + public void SetValues_eachIndexIsASegment(List valuesToSet) + { + for (int i = 0; i < valuesToSet.Count; i++) + { + GetSegment("i=" + i, true).SetValue(valuesToSet[i]); + } + } + + public void SetValues_eachIndexIsASegment(int[] valuesToSet) + { + for (int i = 0; i < valuesToSet.Length; i++) + { + GetSegment("i=" + i, true).SetValue(valuesToSet[i]); + } + } + + public void Clear() + { + segments_inCreationOrder.Clear(); + segments_orderedForDrawing.Clear(); + segments_orderedWithDecreasingSize.Clear(); + } + + public PieChartSegment GetSegment(string segmentName, bool createSegmentIfItDoesntExist) + { + if (segmentName == null || segmentName == "") + { + Debug.LogError("'GetSegment()' failed, because the requested 'segmentName' is null or empty."); + return null; + } + + for (int i = 0; i < segments_inCreationOrder.Count; i++) + { + if (segments_inCreationOrder[i].name != null) + { + if (segments_inCreationOrder[i].name == segmentName) + { + return segments_inCreationOrder[i]; + } + } + } + + //A segment with this name doesn't exist yet: + if (createSegmentIfItDoesntExist) + { + PieChartSegment newlyCreatedPieChartSegment = new PieChartSegment(segmentName, this, segments_inCreationOrder.Count); + segments_inCreationOrder.Add(newlyCreatedPieChartSegment); + segments_orderedForDrawing.Add(segments_inCreationOrder[segments_inCreationOrder.Count - 1]); + segments_orderedWithDecreasingSize.Add(segments_inCreationOrder[segments_inCreationOrder.Count - 1]); + TryReassignRainbowColorsToAllSegments(); + return segments_inCreationOrder[segments_inCreationOrder.Count - 1]; + } + else + { + return null; + } + } + + public bool OrderingIsClockwise() + { + return ((segmentSorting == SegmentSorting.creationOrder_clockwise) || (segmentSorting == SegmentSorting.decreasingSize_clockwise)); + } + + void SortSegmentsForDrawing() + { + segments_orderedWithDecreasingSize.Sort(BiggerValueLeadsToLowerIndex); + switch (segmentSorting) + { + case SegmentSorting.decreasingSize_clockwise: + segments_orderedForDrawing.Sort(BiggerValueLeadsToLowerIndex); + break; + case SegmentSorting.decreasingSize_counterClockwise: + segments_orderedForDrawing.Sort(BiggerValueLeadsToLowerIndex); + break; + case SegmentSorting.creationOrder_clockwise: + Fill_segments_fromListInCreationOrder_toListOrderedForDrawing(); + break; + case SegmentSorting.creationOrder_counterClockwise: + Fill_segments_fromListInCreationOrder_toListOrderedForDrawing(); + break; + default: + segments_orderedForDrawing.Sort(BiggerValueLeadsToLowerIndex); + Debug.LogError("segmentSorting of '" + segmentSorting + "' not implemented."); + break; + } + } + + int BiggerValueLeadsToLowerIndex(PieChartSegment segment1, PieChartSegment segment2) + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(segment1.ValueAsFloat, segment2.ValueAsFloat)) + { + //-> this prevents ongoing flickering change of the order of (zero) segments inside the right column + if (segment1.i_ofThisSegment_insideCreationOrderedList < segment2.i_ofThisSegment_insideCreationOrderedList) + { + return (-1); + } + else + { + return (1); + } + } + else + { + if (segment1.ValueAsFloat > segment2.ValueAsFloat) + { + return (-1); + } + else + { + return (1); + } + } + } + + void Fill_segments_fromListInCreationOrder_toListOrderedForDrawing() + { + for (int i = 0; i < segments_inCreationOrder.Count; i++) + { + segments_orderedForDrawing[i] = segments_inCreationOrder[i]; + } + } + + public bool CheckIfAngleForTextIsAlreadyCovered(float startAngleDegCCFromUp_ofText, float endAngleDegCCFromUp_ofText) + { + for (int i = 0; i < angleSpans_thatAreAlreadyCoveredWithText.Count; i++) + { + if (angleSpans_thatAreAlreadyCoveredWithText[i].DoesIntersect(startAngleDegCCFromUp_ofText, endAngleDegCCFromUp_ofText)) + { + return true; + } + } + return false; + } + + public void MarkAngleSpanAsCoveredWithText(float startAngleDegCCFromUp_ofText, float endAngleDegCCFromUp_ofText) + { + InternalDXXL_PieAngleSpan reservedAngleSpan = new InternalDXXL_PieAngleSpan(); + reservedAngleSpan.startAngleDegCCFromUp = startAngleDegCCFromUp_ofText; + reservedAngleSpan.endAngleDegCCFromUp = endAngleDegCCFromUp_ofText; + angleSpans_thatAreAlreadyCoveredWithText.Add(reservedAngleSpan); + + if (startAngleDegCCFromUp_ofText < 0.0f) + { + InternalDXXL_PieAngleSpan reservedAngleSpan_copy1 = new InternalDXXL_PieAngleSpan(); + reservedAngleSpan_copy1.startAngleDegCCFromUp = startAngleDegCCFromUp_ofText + 360.0f; + reservedAngleSpan_copy1.endAngleDegCCFromUp = endAngleDegCCFromUp_ofText + 360.0f; + angleSpans_thatAreAlreadyCoveredWithText.Add(reservedAngleSpan_copy1); + } + + if (endAngleDegCCFromUp_ofText > 360.0f) + { + InternalDXXL_PieAngleSpan reservedAngleSpan_copy2 = new InternalDXXL_PieAngleSpan(); + reservedAngleSpan_copy2.startAngleDegCCFromUp = startAngleDegCCFromUp_ofText - 360.0f; + reservedAngleSpan_copy2.endAngleDegCCFromUp = endAngleDegCCFromUp_ofText - 360.0f; + angleSpans_thatAreAlreadyCoveredWithText.Add(reservedAngleSpan_copy2); + } + } + + public float Get_vertOffset_fromCircleCenter_toTopRightPosOfRightColumn() + { + float size_ofPieCircleRadius = 0.5f * size_ofPieCircleDiameter; + return (size_ofPieCircleRadius + size_ofPieCircleRadius * 0.4f * relSize_ofSegmentsNameTexts); + } + + int numberOfSegments_inMomentOfLastAutomaticRainbowColorReassignment = 0; + int colorSeedFactor = 11; //if this is set to 1, then the segment colors are one continuous color spectrum pass from the first created segment to the last created segment. This may help to indicate the order in which the segments were created, but in the not-so-seldom-case where the segments size is also ordered (like "first creeated segment is biggest/smallest), then it gets harder to distinguish the color of the segments and associate them with the corresponding text display, since neighboring colors get more and more similar. Setting this "colorSeedFactor" value to something else than 1 "scatters" the color distribution, so that chances are higher that neighboring segments have a clearly different color. + void TryReassignRainbowColorsToAllSegments() + { + for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++) + { + bool isTheNewlyCreatedSegment = (i_segment == (segments_inCreationOrder.Count - 1)); + if (isTheNewlyCreatedSegment) + { + segments_inCreationOrder[i_segment].color = SeededColorGenerator.GetRainbowColor(i_segment * colorSeedFactor, 1.0f, segments_inCreationOrder.Count, luminanceOfSegmentColors); + } + else + { + Color expectedColorOfSegment_beforeCurrReassignment_ifColorWasAutogenerated = SeededColorGenerator.GetRainbowColor(i_segment * colorSeedFactor, 1.0f, numberOfSegments_inMomentOfLastAutomaticRainbowColorReassignment, luminanceOfSegmentColors); + bool colorWasManuallySetByUser = (UtilitiesDXXL_Colors.IsApproxSameColor(segments_inCreationOrder[i_segment].color, expectedColorOfSegment_beforeCurrReassignment_ifColorWasAutogenerated) == false); + if (colorWasManuallySetByUser == false) + { + segments_inCreationOrder[i_segment].color = SeededColorGenerator.GetRainbowColor(i_segment * colorSeedFactor, 1.0f, segments_inCreationOrder.Count, luminanceOfSegmentColors); + } + } + } + numberOfSegments_inMomentOfLastAutomaticRainbowColorReassignment = segments_inCreationOrder.Count; + } + + void ReassignLuminanceToSegmentColors(float oldLuminance, float newLuminance) + { + Color colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated; + Color colorToAssign_ifAutogenerated; + + for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++) + { + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetRainbowColor(i_segment * colorSeedFactor, 1.0f, numberOfSegments_inMomentOfLastAutomaticRainbowColorReassignment, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.GetRainbowColor(i_segment * colorSeedFactor, 1.0f, numberOfSegments_inMomentOfLastAutomaticRainbowColorReassignment, newLuminance); + ReassignLuminanceToSegmentColor(segments_inCreationOrder[i_segment], colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + } + + colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.ForceApproxLuminance(Color.gray, oldLuminance); + colorToAssign_ifAutogenerated = SeededColorGenerator.ForceApproxLuminance(Color.gray, newLuminance); + ReassignLuminanceToSegmentColor(combinedOthersSegment, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance); + } + + void ReassignLuminanceToSegmentColor(PieChartSegment concernedSegment, Color colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, Color colorToAssign_ifAutogenerated, float newLuminance) + { + bool colorWasAutogenerated = UtilitiesDXXL_Colors.IsApproxSameColor(concernedSegment.color, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated); + if (colorWasAutogenerated) + { + concernedSegment.color = colorToAssign_ifAutogenerated; + } + else + { + //color has been manually set by user: + if (UtilitiesDXXL_Math.ApproximatelyZero(concernedSegment.color.r) && UtilitiesDXXL_Math.ApproximatelyZero(concernedSegment.color.g) && UtilitiesDXXL_Math.ApproximatelyZero(concernedSegment.color.b)) + { + //-> black colors cannot be forced with luminance, therefore: slight lift, to make it grey, which can be forced: + concernedSegment.color = new Color(0.01f, 0.01f, 0.01f, concernedSegment.color.a); + } + concernedSegment.color = SeededColorGenerator.ForceApproxLuminance(concernedSegment.color, newLuminance); + } + } + + public void DrawWarningForMaxLinesPerFrame() + { + string warningText = "
Max lines exceeded
(see log)
"; + float size_ofMaxLinesText = 0.09f * size_ofPieCircleDiameter; + UtilitiesDXXL_Text.WriteFramed(warningText, Position_worldspace, color, size_ofMaxLinesText, internalRotation, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipAllText_toFitObsererCamera, 0.0f, false); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/pie charts/PieChartDrawing.cs.meta b/Runtime/DrawDebugLibrary/charts/pie charts/PieChartDrawing.cs.meta new file mode 100644 index 0000000..593f054 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/pie charts/PieChartDrawing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 78be5f93f1552be4db2592d6cdba0cb3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/pie charts/PieChartSegment.cs b/Runtime/DrawDebugLibrary/charts/pie charts/PieChartSegment.cs new file mode 100644 index 0000000..03e0f6a --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/pie charts/PieChartSegment.cs @@ -0,0 +1,409 @@ +namespace DrawXXL +{ + using UnityEngine; + public class PieChartSegment + { + private float valueAsFloat; + public float ValueAsFloat + { + get { return valueAsFloat; } + set { Debug.LogError("'" + name + ".ValueAsFloat' cannot be set directly. Use 'pieChart.SetValue(" + name + " , valueToSet)' instead"); } + } + + int valueAsInt; + float percentage_0to1; + public string name; + public Color color; + bool hasAtLeastBeenFilledOnceWithFloatInsteadOfInt = false; + PieChartDrawing chart_thisSegmentIsPartOf; + public bool isTooSmallToBeDrawn; + public float angleDeg_insidePie; + public int i_ofThisSegment_insideCreationOrderedList; + float radius_ofPieCircle; + float startingAngleDegCCFromUp; + float turnAngleDegCC; + Vector3 center_to_startPosOfThinOuterBorderLine; + string drawnText; + bool textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall; + public bool textInRightColumn_shouldBeInsideTheOthersSection; + float startAngleDegCCFromUp_ofTextBlock; + float endAngleDegCCFromUp_ofTextBlock; + Vector3 positionOfText; + float sizeOfText; + DrawText.TextAnchorDXXL textAnchor; + + public PieChartSegment(string name, PieChartDrawing parentChart, int i_ofThisSegment_insideCreationOrderedList) + { + this.name = name; + hasAtLeastBeenFilledOnceWithFloatInsteadOfInt = false; + chart_thisSegmentIsPartOf = parentChart; + this.i_ofThisSegment_insideCreationOrderedList = i_ofThisSegment_insideCreationOrderedList; + } + + public void AddValue(float addedValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + if (UtilitiesDXXL_Math.FloatIsValid(addedValue)) + { + hasAtLeastBeenFilledOnceWithFloatInsteadOfInt = true; + if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsFloat = Mathf.Max(valueAsFloat, 0.0f); } + valueAsFloat = valueAsFloat + addedValue; + if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsFloat = Mathf.Max(valueAsFloat, 0.0f); } + valueAsInt = Mathf.RoundToInt(valueAsFloat); + } + else + { + Debug.LogError("Add value to pie chart segment '" + name + "' failed, because added value is " + addedValue); + } + } + } + + public void AddValue(int addedValue) + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls + { + if (hasAtLeastBeenFilledOnceWithFloatInsteadOfInt) + { + AddValue((float)addedValue); + } + else + { + if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsInt = Mathf.Max(valueAsInt, 0); } + valueAsInt = valueAsInt + addedValue; + if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsInt = Mathf.Max(valueAsInt, 0); } + valueAsFloat = (float)valueAsInt; + } + } + } + + public void SetValue(float newValue) + { + if (UtilitiesDXXL_Math.FloatIsValid(newValue)) + { + hasAtLeastBeenFilledOnceWithFloatInsteadOfInt = true; + valueAsFloat = newValue; + if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsFloat = Mathf.Max(valueAsFloat, 0.0f); } + valueAsInt = Mathf.RoundToInt(newValue); + } + else + { + Debug.LogError("Set value of pie chart segment '" + name + "' failed, because new value is " + newValue); + } + } + + public void SetValue(int newValue) + { + hasAtLeastBeenFilledOnceWithFloatInsteadOfInt = false; + valueAsInt = newValue; + if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsInt = Mathf.Max(valueAsInt, 0); } + valueAsFloat = (float)newValue; + } + + public void CalcPercentage(float sum_ofAllNonNegativeSegments) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(sum_ofAllNonNegativeSegments)) + { + percentage_0to1 = 0.0f; + } + else + { + percentage_0to1 = valueAsFloat / sum_ofAllNonNegativeSegments; + } + isTooSmallToBeDrawn = ((100.0f * percentage_0to1) < chart_thisSegmentIsPartOf.PercentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection); + angleDeg_insidePie = 360.0f * percentage_0to1; + } + + public float TryDrawCircledLines(float startingAngleDegCCFromUp, float durationInSec, bool hiddenByNearerObjects) + { + this.startingAngleDegCCFromUp = startingAngleDegCCFromUp; + radius_ofPieCircle = 0.5f * chart_thisSegmentIsPartOf.Size_ofPieCircleDiameter; + + if (isTooSmallToBeDrawn == false) + { + float radius_ofBroadFillLine = radius_ofPieCircle * 0.55f; + float width_ofBroadFillLine = radius_ofPieCircle * 0.9f; + + Quaternion rotation_fromPieUp_to_segmentStart = Quaternion.AngleAxis(startingAngleDegCCFromUp, chart_thisSegmentIsPartOf.Forward_normalized); + Vector3 center_to_startPosOfBroadLine_normalized = rotation_fromPieUp_to_segmentStart * chart_thisSegmentIsPartOf.Up_normalized; + Vector3 center_to_startPosOfBroadLine = center_to_startPosOfBroadLine_normalized * radius_ofBroadFillLine; + Vector3 startPosOfBroadLine = chart_thisSegmentIsPartOf.Position_worldspace + center_to_startPosOfBroadLine; + turnAngleDegCC = chart_thisSegmentIsPartOf.OrderingIsClockwise() ? (-angleDeg_insidePie) : angleDeg_insidePie; + DrawBasics.LineCircled(startPosOfBroadLine, chart_thisSegmentIsPartOf.Position_worldspace, chart_thisSegmentIsPartOf.Forward_normalized, turnAngleDegCC, color, width_ofBroadFillLine, null, false, true, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); + + center_to_startPosOfThinOuterBorderLine = center_to_startPosOfBroadLine_normalized * radius_ofPieCircle; + Vector3 startPosOfThinOuterBorderLine = chart_thisSegmentIsPartOf.Position_worldspace + center_to_startPosOfThinOuterBorderLine; + DrawBasics.LineCircled(startPosOfThinOuterBorderLine, chart_thisSegmentIsPartOf.Position_worldspace, chart_thisSegmentIsPartOf.Forward_normalized, turnAngleDegCC, color, 0.0f, null, false, true, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); + + float endingAngleDegCCFromUp = startingAngleDegCCFromUp + turnAngleDegCC; + return endingAngleDegCCFromUp; + } + else + { + float endingAngleDegCCFromUp = startingAngleDegCCFromUp; + return endingAngleDegCCFromUp; + } + } + + public void TryDrawStraightSegmentBorderLine(Color color_ofPrecedingSegment, float durationInSec, bool hiddenByNearerObjects) + { + if (isTooSmallToBeDrawn == false) + { + float lengthOfStripes = 0.03f * radius_ofPieCircle; + LineWithAlternatingColors_fadeableAnimSpeed.InternalDraw(chart_thisSegmentIsPartOf.Position_worldspace, chart_thisSegmentIsPartOf.Position_worldspace + center_to_startPosOfThinOuterBorderLine, color_ofPrecedingSegment, color, 0.0f, lengthOfStripes, null, 0.0f, null, default(Vector3), true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true); + } + } + + public void PrepareTextDrawing() + { + sizeOfText = 0.05f * radius_ofPieCircle * chart_thisSegmentIsPartOf.RelSize_ofSegmentsNameTexts; + drawnText = GetDrawnText(); + if (drawnText == null) { return; } + + if (isTooSmallToBeDrawn == false) + { + textInRightColumn_shouldBeInsideTheOthersSection = false; + + float segmentMiddleAngleDegCCFromUp = startingAngleDegCCFromUp + 0.5f * turnAngleDegCC; + float segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 = UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_0_to_x(segmentMiddleAngleDegCCFromUp, 360.0f); + + Quaternion rotation_fromPieUp_to_segmentCenter = Quaternion.AngleAxis(segmentMiddleAngleDegCCFromUp, chart_thisSegmentIsPartOf.Forward_normalized); + + Vector3 center_to_segmentMiddle_normalized = rotation_fromPieUp_to_segmentCenter * chart_thisSegmentIsPartOf.Up_normalized; + + //This doesn't write yet, but only fills parsedTextSpecs: + UtilitiesDXXL_Text.Write(drawnText, Vector3.zero, default(Color), sizeOfText, Vector3.right, Vector3.up, DrawText.TextAnchorDXXL.MiddleCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, false, 0.0f, true, true, false, true); + float width_ofTextBlock = DrawText.parsedTextSpecs.widthOfLongestLine; + float height_ofTextBlock = DrawText.parsedTextSpecs.height_wholeTextBlock; + + Quaternion rotation_aroundGlobalForward_fromGlobalUp_toSegmentMiddleIfChartIsUnrotatedInsideXYPlane = Quaternion.AngleAxis(segmentMiddleAngleDegCCFromUp, Vector3.forward); + Vector2 center_to_segmentMiddle_unrotatedV3 = rotation_aroundGlobalForward_fromGlobalUp_toSegmentMiddleIfChartIsUnrotatedInsideXYPlane * Vector3.up; + Vector2 center_to_segmentMiddle_unrotatedV2 = new Vector2(center_to_segmentMiddle_unrotatedV3.x, center_to_segmentMiddle_unrotatedV3.y); + Vector2 intersectionOn2DUnitBoundsWithLowLeftAtZero_towardsCircleCenter = InternalDXXL_BoundsCamViewportSpace.GetViewportCenterPlumbIntersectionWithViewportBorder(InternalDXXL_BoundsCamViewportSpace.viewportCenter - center_to_segmentMiddle_unrotatedV2); + Vector2 center_of2DTextBoundsWithLowLeftAtZero = 0.5f * new Vector2(width_ofTextBlock, height_ofTextBlock); + Vector2 intersectionOn2DTextBoundsWithLowLeftAtZero_towardsCircleCenter = new Vector2(intersectionOn2DUnitBoundsWithLowLeftAtZero_towardsCircleCenter.x * width_ofTextBlock, intersectionOn2DUnitBoundsWithLowLeftAtZero_towardsCircleCenter.y * height_ofTextBlock); + float distance_fromTextBlockBoundsIntersectionTowardsCircleCenter_toTextCenter = (intersectionOn2DTextBoundsWithLowLeftAtZero_towardsCircleCenter - center_of2DTextBoundsWithLowLeftAtZero).magnitude; + float distanceOfTextToCircleCenter = radius_ofPieCircle * 1.1f + distance_fromTextBlockBoundsIntersectionTowardsCircleCenter_toTextCenter; + positionOfText = chart_thisSegmentIsPartOf.Position_worldspace + center_to_segmentMiddle_normalized * distanceOfTextToCircleCenter; + textAnchor = DrawText.TextAnchorDXXL.MiddleCenter; //-> this prevents jumping of the text position, compared to a solution where the anchor is at the side of the textBlock that is nearest to the circleCenter + + float enclosingBox_paddingSize_relToTextSize = 0.0f;//-> this defines the enclosingBoxVertices that get used by "Get_angleDeg_thatTextWouldCover()" + //again: This doesn't write yet, but only fills parsedTextSpecs: + UtilitiesDXXL_Text.Write(drawnText, positionOfText, default(Color), sizeOfText, chart_thisSegmentIsPartOf.Right_normalized, chart_thisSegmentIsPartOf.Up_normalized, textAnchor, DrawBasics.LineStyle.solid, 0.0f, enclosingBox_paddingSize_relToTextSize, 0.0f, 0.0f, 0.0f, chart_thisSegmentIsPartOf.autoFlipAllText_toFitObsererCamera, 0.0f, true, true, false, true); + float angleDeg_thatTextWouldCover = Get_angleDeg_thatTextWouldCover(segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360); //-> this depends on the preceding fake "Write()"-call + float halfAngleDeg_thatTextWouldCover = 0.5f * angleDeg_thatTextWouldCover; + startAngleDegCCFromUp_ofTextBlock = segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 - halfAngleDeg_thatTextWouldCover; + endAngleDegCCFromUp_ofTextBlock = segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 + halfAngleDeg_thatTextWouldCover; + } + else + { + textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall = true; + textInRightColumn_shouldBeInsideTheOthersSection = true; + } + } + + public void TryDrawTextBesideSegment(float durationInSec, bool hiddenByNearerObjects) + { + //-> caller guarantees: "isTooSmallToBeDrawn == false" or "isOthersSection" + if (drawnText == null) { return; } + if (chart_thisSegmentIsPartOf.CheckIfAngleForTextIsAlreadyCovered(startAngleDegCCFromUp_ofTextBlock, endAngleDegCCFromUp_ofTextBlock)) + { + textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall = true; + } + else + { + UtilitiesDXXL_Text.Write(drawnText, positionOfText, color, sizeOfText, chart_thisSegmentIsPartOf.Right_normalized, chart_thisSegmentIsPartOf.Up_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisSegmentIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true); + textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall = false; + chart_thisSegmentIsPartOf.MarkAngleSpanAsCoveredWithText(startAngleDegCCFromUp_ofTextBlock, endAngleDegCCFromUp_ofTextBlock); + } + } + + public void ReportThat_textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall() + { + textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall = true; + } + + public float TryDrawTextInRightColumnOutsideOthersSection(bool thisIsTheOthersSegment, float vertOffset_ofTextBlock, float durationInSec, bool hiddenByNearerObjects) + { + float vertOffset_ofNextTextBlock = vertOffset_ofTextBlock; + if (drawnText == null) { return vertOffset_ofNextTextBlock; } + if (CheckIfTextIsDrawn_inRightColumnOutsideOthersSection() || thisIsTheOthersSegment) + { + Vector3 topLeftPos_ofTextBlock = Get_topLeftPos_ofTextBlock(vertOffset_ofTextBlock); + UtilitiesDXXL_Text.Write(drawnText, topLeftPos_ofTextBlock, color, sizeOfText, chart_thisSegmentIsPartOf.Right_normalized, chart_thisSegmentIsPartOf.Up_normalized, DrawText.TextAnchorDXXL.UpperLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisSegmentIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true); + vertOffset_ofNextTextBlock = Get_vertOffset_ofNextTextBlock(vertOffset_ofTextBlock); + } + return vertOffset_ofNextTextBlock; + } + + bool CheckIfTextIsDrawn_inRightColumnOutsideOthersSection() + { + if (textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall) + { + if (textInRightColumn_shouldBeInsideTheOthersSection == false) + { + if (chart_thisSegmentIsPartOf.mentionZeroSegmentsInLegend || (valueAsFloat > 0.0f)) + { + return true; + } + } + } + return false; + } + + public float TryDrawTextInRightColumnInsideOthersSection(float vertOffset_ofTextBlock, Color color_ofOthersSegment, float durationInSec, bool hiddenByNearerObjects) + { + float vertOffset_ofNextTextBlock = vertOffset_ofTextBlock; + if (drawnText == null) { return vertOffset_ofNextTextBlock; } + if (textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall) + { + if (textInRightColumn_shouldBeInsideTheOthersSection) + { + if (chart_thisSegmentIsPartOf.mentionZeroSegmentsInLegend || (valueAsFloat > 0.0f)) + { + Vector3 topLeftPos_ofTextBlock = Get_topLeftPos_ofTextBlock(vertOffset_ofTextBlock); + + bool autoFlipToPreventMirrorInverted = false; + UtilitiesDXXL_Text.Write("", topLeftPos_ofTextBlock, color_ofOthersSegment, 2.0f * sizeOfText, chart_thisSegmentIsPartOf.Right_normalized, chart_thisSegmentIsPartOf.Up_normalized, DrawText.TextAnchorDXXL.UpperLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, false, false, true); + + float horizOffset_dueToArrow = 4.0f * sizeOfText; + Vector3 posOfTextBlock = topLeftPos_ofTextBlock + chart_thisSegmentIsPartOf.Right_normalized * horizOffset_dueToArrow - chart_thisSegmentIsPartOf.Up_normalized * (0.85f * sizeOfText); + UtilitiesDXXL_Text.Write(drawnText, posOfTextBlock, color, sizeOfText, chart_thisSegmentIsPartOf.Right_normalized, chart_thisSegmentIsPartOf.Up_normalized, DrawText.TextAnchorDXXL.UpperLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisSegmentIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true); + vertOffset_ofNextTextBlock = Get_vertOffset_ofNextTextBlock(vertOffset_ofTextBlock); + } + } + } + return vertOffset_ofNextTextBlock; + } + + float Get_angleDeg_thatTextWouldCover(float segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360) + { + Vector3 maxAngleDefining_textBlockCorner1; + Vector3 maxAngleDefining_textBlockCorner2; + + if (segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 < 90.0f) + { + maxAngleDefining_textBlockCorner1 = DrawText.parsedTextSpecs.lowLeftPos_ofEnclosingBox; + maxAngleDefining_textBlockCorner2 = DrawText.parsedTextSpecs.upperRightPos_ofEnclosingBox; + } + else + { + if (segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 < 180.0f) + { + maxAngleDefining_textBlockCorner1 = DrawText.parsedTextSpecs.lowRightPos_ofEnclosingBox; + maxAngleDefining_textBlockCorner2 = DrawText.parsedTextSpecs.upperLeftPos_ofEnclosingBox; + } + else + { + if (segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 < 270.0f) + { + maxAngleDefining_textBlockCorner1 = DrawText.parsedTextSpecs.lowLeftPos_ofEnclosingBox; + maxAngleDefining_textBlockCorner2 = DrawText.parsedTextSpecs.upperRightPos_ofEnclosingBox; + } + else + { + maxAngleDefining_textBlockCorner1 = DrawText.parsedTextSpecs.lowRightPos_ofEnclosingBox; + maxAngleDefining_textBlockCorner2 = DrawText.parsedTextSpecs.upperLeftPos_ofEnclosingBox; + } + } + } + + Vector3 circleCenter_toTextBlockCorner1 = maxAngleDefining_textBlockCorner1 - chart_thisSegmentIsPartOf.Position_worldspace; + Vector3 circleCenter_toTextBlockCorner2 = maxAngleDefining_textBlockCorner2 - chart_thisSegmentIsPartOf.Position_worldspace; + return Vector3.Angle(circleCenter_toTextBlockCorner1, circleCenter_toTextBlockCorner2); + } + + Vector3 Get_topLeftPos_ofTextBlock(float vertOffset_ofTextBlock) + { + float size_ofPieCircleRadius = 0.5f * chart_thisSegmentIsPartOf.Size_ofPieCircleDiameter; + float offsetDistance_upward = chart_thisSegmentIsPartOf.Get_vertOffset_fromCircleCenter_toTopRightPosOfRightColumn() + vertOffset_ofTextBlock; + float offsetDistance_sideward = (size_ofPieCircleRadius + size_ofPieCircleRadius * 1.05f * chart_thisSegmentIsPartOf.RelSize_ofSegmentsNameTexts); + return (chart_thisSegmentIsPartOf.Position_worldspace + chart_thisSegmentIsPartOf.Up_normalized * offsetDistance_upward + chart_thisSegmentIsPartOf.Right_normalized * offsetDistance_sideward); + } + + float Get_vertOffset_ofNextTextBlock(float vertOffset_ofCurrTextBlock) + { + float relDistanceBetweenTextsInsideRightColumn = 0.025f; + return (vertOffset_ofCurrTextBlock - (DrawText.parsedTextSpecs.height_wholeTextBlock + relDistanceBetweenTextsInsideRightColumn * chart_thisSegmentIsPartOf.Size_ofPieCircleDiameter)); + } + + string GetDrawnText() + { + if ((chart_thisSegmentIsPartOf.showSegmentNames == true) && (chart_thisSegmentIsPartOf.showSegmentValues == true) && (chart_thisSegmentIsPartOf.showSegmentPercentages == true)) + { + //-> show all + return (name + "
" + (hasAtLeastBeenFilledOnceWithFloatInsteadOfInt ? valueAsFloat : valueAsInt) + "
" + GetPercentageDisplay()); + } + else + { + if ((chart_thisSegmentIsPartOf.showSegmentNames == false) && (chart_thisSegmentIsPartOf.showSegmentValues == true) && (chart_thisSegmentIsPartOf.showSegmentPercentages == true)) + { + return ("" + (hasAtLeastBeenFilledOnceWithFloatInsteadOfInt ? valueAsFloat : valueAsInt) + "
" + GetPercentageDisplay()); + } + else + { + if ((chart_thisSegmentIsPartOf.showSegmentNames == true) && (chart_thisSegmentIsPartOf.showSegmentValues == false) && (chart_thisSegmentIsPartOf.showSegmentPercentages == true)) + { + return (name + "
" + GetPercentageDisplay()); + } + else + { + if ((chart_thisSegmentIsPartOf.showSegmentNames == true) && (chart_thisSegmentIsPartOf.showSegmentValues == true) && (chart_thisSegmentIsPartOf.showSegmentPercentages == false)) + { + return (name + "
" + (hasAtLeastBeenFilledOnceWithFloatInsteadOfInt ? valueAsFloat : valueAsInt)); + } + else + { + if ((chart_thisSegmentIsPartOf.showSegmentNames == true) && (chart_thisSegmentIsPartOf.showSegmentValues == false) && (chart_thisSegmentIsPartOf.showSegmentPercentages == false)) + { + return name; + } + else + { + if ((chart_thisSegmentIsPartOf.showSegmentNames == false) && (chart_thisSegmentIsPartOf.showSegmentValues == true) && (chart_thisSegmentIsPartOf.showSegmentPercentages == false)) + { + return ("" + (hasAtLeastBeenFilledOnceWithFloatInsteadOfInt ? valueAsFloat : valueAsInt)); + } + else + { + if ((chart_thisSegmentIsPartOf.showSegmentNames == false) && (chart_thisSegmentIsPartOf.showSegmentValues == false) && (chart_thisSegmentIsPartOf.showSegmentPercentages == true)) + { + return GetPercentageDisplay(); + } + else + { + //-> show nothing + if (((chart_thisSegmentIsPartOf.showSegmentNames == false) && (chart_thisSegmentIsPartOf.showSegmentValues == false) && (chart_thisSegmentIsPartOf.showSegmentPercentages == false)) == false) + { + UtilitiesDXXL_Log.PrintErrorCode("29-" + chart_thisSegmentIsPartOf.showSegmentNames + "-" + chart_thisSegmentIsPartOf.showSegmentValues + "-" + chart_thisSegmentIsPartOf.showSegmentPercentages); + } + return null; + } + } + } + } + } + } + } + } + + string GetPercentageDisplay() + { + float value; + if (chart_thisSegmentIsPartOf.postDecimalPositions_ofPercentageDisplay <= 0) + { + value = Mathf.Round(100.0f * percentage_0to1); + } + else + { + float postDecimalPositions_ofPercentageDisplay_asFloat = (float)chart_thisSegmentIsPartOf.postDecimalPositions_ofPercentageDisplay; + float factor1 = Mathf.Pow(0.1f, postDecimalPositions_ofPercentageDisplay_asFloat); + float factor2 = 100.0f * Mathf.Pow(10.0f, postDecimalPositions_ofPercentageDisplay_asFloat); + value = factor1 * Mathf.Round(factor2 * percentage_0to1); + } + return "" + value + " %"; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/charts/pie charts/PieChartSegment.cs.meta b/Runtime/DrawDebugLibrary/charts/pie charts/PieChartSegment.cs.meta new file mode 100644 index 0000000..09ff29c --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/pie charts/PieChartSegment.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc081852df8d85745917b02aa7471345 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/pie charts/internal utilities.meta b/Runtime/DrawDebugLibrary/charts/pie charts/internal utilities.meta new file mode 100644 index 0000000..13d99f2 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/pie charts/internal utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ea334b5da36419547b452d3e2e7dbfa7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/charts/pie charts/internal utilities/InternalDXXL_PieAngleSpan.cs b/Runtime/DrawDebugLibrary/charts/pie charts/internal utilities/InternalDXXL_PieAngleSpan.cs new file mode 100644 index 0000000..94a5eb3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/pie charts/internal utilities/InternalDXXL_PieAngleSpan.cs @@ -0,0 +1,39 @@ +namespace DrawXXL +{ + public struct InternalDXXL_PieAngleSpan + { + public float startAngleDegCCFromUp; + public float endAngleDegCCFromUp; + + public bool DoesIntersect(float startAngleDegCCFromUp_ofSpanThatIsCheckedIfItIntersectsWithThisSpan, float endAngleDegCCFromUp_ofSpanThatIsCheckedIfItIntersectsWithThisSpan) + { + //This function expects: + //-> startAngleDegCCFromUp is smaller than endAngleDegCCFromUp + //-> at least one angle lies between 0 and 360, and the other angle is not looped into this span, but is either negative or bigger thatn 360 + //(both is guaranteed by "PieChartSegment.PrepareTextDrawing") + + if (startAngleDegCCFromUp_ofSpanThatIsCheckedIfItIntersectsWithThisSpan < startAngleDegCCFromUp) + { + if (endAngleDegCCFromUp_ofSpanThatIsCheckedIfItIntersectsWithThisSpan < startAngleDegCCFromUp) + { + return false; + } + else + { + return true; + } + } + else + { + if (startAngleDegCCFromUp_ofSpanThatIsCheckedIfItIntersectsWithThisSpan < endAngleDegCCFromUp) + { + return true; + } + else + { + return false; + } + } + } + } +} diff --git a/Runtime/DrawDebugLibrary/charts/pie charts/internal utilities/InternalDXXL_PieAngleSpan.cs.meta b/Runtime/DrawDebugLibrary/charts/pie charts/internal utilities/InternalDXXL_PieAngleSpan.cs.meta new file mode 100644 index 0000000..02a94e6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/charts/pie charts/internal utilities/InternalDXXL_PieAngleSpan.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: abed9bbbb2db23c40a707aeb07e0bde0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components.meta b/Runtime/DrawDebugLibrary/components.meta new file mode 100644 index 0000000..805c097 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e08c3d9638ad318458b3225ec276152d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/2D.meta b/Runtime/DrawDebugLibrary/components/2D.meta new file mode 100644 index 0000000..ceb6ec1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6984a01ed542a394886c3485775d62ef +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/2D/BezierSplineDrawer2D.cs b/Runtime/DrawDebugLibrary/components/2D/BezierSplineDrawer2D.cs new file mode 100644 index 0000000..1ef651c --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/BezierSplineDrawer2D.cs @@ -0,0 +1,1330 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/2D/Bezier Spline Drawer 2D")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class BezierSplineDrawer2D : BezierSplineDrawerBase + { + static Color default_colorOfLinesAlongZToBoundGameobjects = new Color(0.09f, 1.0f, 0.653f, 1.0f); + + [SerializeField] public bool drawSpaceSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public BezierSplineDrawer.DrawSpace drawSpace; + [SerializeField] bool keepWorldPos_duringDrawSpaceChange = false; + + [SerializeField] public Color color_ofAnchorPoints = BezierSplineDrawer.default_color_ofAnchorPoints; + [SerializeField] public Color color_ofHelperPoints = BezierSplineDrawer.default_color_ofHelperPoints; + [SerializeField] public bool gapFromEndToStart_isClosed = false; + + [SerializeField] public BezierSplineDrawer.PositionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal = BezierSplineDrawer.PositionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal.localDrawSpace; + + public static float default_handleSizeOf_customHandle_atAnchors = 0.28f; + static float default_handleSizeOf_customHandle_atHelpers = 0.18f; + static float default_handleSizeOf_plusButtons = 0.2f; + + [SerializeField] public bool handlesSection_isOutfolded = false; + [SerializeField] public bool hideAllHandles = false; + [SerializeField] public bool showHandleFor_position_atAnchors = true; + [SerializeField] public bool showHandleFor_position_atHelpers = true; + [SerializeField] [Range(0.2f, 2.0f)] public float handleSizeFor_position_atAnchors = 0.85f; + [SerializeField] [Range(0.2f, 2.0f)] public float handleSizeFor_position_atHelpers = 0.85f; + [SerializeField] public bool showHandleFor_rotation = true; + [SerializeField] [Range(0.15f, 1.5f)] public float handleSizeFor_rotation = 0.55f; + [SerializeField] public bool showCustomHandleFor_anchorPoints = true; + [SerializeField] public bool showCustomHandleFor_helperPoints = true; + [SerializeField] [Range(0.08f, 0.75f)] public float handleSizeOf_customHandle_atAnchors = default_handleSizeOf_customHandle_atAnchors; + [SerializeField] [Range(0.08f, 0.75f)] public float handleSizeOf_customHandle_atHelpers = default_handleSizeOf_customHandle_atHelpers; + [SerializeField] public bool showHandleFor_plusButtons_atSplineStartAndEnd = true; + [SerializeField] public bool showHandleFor_plusButtons_insideSegments = true; + [SerializeField] [Range(0.08f, 0.75f)] public float handleSizeOf_plusButtons = default_handleSizeOf_plusButtons; + [SerializeField] public bool showDottedLinesAlongZToBoundGameobjects = true; + [SerializeField] public Color colorOfLinesAlongZToBoundGameobjects = default_colorOfLinesAlongZToBoundGameobjects; + [SerializeField] public float dotLength_ofDottedLinesAlongZToBoundGameobjects = 8.0f; + + [SerializeField] public bool controlPointsList_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool defaultRotOfNewlyCreatedPoints_subSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + [SerializeField] public BezierSplineDrawer.DefinitionType_ofDefaultPosOffset definitionType_ofDefaultPosOffset = BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.straightExtentionOfCurveEnd; + [SerializeField] public float distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace = 3.0f; + + [SerializeField] public BezierSplineDrawer.DefinitionType_ofDefaultRot definitionType_ofDefaultRot = BezierSplineDrawer.DefinitionType_ofDefaultRot.sameAsCurveEnd; + + [SerializeField] public float forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace = BezierSplineDrawer.default_forwardWeightDistance_ofNewlyCreatedPoints; + [SerializeField] public float backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace = BezierSplineDrawer.default_backwardWeightDistance_ofNewlyCreatedPoints; + [SerializeField] public InternalDXXL_BezierControlAnchorSubPoint.JunctureType junctureType_ofNewlyCreatedPoints = InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned; + + //Serialization of the list: + //-> In the serialized context the items and subItems of the list behave like structs that are copied by value, even if they are classes + //-> The list contains controlPoints and sub-controlPoints with cross references that should be copied by reference. There are constructions how this is possible via using "[SerializeReference]", but serialized lists/arrays/reorderableList seem not to be fully compatible with it. Obscure errors appear, for example when clicking the "choose presets symbol" in the component inspector, then these lists dissolve into nullRefExceptions, even if there aren't any presets available. Also other obscure errors for reorderable list like "list item not found" after deleting control points via custom buttons. + //-> see also Unitys documenation on Serialization: "Avoid nested, recursive structures where you reference other classes." + //-> Therefore the cross references of the subItems are implemented via fake properties: They don't "reference each other", but they reference only the list-carrying MonoBehaviour-inherited spline-component here and ask for the position of the "(quasi)referenced" other subItem inside the (quasi)struct. References from other gameobjects (that are bound to controlSubPoints via the "SplineConnection"-component) have to act in the same way: They cannot reference the subPoint where they are bound to "directly", but have to obtain it via the position inside the list-(quasi)struct. + [SerializeField] public List listOfControlPointTriplets = new List(); + + [SerializeField] Vector3 lastGlobalPositionOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf; + [SerializeField] Quaternion lastGlobalRotationOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf; + [SerializeField] Vector3 lastLossyScaleOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf; //known issue: if a parent transform scale is set to 0/0/0 in local draw space, then after setting the scale to a valid value again the spline shape cannot be retrieved and is melted to a single point + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + + customVector2Configs[0].picker_isOutfolded = true; + customVector2Configs[0].source = CustomVector2Source.manualInput; + customVector2Configs[0].clipboardForManualInput = Vector2.right; + customVector2Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector2Configs[1].picker_isOutfolded = true; + customVector2Configs[1].source = CustomVector2Source.manualInput; + customVector2Configs[1].clipboardForManualInput = Vector2.right; + customVector2Configs[1].vectorInterpretation = VectorInterpretation.globalSpace; + + drawSpace = BezierSplineDrawer.DrawSpace.global; + CreateFirstTwoControlPointsOfNewlyCreatedSpline(); + } + + void CreateFirstTwoControlPointsOfNewlyCreatedSpline() + { + CreateNewControlPoint_atSplineEnd(); + CreateNewControlPoint_atSplineEnd(); + + Vector2 initialPosOfSecondControlPoint = listOfControlPointTriplets[1].anchorPoint.GetPos_inUnitsOfGlobalSpace() + 2.0f * Vector2.up - 0.75f * Vector2.right; + listOfControlPointTriplets[1].anchorPoint.SetPos_inUnitsOfGlobalSpace(initialPosOfSecondControlPoint, true, null); + listOfControlPointTriplets[1].isHighlighted = false; + } + + void OnDestroy() + { + //"OnDestroy" is sometimes not fired. I don't see the clear reason for this. It is not always tied to the reason which the Unity documentation mentions (which is "OnDestroy() is not called for inactive gameobjects"). In the cases where it is not fired the boundGameobject.connectionComponent-references don't get reverted via "Undo (the spline deletion)". + TryDeleteAllBoundGameobjectConnectionsInclUndo(); + } + + public override void DrawVisualizedObject() + { + TryReApplyLocalDrawSpaceValues(); + + bool textHasBeenDrawn = false; + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + InternalDXXL_BezierControlPointTriplet2D currControlPointTriplet = listOfControlPointTriplets[i]; + InternalDXXL_BezierControlPointTriplet2D nextControlPointTriplet = GetNextControlPointTriplet(i, true); + textHasBeenDrawn = DrawBezierSegmentBetweenTwoControlPointTriplets(textHasBeenDrawn, currControlPointTriplet, nextControlPointTriplet); + } + DrawTextIfThereArentAnyControlPoints(); + } + + void TryReApplyLocalDrawSpaceValues() + { + bool reApplyLocalDrawSpaceValues = false; + if (drawSpace == BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject) + { + if (false == UtilitiesDXXL_Math.CheckIf_twoVectorsAreExactlyEqual(transform.position, lastGlobalPositionOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf)) + { + reApplyLocalDrawSpaceValues = true; + } + + if (false == UtilitiesDXXL_Math.CheckIf_twoQuaternionsAreExactlyEqual(transform.rotation, lastGlobalRotationOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf)) + { + reApplyLocalDrawSpaceValues = true; + } + + if (false == UtilitiesDXXL_Math.CheckIf_twoVectorsAreExactlyEqual(transform.lossyScale, lastLossyScaleOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf)) + { + reApplyLocalDrawSpaceValues = true; + } + } + + if (reApplyLocalDrawSpaceValues) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].Save_currentPosConfigInUnitsOfActiveDrawSpace_as_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace(); + listOfControlPointTriplets[i].ApplySaved_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace(); + } + Save_lastTransformStateOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf(); + } + } + + bool DrawBezierSegmentBetweenTwoControlPointTriplets(bool textHasBeenDrawn, InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentStart, InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentEnd) + { + if (controlPointTriplet_atSegmentEnd != null) + { + if (controlPointTriplet_atSegmentStart.forwardHelperPoint.isUsed == true) + { + if (controlPointTriplet_atSegmentEnd.backwardHelperPoint.isUsed == true) + { + DrawBasics2D.BezierSegmentCubic(controlPointTriplet_atSegmentStart.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentStart.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), color, GetTextForCurrentSegment(textHasBeenDrawn), lineWidth, straightSubDivisionsPerSegment, GetZPos_global_for2D(), false, textSize, 0.0f, hiddenByNearerObjects); + } + else + { + DrawBasics2D.BezierSegmentQuadratic(controlPointTriplet_atSegmentStart.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentStart.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), color, GetTextForCurrentSegment(textHasBeenDrawn), lineWidth, straightSubDivisionsPerSegment, GetZPos_global_for2D(), textSize, 0.0f, hiddenByNearerObjects); + } + } + else + { + if (controlPointTriplet_atSegmentEnd.backwardHelperPoint.isUsed == true) + { + DrawBasics2D.BezierSegmentQuadratic(controlPointTriplet_atSegmentStart.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), color, GetTextForCurrentSegment(textHasBeenDrawn), lineWidth, straightSubDivisionsPerSegment, GetZPos_global_for2D(), textSize, 0.0f, hiddenByNearerObjects); + } + else + { + Line_fadeableAnimSpeed_2D.InternalDraw(controlPointTriplet_atSegmentStart.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.anchorPoint.GetPos_inUnitsOfGlobalSpace(), color, lineWidth, GetTextForCurrentSegment(textHasBeenDrawn), DrawBasics.LineStyle.solid, GetZPos_global_for2D(), 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, 0.0f, hiddenByNearerObjects, false, false); + } + } + } + + textHasBeenDrawn = true; + return textHasBeenDrawn; + } + + string GetTextForCurrentSegment(bool textHasBeenDrawn) + { + return textHasBeenDrawn ? null : text_inclGlobalMarkupTags; + } + + void DrawTextIfThereArentAnyControlPoints() + { + Vector2 textPosGlobal = default; + if (text_inclGlobalMarkupTags != null && text_inclGlobalMarkupTags != "") + { + if (listOfControlPointTriplets.Count == 0) + { + textPosGlobal = Get_originPos_ofActiveDrawSpace_inUnitsOfGlobalSpace(); + } + + if ((listOfControlPointTriplets.Count == 1) && (gapFromEndToStart_isClosed == false)) + { + textPosGlobal = listOfControlPointTriplets[0].anchorPoint.GetPos_inUnitsOfGlobalSpace(); + } + + if (listOfControlPointTriplets.Count == 0 || ((listOfControlPointTriplets.Count == 1) && (gapFromEndToStart_isClosed == false))) + { + UtilitiesDXXL_Text.Write2DFramed(text_inclGlobalMarkupTags, textPosGlobal, color, textSize, default(Vector2), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, GetZPos_global_for2D(), DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, hiddenByNearerObjects); + } + } + } + + public void CreateNewControlPoint_dueToPlusButtonBelowControlPointsListHasBeenClicked() + { + CreateNewControlPoint_atSplineEnd(); + } + + public void TryDeleteControlPoint_dueToMinusButtonAtControlPointListItemHasBeenClicked(int i_ofItemToDelete) + { + RegisterStateForUndo("Delete Spline Point(s)", true, true); + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet(i_ofItemToDelete); + listOfControlPointTriplets.RemoveAt(i_ofItemToDelete); + ReassignIndexesToAllControlPoints(); + TryDeactivateHelperPointsAtSplineEndsToVoid(); + } + + void TryDeleteAllBoundGameobjectConnectionsInclUndo() + { + //-> this ensures the retrieval of the boundGameobject-references if after spline-deletion "Editor/Undo" is used + if (listOfControlPointTriplets != null) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet(i); + } + } + } + + void DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet(int i_ofControlPointTripletWhereConnectionsGetDeleted) + { + if (Application.isPlaying) + { + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet_nonImmediate(i_ofControlPointTripletWhereConnectionsGetDeleted); + } + else + { + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet_immediate(i_ofControlPointTripletWhereConnectionsGetDeleted); + } + } + + void DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet_nonImmediate(int i_ofControlPointTripletWhereConnectionsGetDeleted) + { + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].backwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + Destroy(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].backwardHelperPoint.connectionComponent_onBoundGameobject); + } + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].anchorPoint.connectionComponent_onBoundGameobject != null) + { + Destroy(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].anchorPoint.connectionComponent_onBoundGameobject); + } + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].forwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + Destroy(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].forwardHelperPoint.connectionComponent_onBoundGameobject); + } + } + + void DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet_immediate(int i_ofControlPointTripletWhereConnectionsGetDeleted) + { +#if UNITY_EDITOR + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].backwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.DestroyObjectImmediate(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].backwardHelperPoint.connectionComponent_onBoundGameobject); + } + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].anchorPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.DestroyObjectImmediate(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].anchorPoint.connectionComponent_onBoundGameobject); + } + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].forwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.DestroyObjectImmediate(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].forwardHelperPoint.connectionComponent_onBoundGameobject); + } +#else + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet_nonImmediate(i_ofControlPointTripletWhereConnectionsGetDeleted); +#endif + } + + public void DeleteConnectionComponentOfBoundGameobject_onControlSubPoint(int i_ofControlPointWhereConnectionsGetDeleted, InternalDXXL_BezierControlSubPoint.SubPointType subPointType_whereConnectionsGetDeleted) + { + if (Application.isPlaying) + { + DeleteConnectionComponentOfBoundGameobject_onControlSubPoint_nonImmediate(i_ofControlPointWhereConnectionsGetDeleted, subPointType_whereConnectionsGetDeleted); + } + else + { + DeleteConnectionComponentOfBoundGameobject_onControlSubPoint_immediate(i_ofControlPointWhereConnectionsGetDeleted, subPointType_whereConnectionsGetDeleted); + } + } + + public void DeleteConnectionComponentOfBoundGameobject_onControlSubPoint_nonImmediate(int i_ofControlPointWhereConnectionsGetDeleted, InternalDXXL_BezierControlSubPoint.SubPointType subPointType_whereConnectionsGetDeleted) + { + if (listOfControlPointTriplets[i_ofControlPointWhereConnectionsGetDeleted].GetASubPoint(subPointType_whereConnectionsGetDeleted).connectionComponent_onBoundGameobject != null) + { + Destroy(listOfControlPointTriplets[i_ofControlPointWhereConnectionsGetDeleted].GetASubPoint(subPointType_whereConnectionsGetDeleted).connectionComponent_onBoundGameobject); + } + } + + public void DeleteConnectionComponentOfBoundGameobject_onControlSubPoint_immediate(int i_ofControlPointWhereConnectionsGetDeleted, InternalDXXL_BezierControlSubPoint.SubPointType subPointType_whereConnectionsGetDeleted) + { +#if UNITY_EDITOR + if (listOfControlPointTriplets[i_ofControlPointWhereConnectionsGetDeleted].GetASubPoint(subPointType_whereConnectionsGetDeleted).connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.DestroyObjectImmediate(listOfControlPointTriplets[i_ofControlPointWhereConnectionsGetDeleted].GetASubPoint(subPointType_whereConnectionsGetDeleted).connectionComponent_onBoundGameobject); + } +#else + DeleteConnectionComponentOfBoundGameobject_onControlSubPoint_nonImmediate(i_ofControlPointWhereConnectionsGetDeleted, subPointType_whereConnectionsGetDeleted); +#endif + } + + void TryDeactivateHelperPointsAtSplineEndsToVoid() + { + if (gapFromEndToStart_isClosed == false) + { + if (listOfControlPointTriplets.Count > 0) + { + listOfControlPointTriplets[0].backwardHelperPoint.ChangeUsedState(false, false); + listOfControlPointTriplets[0].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + + int i_ofLastControlPoint = listOfControlPointTriplets.Count - 1; + listOfControlPointTriplets[i_ofLastControlPoint].forwardHelperPoint.ChangeUsedState(false, false); + listOfControlPointTriplets[i_ofLastControlPoint].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + } + } + } + + public void CreateNewControlPoint_atSplineEnd() + { + RegisterStateForUndo("Add Spline Point", false, false); + InternalDXXL_BezierControlPointTriplet2D newControlPointTriplet = new InternalDXXL_BezierControlPointTriplet2D(); + listOfControlPointTriplets.Add(newControlPointTriplet); + ReassignIndexesToAllControlPoints(); + + if (listOfControlPointTriplets.Count >= 2) + { + InitializeNewlyCreatedControlPoint_atSplineEnd(); + } + else + { + InitializeFirstControlPoint(); + } + + SetSelectedListSlot(listOfControlPointTriplets.Count - 1); + } + + public void CreateNewControlPoint_atSplineStart() + { + RegisterStateForUndo("Add Spline Point", false, false); + InternalDXXL_BezierControlPointTriplet2D newControlPointTriplet = new InternalDXXL_BezierControlPointTriplet2D(); + listOfControlPointTriplets.Insert(0, newControlPointTriplet); + ReassignIndexesToAllControlPoints(); + + if (listOfControlPointTriplets.Count >= 2) + { + InitializeNewControlPoint_atSplineStart(); + SetSelectedListSlot(0); + } + else + { + UtilitiesDXXL_Log.PrintErrorCode("80-" + listOfControlPointTriplets.Count); + } + } + + public void CreateNewControlPoint_somewhereOnUpcomingSplineSegment(int i_startOfSegmentPreInsert) + { + RegisterStateForUndo("Add Spline Point", false, false); + + InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentStartPreInsert = listOfControlPointTriplets[i_startOfSegmentPreInsert]; + InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentEndPreInsert = controlPointTriplet_atSegmentStartPreInsert.GetNextControlPointTripletAlongSplineDir(true); + + if (controlPointTriplet_atSegmentEndPreInsert != null) + { + Vector2 posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentStartPreInsert.GetPosAtPlusButton_onUpcomingBezierSegment_inUnitsOfGlobalSpace(); + + if (controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.isUsed == true) + { + if (controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.isUsed == true) + { + CreateSubdividingControlPoint_insideCubicSegment(i_startOfSegmentPreInsert, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentStartPreInsert, controlPointTriplet_atSegmentEndPreInsert); + } + else + { + CreateSubdividingControlPoint_insideQuadraticSegmentThatHasOnlyStartPointsForwardHelper(i_startOfSegmentPreInsert, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentStartPreInsert, controlPointTriplet_atSegmentEndPreInsert); + } + } + else + { + if (controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.isUsed == true) + { + CreateSubdividingControlPoint_insideQuadraticSegmentThatHasOnlyEndPointsBackwardHelper(i_startOfSegmentPreInsert, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentStartPreInsert, controlPointTriplet_atSegmentEndPreInsert); + } + else + { + CreateSubdividingControlPoint_insideStraightSegmentThatHasNoHelpers(i_startOfSegmentPreInsert, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentStartPreInsert, controlPointTriplet_atSegmentEndPreInsert); + } + } + + controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment = 0.5f; + } + else + { + UtilitiesDXXL_Log.PrintErrorCode("57-" + i_startOfSegmentPreInsert + "-" + listOfControlPointTriplets.Count + "" + gapFromEndToStart_isClosed); + } + } + + void CreateSubdividingControlPoint_insideCubicSegment(int i_startOfSegmentPreInsert, Vector2 posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentStartPreInsert, InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentEndPreInsert) + { + InternalDXXL_BezierControlPointTriplet2D newlyCreatedControlPointTriplet = InsertUninitializedNewControlPointIntoList(i_startOfSegmentPreInsert); + Vector2 initialDirection_normalized = Vector2.right; //-> is anyway not used, but immediately overwritten inside this function + newlyCreatedControlPointTriplet.Initialize(this, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialDirection_normalized, InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned); + + //all vectors are meant "_inUnitsOfGlobalSpace": + float progress0to1_insidePreInsertSegment = controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + + Vector2 from_preInsertStartForwardHelper_to_preInsertEndBackwardHelper = controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace() - controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + Vector2 interpolatedPosOnStrech_from_preInsertForwardHelper_to_preInsertEndBackwardHelper = controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace() + from_preInsertStartForwardHelper_to_preInsertEndBackwardHelper * progress0to1_insidePreInsertSegment; + Vector2 from_anchorOfStartPointPreInsert_to_forwardHelperOfStartPointPostInsert = (controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace() - controlPointTriplet_atSegmentStartPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace()) * progress0to1_insidePreInsertSegment; + Vector2 startPointsForwardHelperPostInsert = controlPointTriplet_atSegmentStartPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace() + from_anchorOfStartPointPreInsert_to_forwardHelperOfStartPointPostInsert; + Vector2 from_forwardHelperOfStartPointPostInsert_interpolatedPosOnPreInsertStartHelperToEndHelper = interpolatedPosOnStrech_from_preInsertForwardHelper_to_preInsertEndBackwardHelper - startPointsForwardHelperPostInsert; + Vector2 posOfBackwardHelper_ofNewlyCreatedControlPoint = startPointsForwardHelperPostInsert + from_forwardHelperOfStartPointPostInsert_interpolatedPosOnPreInsertStartHelperToEndHelper * progress0to1_insidePreInsertSegment; + newlyCreatedControlPointTriplet.backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfBackwardHelper_ofNewlyCreatedControlPoint, true, null); + + float new_absDistanceOfBackwardHelperOfPreInsertEndPoint_ifSegmentWouldNotBeMirrorForced = controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace() * (1.0f - progress0to1_insidePreInsertSegment); + Vector2 vector_fromPreInsertSegmentEndAnchor_toPreInsertSegmentEndBackwardHelperAfterInsert_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized() * new_absDistanceOfBackwardHelperOfPreInsertEndPoint_ifSegmentWouldNotBeMirrorForced; + Vector2 pos_ofPreInsertSegmentEndBackwardHelperAfterInsert_inUnitsOfGlobalSpace_ifSegmentWouldNotBeMirrorForced = controlPointTriplet_atSegmentEndPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace() + vector_fromPreInsertSegmentEndAnchor_toPreInsertSegmentEndBackwardHelperAfterInsert_inUnitsOfGlobalSpace; + if (controlPointTriplet_atSegmentEndPreInsert.anchorPoint.junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(pos_ofPreInsertSegmentEndBackwardHelperAfterInsert_inUnitsOfGlobalSpace_ifSegmentWouldNotBeMirrorForced, true, null); + } + else + { + LogMessageThatExplainsWhyTheSplineShapeChangedOnPointCreation(false); + } + + Vector2 from_interpolatedPosOnPreInsertStartHelperToEndHelper_to_endPointsBackwardHelperPostInsert = pos_ofPreInsertSegmentEndBackwardHelperAfterInsert_inUnitsOfGlobalSpace_ifSegmentWouldNotBeMirrorForced - interpolatedPosOnStrech_from_preInsertForwardHelper_to_preInsertEndBackwardHelper; + Vector2 posOfForwardHelper_ofNewlyCreatedControlPoint = interpolatedPosOnStrech_from_preInsertForwardHelper_to_preInsertEndBackwardHelper + from_interpolatedPosOnPreInsertStartHelperToEndHelper_to_endPointsBackwardHelperPostInsert * progress0to1_insidePreInsertSegment; + newlyCreatedControlPointTriplet.forwardHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfForwardHelper_ofNewlyCreatedControlPoint, true, null); + + ScaleForwardDistance_ofPreInsertStartPoint(controlPointTriplet_atSegmentStartPreInsert); + SetDefaultJunctureType_forCase_createInsideCubicSegment(newlyCreatedControlPointTriplet); + } + + void SetDefaultJunctureType_forCase_createInsideCubicSegment(InternalDXXL_BezierControlPointTriplet2D newlyCreatedControlPointTriplet) + { + if (junctureType_ofNewlyCreatedPoints == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored); + Debug.Log("Spline Position Creation Information: The spline segment before the newly created control point doesn't fit the spline shape from before the point was created. The reason for this is that the default juncture type of newly created control points is 'mirrored'. It is not possible to keep the spline shape with this constraint."); + } + + if (junctureType_ofNewlyCreatedPoints == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + } + } + + void CreateSubdividingControlPoint_insideQuadraticSegmentThatHasOnlyStartPointsForwardHelper(int i_startOfSegmentPreInsert, Vector2 posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentStartPreInsert, InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentEndPreInsert) + { + if (controlPointTriplet_atSegmentEndPreInsert.anchorPoint.junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + UtilitiesDXXL_Log.PrintErrorCode("67-" + i_startOfSegmentPreInsert + "-" + listOfControlPointTriplets.Count + "-" + gapFromEndToStart_isClosed + "-" + controlPointTriplet_atSegmentStartPreInsert.anchorPoint.junctureType + "-" + controlPointTriplet_atSegmentEndPreInsert.anchorPoint.junctureType); + return; + } + + InternalDXXL_BezierControlPointTriplet2D newlyCreatedControlPointTriplet = InsertUninitializedNewControlPointIntoList(i_startOfSegmentPreInsert); + Vector2 initialDirection_normalized = Vector2.right; //-> is anyway not used, but immediately overwritten inside this function + newlyCreatedControlPointTriplet.Initialize(this, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialDirection_normalized, junctureType_ofNewlyCreatedPoints); + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + newlyCreatedControlPointTriplet.backwardHelperPoint.ChangeUsedState(false, false); + + Vector2 from_forwardHelperPosOfPreInsertStartPoint_to_preInsertEndPointAnchor_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentEndPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace() - controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + Vector2 posOfForwardHelper_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace() + from_forwardHelperPosOfPreInsertStartPoint_to_preInsertEndPointAnchor_inUnitsOfGlobalSpace * controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + newlyCreatedControlPointTriplet.forwardHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfForwardHelper_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace, true, null); + + ScaleForwardDistance_ofPreInsertStartPoint(controlPointTriplet_atSegmentStartPreInsert); + SetDefaultJunctureType_forCase_createInsideQuadraticSegment(newlyCreatedControlPointTriplet, "before", "end"); + } + + void CreateSubdividingControlPoint_insideQuadraticSegmentThatHasOnlyEndPointsBackwardHelper(int i_startOfSegmentPreInsert, Vector2 posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentStartPreInsert, InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentEndPreInsert) + { + if (controlPointTriplet_atSegmentStartPreInsert.anchorPoint.junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + UtilitiesDXXL_Log.PrintErrorCode("68-" + i_startOfSegmentPreInsert + "-" + listOfControlPointTriplets.Count + "-" + gapFromEndToStart_isClosed + "-" + controlPointTriplet_atSegmentStartPreInsert.anchorPoint.junctureType + "-" + controlPointTriplet_atSegmentEndPreInsert.anchorPoint.junctureType); + return; + } + + InternalDXXL_BezierControlPointTriplet2D newlyCreatedControlPointTriplet = InsertUninitializedNewControlPointIntoList(i_startOfSegmentPreInsert); + Vector2 initialDirection_normalized = Vector2.right; //-> is anyway not used, but immediately overwritten inside this function + newlyCreatedControlPointTriplet.Initialize(this, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialDirection_normalized, junctureType_ofNewlyCreatedPoints); + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + newlyCreatedControlPointTriplet.forwardHelperPoint.ChangeUsedState(false, false); + + Vector2 from_anchorPosOfPreInsertStartPoint_to_preInsertEndPointsBackwardHelper_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace() - controlPointTriplet_atSegmentStartPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace(); + Vector2 posOfBackwardHelper_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentStartPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace() + from_anchorPosOfPreInsertStartPoint_to_preInsertEndPointsBackwardHelper_inUnitsOfGlobalSpace * controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + newlyCreatedControlPointTriplet.backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfBackwardHelper_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace, true, null); + + if (controlPointTriplet_atSegmentEndPreInsert.anchorPoint.junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + float new_absDistanceOfBackwardHelperOfPreInsertEndPoint_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace() * (1.0f - controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment); + controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(new_absDistanceOfBackwardHelperOfPreInsertEndPoint_inUnitsOfGlobalSpace, true, null); + } + else + { + LogMessageThatExplainsWhyTheSplineShapeChangedOnPointCreation(false); + } + + SetDefaultJunctureType_forCase_createInsideQuadraticSegment(newlyCreatedControlPointTriplet, "after", "start"); + } + + void SetDefaultJunctureType_forCase_createInsideQuadraticSegment(InternalDXXL_BezierControlPointTriplet2D newlyCreatedControlPointTriplet, string segment_identifier, string disabledWeightPoint_identifier) + { + if (junctureType_ofNewlyCreatedPoints == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned) + { + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned); + LogInfoThatSplineShapeChangedOnPointCreation_dueToDefaultJunctureTypeDoesntFitQuadraticSegment(segment_identifier, disabledWeightPoint_identifier, "an"); + } + + if (junctureType_ofNewlyCreatedPoints == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored); + LogInfoThatSplineShapeChangedOnPointCreation_dueToDefaultJunctureTypeDoesntFitQuadraticSegment(segment_identifier, disabledWeightPoint_identifier, "a"); + } + } + + void LogInfoThatSplineShapeChangedOnPointCreation_dueToDefaultJunctureTypeDoesntFitQuadraticSegment(string segment_identifier, string disabledWeightPoint_identifier, string indefiniteArticle_ofDefaultJunctureType) + { + Debug.Log("Spline Position Creation Information: The spline segment " + segment_identifier + " the newly created control point doesn't fit the spline shape from before the point was created. The reason for this is that the default juncture type of newly created control points is '" + junctureType_ofNewlyCreatedPoints + "', but the weight point at the " + disabledWeightPoint_identifier + " of the pre-insert segment is disabled. It is not possible to keep the spline shape with " + indefiniteArticle_ofDefaultJunctureType + " " + junctureType_ofNewlyCreatedPoints + " juncture type if not both weight points of the pre-insert segment are enabled."); + } + + void ScaleForwardDistance_ofPreInsertStartPoint(InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentStartPreInsert) + { + if (controlPointTriplet_atSegmentStartPreInsert.anchorPoint.junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + float new_absDistanceOfForwardHelperOfPreInsertStartPoint_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace() * controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(new_absDistanceOfForwardHelperOfPreInsertStartPoint_inUnitsOfGlobalSpace, true, null); + } + else + { + LogMessageThatExplainsWhyTheSplineShapeChangedOnPointCreation(true); + } + } + + void LogMessageThatExplainsWhyTheSplineShapeChangedOnPointCreation(bool theMessageCorrespondsTo_theSplinePartAtPreInsertSTARTpoint_notAtPreInsertENDpoint) + { + string segment_identifier; //-> this is actually only specified to prevent the confusion that the same message could be thrown twice for a single point creation + if (theMessageCorrespondsTo_theSplinePartAtPreInsertSTARTpoint_notAtPreInsertENDpoint) + { + segment_identifier = "before"; + } + else + { + segment_identifier = "after"; + } + Debug.Log("Spline Position Creation Information: The spline segment " + segment_identifier + " the newly created control point doesn't fit the spline shape from before the point was created. The reason for this is that the neighboring control point has a 'mirrored' juncture type. Otherwise the neighboring segment would have changed it's shape."); + } + + void CreateSubdividingControlPoint_insideStraightSegmentThatHasNoHelpers(int i_startOfSegmentPreInsert, Vector2 posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentStartPreInsert, InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_atSegmentEndPreInsert) + { + InternalDXXL_BezierControlPointTriplet2D newlyCreatedControlPointTriplet = InsertUninitializedNewControlPointIntoList(i_startOfSegmentPreInsert); + Vector2 initialDirection_normalized = Vector2.right; //-> is anyway not used, but immediately overwritten inside this function + newlyCreatedControlPointTriplet.Initialize(this, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialDirection_normalized, junctureType_ofNewlyCreatedPoints); + + Vector2 initialPosOfForwardHelper_inUnitsOfGlobalSpace = UtilitiesDXXL_Math.GetCenterBetweenTwoPoints(posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentEndPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace()); + newlyCreatedControlPointTriplet.forwardHelperPoint.SetPos_inUnitsOfGlobalSpace(initialPosOfForwardHelper_inUnitsOfGlobalSpace, true, null); + + Vector2 initialPosOfBackwardHelper_inUnitsOfGlobalSpace = UtilitiesDXXL_Math.GetCenterBetweenTwoPoints(posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentStartPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace()); + newlyCreatedControlPointTriplet.backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(initialPosOfBackwardHelper_inUnitsOfGlobalSpace, true, null); + } + + InternalDXXL_BezierControlPointTriplet2D InsertUninitializedNewControlPointIntoList(int i_startOfSegmentPreInsert) + { + InternalDXXL_BezierControlPointTriplet2D newControlPointTriplet = new InternalDXXL_BezierControlPointTriplet2D(); + int i_insertionSlot = i_startOfSegmentPreInsert + 1; + listOfControlPointTriplets.Insert(i_insertionSlot, newControlPointTriplet); + ReassignIndexesToAllControlPoints(); + return newControlPointTriplet; + } + + public void ReassignIndexesToAllControlPoints() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].ReassignIndexInsideControlPointsList(i); + } + } + + void InitializeFirstControlPoint() + { + Vector2 initialPos_inUnitsOfGlobalSpace = Get_originPos_ofActiveDrawSpace_inUnitsOfGlobalSpace(); + Vector2 initialForwardDir_inUnitsOfGlobalSpace_normalized = Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + + listOfControlPointTriplets[0].Initialize(this, initialPos_inUnitsOfGlobalSpace, initialForwardDir_inUnitsOfGlobalSpace_normalized, junctureType_ofNewlyCreatedPoints); + + if (gapFromEndToStart_isClosed == false) + { + listOfControlPointTriplets[0].backwardHelperPoint.ChangeUsedState(false, false); + listOfControlPointTriplets[0].forwardHelperPoint.ChangeUsedState(false, false); + listOfControlPointTriplets[0].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + } + } + + void InitializeNewlyCreatedControlPoint_atSplineEnd() + { + int i_ofNewControlPoint = listOfControlPointTriplets.Count - 1; //"i_ofNewControlPoint" is guaranteed bigger than 0 here, so the controlPoint list has at least 2 items + InternalDXXL_BezierControlPointTriplet2D previouslyLastControlPointTriplet = GetPreviousControlPointTriplet(i_ofNewControlPoint, false); + Vector2 previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized = Get_previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized(previouslyLastControlPointTriplet); + float distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace = Get_distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace(); + Vector2 initialPos_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace = previouslyLastControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace() + previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized * distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace; + Vector2 initialForwardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized = Get_initialFowardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized(previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized); + + listOfControlPointTriplets[i_ofNewControlPoint].Initialize(this, initialPos_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialForwardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized, junctureType_ofNewlyCreatedPoints); + + if (gapFromEndToStart_isClosed == false) + { + listOfControlPointTriplets[i_ofNewControlPoint].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + listOfControlPointTriplets[i_ofNewControlPoint].forwardHelperPoint.ChangeUsedState(false, false); + + int i_ofPreviouslyLastControlPoint = i_ofNewControlPoint - 1; + if (listOfControlPointTriplets[i_ofPreviouslyLastControlPoint].IsEndPointToVoid_atStartOrEndOfAnUnclosedSpline() == false) + { + listOfControlPointTriplets[i_ofPreviouslyLastControlPoint].anchorPoint.SetJunctureType(junctureType_ofNewlyCreatedPoints); + } + listOfControlPointTriplets[i_ofPreviouslyLastControlPoint].forwardHelperPoint.ChangeUsedState(true, false); //-> this is for the case when "junctureType_ofNewlyCreatedPoints == kinked". Then "SetJunctureType" doesn't do anything (since the new junctureType doesn't differ from the previous one) and therefore also didn't activate the formerly unused forwardHelper + } + } + + void InitializeNewControlPoint_atSplineStart() + { + //"listOfControlPointRefs.Count" is guaranteed bigger than 0 here, so the controlPoint list has at least 2 items + InternalDXXL_BezierControlPointTriplet2D previouslyFirstControlPointTriplet = listOfControlPointTriplets[1]; + Vector2 previouslyFirstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized = Get_firstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized(previouslyFirstControlPointTriplet); + float distance_from_prevFirstControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace = Get_distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace(); + Vector2 initialPos_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace = previouslyFirstControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace() + previouslyFirstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized * distance_from_prevFirstControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace; + Vector2 initialForwardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized = Get_initialFowardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized(-previouslyFirstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized); + + listOfControlPointTriplets[0].Initialize(this, initialPos_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialForwardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized, junctureType_ofNewlyCreatedPoints); + + if (gapFromEndToStart_isClosed == false) + { + listOfControlPointTriplets[0].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + listOfControlPointTriplets[0].backwardHelperPoint.ChangeUsedState(false, false); + + int i_ofPreviouslyFirstControlPoint = 1; + if (listOfControlPointTriplets[i_ofPreviouslyFirstControlPoint].IsEndPointToVoid_atStartOrEndOfAnUnclosedSpline() == false) + { + listOfControlPointTriplets[i_ofPreviouslyFirstControlPoint].anchorPoint.SetJunctureType(junctureType_ofNewlyCreatedPoints); + } + listOfControlPointTriplets[i_ofPreviouslyFirstControlPoint].backwardHelperPoint.ChangeUsedState(true, false); //-> this is for the case when "junctureType_ofNewlyCreatedPoints == kinked". Then "SetJunctureType" doesn't do anything (since the new junctureType doesn't differ from the previous one) and therefore also didn't activate the formerly unused backwardHelper + } + } + + public Vector2 Get_previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized(InternalDXXL_BezierControlPointTriplet2D previouslyLastControlPointTriplet) + { + //Caller has to take into account: This function may return the zero vector + switch (definitionType_ofDefaultPosOffset) + { + case BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.straightExtentionOfCurveEnd: + return Get_forwardTangent_ofControlPointThatDoesntKnowOfANextOne_inUnitsOfGlobalSpace_normalized(previouslyLastControlPointTriplet); + case BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.customOffset: + Vector2 posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace = Get_posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace(); + return UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace); + default: + return Vector2.right; + } + } + + public Vector2 Get_forwardTangent_ofControlPointThatDoesntKnowOfANextOne_inUnitsOfGlobalSpace_normalized(InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_thatDoesntKnowOfANextOne) + { + if (controlPointTriplet_thatDoesntKnowOfANextOne.backwardHelperPoint.isUsed) + { + return (-controlPointTriplet_thatDoesntKnowOfANextOne.anchorPoint.Get_direction_toBackward_inUnitsOfGlobalSpace_normalized()); + } + else + { + InternalDXXL_BezierControlSubPoint2D previousUsedNonSuperimposedSubPoint = controlPointTriplet_thatDoesntKnowOfANextOne.backwardHelperPoint.GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + if (previousUsedNonSuperimposedSubPoint != null) + { + Vector2 previousUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace = controlPointTriplet_thatDoesntKnowOfANextOne.anchorPoint.GetPos_inUnitsOfGlobalSpace() - previousUsedNonSuperimposedSubPoint.GetPos_inUnitsOfGlobalSpace(); + Vector2 previousUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(previousUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(previousUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized)) + { + return Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + else + { + return previousUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized; + } + } + else + { + return Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + } + } + + public Vector2 Get_firstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized(InternalDXXL_BezierControlPointTriplet2D previouslyFirstControlPointTriplet) + { + //Caller has to take into account: This function may return the zero vector + switch (definitionType_ofDefaultPosOffset) + { + case BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.straightExtentionOfCurveEnd: + return Get_backwardTangent_ofControlPointThatDoesntKnowOfAPreviousOne_inUnitsOfGlobalSpace_normalized(previouslyFirstControlPointTriplet); + case BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.customOffset: + Vector2 posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace = Get_posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace(); + return (-UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace)); + default: + return Vector2.right; + } + } + + public Vector2 Get_backwardTangent_ofControlPointThatDoesntKnowOfAPreviousOne_inUnitsOfGlobalSpace_normalized(InternalDXXL_BezierControlPointTriplet2D controlPointTriplet_thatDoesntKnowOfAPreviousOne) + { + if (controlPointTriplet_thatDoesntKnowOfAPreviousOne.forwardHelperPoint.isUsed) + { + return (-controlPointTriplet_thatDoesntKnowOfAPreviousOne.anchorPoint.Get_direction_toForward_inUnitsOfGlobalSpace_normalized()); + } + else + { + InternalDXXL_BezierControlSubPoint2D nextUsedNonSuperimposedSubPoint = controlPointTriplet_thatDoesntKnowOfAPreviousOne.forwardHelperPoint.GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + if (nextUsedNonSuperimposedSubPoint != null) + { + Vector2 nextUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace = controlPointTriplet_thatDoesntKnowOfAPreviousOne.anchorPoint.GetPos_inUnitsOfGlobalSpace() - nextUsedNonSuperimposedSubPoint.GetPos_inUnitsOfGlobalSpace(); + Vector2 nextUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(nextUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(nextUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized)) + { + return (-Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized()); + } + else + { + return nextUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized; + } + } + else + { + return (-Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized()); + } + } + } + + public float Get_distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace() + { + switch (definitionType_ofDefaultPosOffset) + { + case BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.straightExtentionOfCurveEnd: + return TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace); + case BezierSplineDrawer.DefinitionType_ofDefaultPosOffset.customOffset: + return Get_posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace().magnitude; + default: + return 1.0f; + } + } + + Vector2 Get_initialFowardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized(Vector2 forwardDirThatRepresents_asCurveEnd_inUnitsOfGlobalSpace_normalized) + { + //"forwardDirThatRepresents_asCurveEnd_inUnitsOfGlobalSpace_normalized" may be zero vector here. + switch (definitionType_ofDefaultRot) + { + case BezierSplineDrawer.DefinitionType_ofDefaultRot.sameAsCurveEnd: + return ReturnGivenVector_orForTooShortVectorsFallbackToActiveDrawSpaceForward(forwardDirThatRepresents_asCurveEnd_inUnitsOfGlobalSpace_normalized); + case BezierSplineDrawer.DefinitionType_ofDefaultRot.customOrientation: + Vector2 forwardDirOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace = Get_orientationOfNewlyCreatedPointAsForwardDirection_atSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace(); + Vector2 forwardDirOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(forwardDirOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace); + return ReturnGivenVector_orForTooShortVectorsFallbackToActiveDrawSpaceForward(forwardDirOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace_normalized); + default: + return Vector2.right; + } + } + + Vector2 ReturnGivenVector_orForTooShortVectorsFallbackToActiveDrawSpaceForward(Vector2 givenVector_normalizedOrTooShort) + { + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(givenVector_normalizedOrTooShort)) + { + return Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + else + { + return givenVector_normalizedOrTooShort; + } + } + + public void SetSelectedListSlot(int i_toSelect) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].isHighlighted = (i == i_toSelect); + } + } + + public int Get_i_ofFirstHighlightedControlPoint() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].isHighlighted) + { + return i; + } + } + return (-1); + } + + public int GetNumberOfHighlightedControlPoints() + { + int number = 0; + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].isHighlighted) + { + number++; + } + } + return number; + } + + public bool IsFirstControlPoint(int i) + { + return (i == 0); + } + + public bool IsLastControlPoint(int i) + { + return (i == (listOfControlPointTriplets.Count - 1)); + } + + public bool IsFirstControlPoint(InternalDXXL_BezierControlPointTriplet2D controlPoint_toCheck) + { + if (listOfControlPointTriplets.Count > 0) + { + return (listOfControlPointTriplets[0] == controlPoint_toCheck); + } + else + { + return false; + } + } + + public bool IsLastControlPoint(InternalDXXL_BezierControlPointTriplet2D controlPoint_toCheck) + { + if (listOfControlPointTriplets.Count > 0) + { + return (listOfControlPointTriplets[listOfControlPointTriplets.Count - 1] == controlPoint_toCheck); + } + else + { + return false; + } + } + + public InternalDXXL_BezierControlPointTriplet2D GetNextControlPointTriplet(int i_ofRequestingControlPoint, bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (gapFromEndToStart_isClosed) + { + if (listOfControlPointTriplets.Count == 0) + { + return null; + } + else + { + if (listOfControlPointTriplets.Count == 1) + { + if (allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (i_ofRequestingControlPoint != 0) + { + UtilitiesDXXL_Log.PrintErrorCode("71-" + i_ofRequestingControlPoint); + } + return listOfControlPointTriplets[0]; + } + else + { + return null; + } + } + else + { + int i_ofNextControlPoint = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i_ofRequestingControlPoint + 1, listOfControlPointTriplets.Count); + return listOfControlPointTriplets[i_ofNextControlPoint]; + } + } + } + else + { + if (IsLastControlPoint(i_ofRequestingControlPoint)) + { + return null; + } + else + { + return listOfControlPointTriplets[i_ofRequestingControlPoint + 1]; + } + } + } + + public InternalDXXL_BezierControlPointTriplet2D GetPreviousControlPointTriplet(int i_ofRequestingControlPoint, bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (gapFromEndToStart_isClosed) + { + if (listOfControlPointTriplets.Count == 0) + { + return null; + } + else + { + if (listOfControlPointTriplets.Count == 1) + { + if (allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (i_ofRequestingControlPoint != 0) + { + UtilitiesDXXL_Log.PrintErrorCode("72-" + i_ofRequestingControlPoint); + } + return listOfControlPointTriplets[0]; + } + else + { + return null; + } + } + else + { + int i_ofPreviousControlPoint = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i_ofRequestingControlPoint - 1, listOfControlPointTriplets.Count); + return listOfControlPointTriplets[i_ofPreviousControlPoint]; + } + } + } + else + { + if (IsFirstControlPoint(i_ofRequestingControlPoint)) + { + return null; + } + else + { + return listOfControlPointTriplets[i_ofRequestingControlPoint - 1]; + } + } + } + + public InternalDXXL_BezierControlPointTriplet2D GetNextControlPointTriplet(InternalDXXL_BezierControlPointTriplet2D controlPoint_forWhichToGetTheNextNeighbor, bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return GetNextControlPointTriplet(controlPoint_forWhichToGetTheNextNeighbor.i_ofThisPoint_insideControlPointsList, allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + + public InternalDXXL_BezierControlPointTriplet2D GetPreviousControlPointTriplet(InternalDXXL_BezierControlPointTriplet2D controlPoint_forWhichToGetThePreviousNeighbor, bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return GetPreviousControlPointTriplet(controlPoint_forWhichToGetThePreviousNeighbor.i_ofThisPoint_insideControlPointsList, allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + + Vector2 Get_posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace() + { + return Get_customVector2_1_inGlobalSpaceUnits(); + } + + Vector2 Get_orientationOfNewlyCreatedPointAsForwardDirection_atSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace() + { + return Get_customVector2_2_inGlobalSpaceUnits(); + } + + public Vector2 Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized() + { + switch (drawSpace) + { + case BezierSplineDrawer.DrawSpace.global: + return Vector2.right; + case BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject: + Vector2 transformRight_asV2 = transform.right; + Vector2 transformRight_asV2_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(transformRight_asV2); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(transformRight_asV2_normalized)) + { + return Vector2.right; + } + else + { + return transformRight_asV2_normalized; + } + default: + return Vector2.right; + } + } + + public Vector3 Get_originPos_ofActiveDrawSpace_inUnitsOfGlobalSpace() + { + switch (drawSpace) + { + case BezierSplineDrawer.DrawSpace.global: + return new Vector3(0.0f, 0.0f, GetZPos_global_for2D()); + case BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject: + return new Vector3(transform.position.x, transform.position.y, GetZPos_global_for2D()); + default: + return new Vector3(0.0f, 0.0f, GetZPos_global_for2D()); + } + } + + public void ChangeDrawSpace(BezierSplineDrawer.DrawSpace newDrawSpace) + { + if (newDrawSpace != drawSpace) + { + if (keepWorldPos_duringDrawSpaceChange) + { + //same for both draw space change directions (i.e. "to local space" and "to global space"): + ConvertSplineShape_onDrawSpaceChange_butKeepWorldPos(newDrawSpace); + } + else + { + switch (newDrawSpace) + { + case BezierSplineDrawer.DrawSpace.global: + ConvertSplineShape_fromOldLocalDrawSpace_to_newGlobalDrawSpace(); + break; + case BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject: + ConvertSplineShape_fromOldGlobalDrawSpace_to_newLocalDrawSpace(); + Save_lastTransformStateOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf(); + break; + default: + break; + } + } + SheduleSceneViewRepaint(); + } + } + + void ConvertSplineShape_onDrawSpaceChange_butKeepWorldPos(BezierSplineDrawer.DrawSpace newDrawSpace) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].Save_currentPosConfigInUnitsOfGlobalSpace_as_posConfigAfterSpaceChangeInUnitsOfGlobalSpace(); + } + + drawSpace = newDrawSpace; + + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].ApplySaved_posConfigAfterSpaceChangeInUnitsOfGlobalSpace(); + } + } + + void ConvertSplineShape_fromOldLocalDrawSpace_to_newGlobalDrawSpace() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].Save_currentPosConfigInUnitsOfActiveDrawSpace_as_posConfigAfterSpaceChangeInUnitsOfGlobalSpace(); + } + + drawSpace = BezierSplineDrawer.DrawSpace.global; + + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].ApplySaved_posConfigAfterSpaceChangeInUnitsOfGlobalSpace(); + } + } + + void ConvertSplineShape_fromOldGlobalDrawSpace_to_newLocalDrawSpace() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].Save_currentPosConfigInUnitsOfGlobalSpace_as_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace(); + } + + drawSpace = BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject; + + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].ApplySaved_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace(); + } + } + + void Save_lastTransformStateOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf() + { + lastGlobalPositionOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf = transform.position; + lastGlobalRotationOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf = transform.rotation; + lastLossyScaleOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf = transform.lossyScale; + } + + public void ChangeCloseGapState(bool newStateOf_gapIsClosed) + { + RegisterStateForUndo("Spline Ring State", false, false); + + gapFromEndToStart_isClosed = newStateOf_gapIsClosed; + int i_lastControlPoint = listOfControlPointTriplets.Count - 1; + + if (newStateOf_gapIsClosed == true) + { + //change from "unclosed" to "closed": + listOfControlPointTriplets[0].anchorPoint.SetJunctureType(junctureType_ofNewlyCreatedPoints); + listOfControlPointTriplets[i_lastControlPoint].anchorPoint.SetJunctureType(junctureType_ofNewlyCreatedPoints); + } + else + { + //change from "closed" to "unclosed": + listOfControlPointTriplets[0].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + listOfControlPointTriplets[i_lastControlPoint].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + } + + listOfControlPointTriplets[0].backwardHelperPoint.ChangeUsedState(newStateOf_gapIsClosed, false); + listOfControlPointTriplets[i_lastControlPoint].forwardHelperPoint.ChangeUsedState(newStateOf_gapIsClosed, false); + + SheduleSceneViewRepaint(); + } + + public bool CheckIf_allFoldableHelperPoints_areUnfolded_inTheInspectorList() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].CheckIf_foldableHelperPoints_areUnfolded_inTheInspectorList() == false) + { + return false; + } + } + return true; + } + + public bool CheckIf_allFoldableHelperPoints_areCollapsed_inTheInspectorList() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].CheckIf_foldableHelperPoints_areCollapsed_inTheInspectorList() == false) + { + return false; + } + } + return true; + } + + public void UnfoldAllHelperPointInTheInspectorList() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].UnfoldBothHelperPointInTheInspectorList(); + } + } + + public void CollapseAllHelperPointInTheInspectorList() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].CollapseBothHelperPointInTheInspectorList(); + } + } + + public bool CheckIf_gameobjectToAssign_isAlreadyAssignedAtAnotherSubPointOfTheSpline(GameObject gameobjectToAssign, out int i_ofTripletThatContainsTheSubPointThatAlreadyHasTheGameobjectAssigned, out InternalDXXL_BezierControlSubPoint.SubPointType subPointThatAlreadyHasTheGameobjectAssigned) + { + i_ofTripletThatContainsTheSubPointThatAlreadyHasTheGameobjectAssigned = -1; //not further used + subPointThatAlreadyHasTheGameobjectAssigned = InternalDXXL_BezierControlSubPoint.SubPointType.anchor; //not further used + if (gameobjectToAssign == null) + { + return false; + } + else + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + i_ofTripletThatContainsTheSubPointThatAlreadyHasTheGameobjectAssigned = i; + + if (listOfControlPointTriplets[i].backwardHelperPoint.boundGameobject == gameobjectToAssign) + { + subPointThatAlreadyHasTheGameobjectAssigned = InternalDXXL_BezierControlSubPoint.SubPointType.backwardHelper; + return true; + } + + if (listOfControlPointTriplets[i].anchorPoint.boundGameobject == gameobjectToAssign) + { + subPointThatAlreadyHasTheGameobjectAssigned = InternalDXXL_BezierControlSubPoint.SubPointType.anchor; + return true; + } + + if (listOfControlPointTriplets[i].forwardHelperPoint.boundGameobject == gameobjectToAssign) + { + subPointThatAlreadyHasTheGameobjectAssigned = InternalDXXL_BezierControlSubPoint.SubPointType.forwardHelper; + return true; + } + } + } + return false; + } + + public void RegisterStateForUndo(string nameOfUndoEntry, bool includeTransformsOfAllBoundGameobjects, bool includeConnectionComponentsOfAllBoundGameobjects) + { +#if UNITY_EDITOR + UnityEditor.Undo.RegisterCompleteObjectUndo(this, nameOfUndoEntry); + + if (includeTransformsOfAllBoundGameobjects) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].backwardHelperPoint.boundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].backwardHelperPoint.boundGameobject.transform, nameOfUndoEntry); + } + + if (listOfControlPointTriplets[i].anchorPoint.boundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].anchorPoint.boundGameobject.transform, nameOfUndoEntry); + } + + if (listOfControlPointTriplets[i].forwardHelperPoint.boundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].forwardHelperPoint.boundGameobject.transform, nameOfUndoEntry); + } + } + } + + if (includeConnectionComponentsOfAllBoundGameobjects) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].backwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].backwardHelperPoint.connectionComponent_onBoundGameobject, nameOfUndoEntry); + } + + if (listOfControlPointTriplets[i].anchorPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].anchorPoint.connectionComponent_onBoundGameobject, nameOfUndoEntry); + } + + if (listOfControlPointTriplets[i].forwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].forwardHelperPoint.connectionComponent_onBoundGameobject, nameOfUndoEntry); + } + } + } +#endif + } + + public bool sheduledSceneViewRepaint_hasBeenExecuted = true; + public void SheduleSceneViewRepaint() + { +#if UNITY_EDITOR + sheduledSceneViewRepaint_hasBeenExecuted = false; + UnityEditor.EditorUtility.SetDirty(this); +#endif + } + + public void TryResheduleSceneViewRepaint() + { + //-> This function is necessary, because "EditorUtility.SetDirty(this)" does not reliably lead to scene view repaints + //-> When in "OnInspectorGUI().*.DrawNonSerializedControlPointsList()" a "SheduleSceneViewRepaint()" is issued due to a changed inspector input value, it "mostly" works. + //-> "mostly" means: + //---> if the changed inspector field is e.g. a "Vector2" or "float" then it works + //---> if the changed inspector field is a "enumPopup" then it doesn't work + //-> This function repeats the "SetDirty" until the scene view repaint finally happens. + + if (sheduledSceneViewRepaint_hasBeenExecuted == false) + { + SheduleSceneViewRepaint(); + } + } + + public Vector3 TransformPos_fromUnitsOfActiveDrawSpace_toGlobalSpace(Vector3 posToTransform_inUnitsOfActiveDrawSpace) + { + if (drawSpace == BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject) + { + return transform.TransformPoint(posToTransform_inUnitsOfActiveDrawSpace); + } + else + { + return posToTransform_inUnitsOfActiveDrawSpace; + } + } + + public Vector3 TransformPos_fromGlobalSpace_toUnitsOfActiveDrawSpace(Vector3 posToTransform_inUnitsOfGlobalSpace) + { + if (drawSpace == BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject) + { + return transform.InverseTransformPoint(posToTransform_inUnitsOfGlobalSpace); + } + else + { + return posToTransform_inUnitsOfGlobalSpace; + } + } + + public Vector3 TransformDirection_fromUnitsOfActiveDrawSpace_toGlobalSpace(Vector3 directionToTransform_inUnitsOfActiveDrawSpace) + { + if (drawSpace == BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject) + { + return transform.TransformDirection(directionToTransform_inUnitsOfActiveDrawSpace); + } + else + { + return directionToTransform_inUnitsOfActiveDrawSpace; + } + } + + public Vector3 TransformDirection_fromGlobalSpace_toUnitsOfActiveDrawSpace(Vector3 directionToTransform_inUnitsOfGlobalSpace) + { + if (drawSpace == BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject) + { + return transform.InverseTransformDirection(directionToTransform_inUnitsOfGlobalSpace); + } + else + { + return directionToTransform_inUnitsOfGlobalSpace; + } + } + + public float TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(float lengthToTransform_inUnitsOfActiveDrawSpace) + { + //This function only works correctly if all transforms of the parenting hierarchy have a homogeneous scale + if (drawSpace == BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject) + { + return (lengthToTransform_inUnitsOfActiveDrawSpace * transform.lossyScale.x); + } + else + { + return lengthToTransform_inUnitsOfActiveDrawSpace; + } + } + + public float TransformLength_fromGlobalSpace_toUnitsOfActiveDrawSpace(float lengthToTransform_inUnitsOfGlobalSpace) + { + //This function only works correctly if all transforms of the parenting hierarchy have a homogeneous scale + if ((drawSpace == BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject) && (UtilitiesDXXL_Math.ApproximatelyZero(transform.lossyScale.x) == false)) + { + return (lengthToTransform_inUnitsOfGlobalSpace / transform.lossyScale.x); + } + else + { + return lengthToTransform_inUnitsOfGlobalSpace; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/2D/BezierSplineDrawer2D.cs.meta b/Runtime/DrawDebugLibrary/components/2D/BezierSplineDrawer2D.cs.meta new file mode 100644 index 0000000..264e1a1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/BezierSplineDrawer2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b9700223156c2d4b9c92bf7c0f208b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/2D/LineDrawer2D.cs b/Runtime/DrawDebugLibrary/components/2D/LineDrawer2D.cs new file mode 100644 index 0000000..c23328f --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/LineDrawer2D.cs @@ -0,0 +1,160 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/2D/Line Drawer 2D")] + public class LineDrawer2D : LineDrawer + { + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + + customVector2Configs[0].picker_isOutfolded = true; + customVector2Configs[0].source = CustomVector2Source.transformsRight; + customVector2Configs[0].clipboardForManualInput = Vector2.right; + customVector2Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector2Configs[2].source = CustomVector2Source.manualInput; + customVector2Configs[2].clipboardForManualInput = Vector2.zero; + customVector2Configs[2].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector2Configs[3].source = CustomVector2Source.manualInput; + customVector2Configs[3].clipboardForManualInput = Vector2.right; + customVector2Configs[3].vectorInterpretation = VectorInterpretation.globalSpace; + + endPlates_size = 0.1f; //is initially disabled due to "endPlatesConfig" + lineStyle_underTension = DrawBasics.LineStyle.sine; + } + + public override void DrawVisualizedObject() + { + float used_enlargeSmallTextToThisMinTextSize_value = enlargeSmallTextToThisMinTextSize ? enlargeSmallTextToThisMinTextSize_value : 0.0f; + float used_endPlates_size = Set_endPlatesConfig_reversible(); + UtilitiesDXXL_DrawBasics.Set_shiftTextPosOnLines_toNonIntersecting_reversible(shiftTextPosOnLines_toNonIntersecting); + UtilitiesDXXL_DrawBasics.Set_relSizeOfTextOnLines_reversible(relSizeOfTextOnLines); + GetLineStartPosAndDirection(out Vector2 lineStartPosition, out Vector2 vector_fromLineStart_toLineEnd); + + switch (lineType) + { + case LineType.standardLine: + if (useDifferentEndColor) + { + precedingLineAnimationProgress = LineFrom_fadeableAnimSpeed_2D.InternalDraw_withColorFade(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, endColor, lineWidth, text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, used_endPlates_size, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + precedingLineAnimationProgress = LineFrom_fadeableAnimSpeed_2D.InternalDraw(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, lineWidth, text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, used_endPlates_size, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + break; + case LineType.vector: + switch (conesConfig) + { + case ConesConfig.bothSides: + DrawBasics2D.VectorFrom(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, lineWidth, text_inclGlobalMarkupTags, coneLength_forStraightVectors, true, GetZPos_global_for2D(), addNormalizedMarkingText, used_enlargeSmallTextToThisMinTextSize_value, writeComponentValuesAsText, used_endPlates_size, 0.0f, hiddenByNearerObjects); + break; + case ConesConfig.onlyAtStart: + DrawBasics2D.VectorTo(-vector_fromLineStart_toLineEnd, lineStartPosition, startColor, lineWidth, text_inclGlobalMarkupTags, coneLength_forStraightVectors, false, GetZPos_global_for2D(), addNormalizedMarkingText, used_enlargeSmallTextToThisMinTextSize_value, writeComponentValuesAsText, used_endPlates_size, 0.0f, hiddenByNearerObjects); + break; + case ConesConfig.onlyAtEnd: + DrawBasics2D.VectorFrom(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, lineWidth, text_inclGlobalMarkupTags, coneLength_forStraightVectors, false, GetZPos_global_for2D(), addNormalizedMarkingText, used_enlargeSmallTextToThisMinTextSize_value, writeComponentValuesAsText, used_endPlates_size, 0.0f, hiddenByNearerObjects); + break; + default: + break; + } + break; + case LineType.vectorWithExtention: + float used_forceFixedConeLength_value = forceFixedConeLength ? forceFixedConeLength_value : 0.0f; + DrawEngineBasics.RayLineExtended2D(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, lineWidth, text_inclGlobalMarkupTags, GetZPos_global_for2D(), used_forceFixedConeLength_value, addNormalizedMarkingText, used_enlargeSmallTextToThisMinTextSize_value, extentionLength, 0.0f, hiddenByNearerObjects); + break; + case LineType.blinkingLine: + float used_blinkDurationInSec = ((Application.isPlaying == false) && (animationDuringEditMode == false)) ? float.MaxValue : blinkDurationInSec; //-> this prevents a problem in the situation where "animationDuringEditMode" has been disabled in a blink phase where the line is not possible. Otherwise in such cases the line would permanently invisible. + DrawBasics2D.BlinkingRay(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, used_blinkDurationInSec, lineWidth, text_inclGlobalMarkupTags, lineStyle, blinkColor, GetZPos_global_for2D(), stylePatternScaleFactor, used_endPlates_size, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + break; + case LineType.lineUnderTension: + DrawBasics2D.RayUnderTension(lineStartPosition, vector_fromLineStart_toLineEnd, relaxedLength, relaxedColor, lineStyle_underTension, stretchFactor_forStretchedTensionColor, color_forStretchedTension, stretchFactor_forSqueezedTensionColor, color_forSqueezedTension, lineWidth, text_inclGlobalMarkupTags, alphaOfReferenceLengthDisplay, GetZPos_global_for2D(), stylePatternScaleFactor, used_endPlates_size, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + break; + case LineType.movingArrowsLine: + precedingLineAnimationProgress = MovingArrowsRay_fadeableAnimSpeed_2D.InternalDraw(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, lineWidth_ofMovingArrowsLine, distanceBetweenArrows, lengthOfArrows, text_inclGlobalMarkupTags, GetZPos_global_for2D(), animationSpeed_ofMovingArrowsLine, precedingLineAnimationProgress, backwardAnimationFlipsArrowDirection, used_endPlates_size, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects); + break; + case LineType.lineWithAlternatingColors: + precedingLineAnimationProgress = RayWithAlternatingColors_fadeableAnimSpeed_2D.InternalDraw(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, alternatingColor, lineWidth, lengthOfStripes, text_inclGlobalMarkupTags, GetZPos_global_for2D(), animationSpeed, precedingLineAnimationProgress, used_endPlates_size, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + break; + default: + break; + } + + UtilitiesDXXL_DrawBasics.Reverse_shiftTextPosOnLines_toNonIntersecting(); + UtilitiesDXXL_DrawBasics.Reverse_relSizeOfTextOnLines(); + Reverse_endPlatesConfig(); + + TrySheduleRepaintSceneViewForAnimationOutsidePlaymode(); + } + + void GetLineStartPosAndDirection(out Vector2 lineStartPosition, out Vector2 vector_fromLineStart_toLineEnd) + { + Vector2 lineEndPosition; + switch (lineDefinitionMode) + { + case LineDefinitionMode.startPositionAndEndPosition: + lineStartPosition = GetLineStartPosition_fromDefineStartPosSection(); + lineEndPosition = GetLineEndPosition_fromDefineEndPosSection(); + vector_fromLineStart_toLineEnd = lineEndPosition - lineStartPosition; + break; + case LineDefinitionMode.startPositionAndDirectionVectorToEndPosition: + lineStartPosition = GetLineStartPosition_fromDefineStartPosSection(); + vector_fromLineStart_toLineEnd = Get_customVector2_1_inGlobalSpaceUnits(); + break; + case LineDefinitionMode.endPositionAndDirectionVectorToIt: + lineEndPosition = GetLineEndPosition_fromDefineEndPosSection(); + vector_fromLineStart_toLineEnd = Get_customVector2_1_inGlobalSpaceUnits(); + lineStartPosition = lineEndPosition - vector_fromLineStart_toLineEnd; + break; + default: + lineStartPosition = Vector2.zero; + vector_fromLineStart_toLineEnd = Vector2.right; + break; + } + } + + Vector2 GetLineStartPosition_fromDefineStartPosSection() + { + switch (positionDefinitionOption_ofStartPos) + { + case PositionDefinitionOption.positionOfThisGameobjectPlusOffset: + return GetDrawPos2D_global(); + case PositionDefinitionOption.positionOfOtherGameobjectPlusOffset: + bool theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject = (coordinateSpaceForLocalOffsetOnOtherGameobject_forStartPos == CoordinateSpaceForLocalOffset.useLocalSpaceDefinedByTransformOnOtherGameobject); + return GetDrawPos2D_ofPartnerGameobject_global(theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject); + case PositionDefinitionOption.chooseFree: + return Get_customVector2_3_inGlobalSpaceUnits(); + default: + return Vector2.zero; + } + } + + Vector2 GetLineEndPosition_fromDefineEndPosSection() + { + switch (positionDefinitionOption_ofEndPos) + { + case PositionDefinitionOption.positionOfThisGameobjectPlusOffset: + return GetDrawPos2D_global_independentAlternativeValue(); + case PositionDefinitionOption.positionOfOtherGameobjectPlusOffset: + bool theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject = (coordinateSpaceForLocalOffsetOnOtherGameobject_forEndPos == CoordinateSpaceForLocalOffset.useLocalSpaceDefinedByTransformOnOtherGameobject); + return GetDrawPos2D_ofPartnerGameobject_global_independentAlternativeValue(theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject); + case PositionDefinitionOption.chooseFree: + return Get_customVector2_4_inGlobalSpaceUnits(); + default: + return Vector2.one; + } + } + + public override float GetLineLength() + { + GetLineStartPosAndDirection(out Vector2 lineStartPosition, out Vector2 vector_fromLineStart_toLineEnd); + return vector_fromLineStart_toLineEnd.magnitude; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/2D/LineDrawer2D.cs.meta b/Runtime/DrawDebugLibrary/components/2D/LineDrawer2D.cs.meta new file mode 100644 index 0000000..fd79c75 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/LineDrawer2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7faa130aef499634f8de3d45f22be81f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/2D/MeasurementVisualizer2D.cs b/Runtime/DrawDebugLibrary/components/2D/MeasurementVisualizer2D.cs new file mode 100644 index 0000000..ead5a39 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/MeasurementVisualizer2D.cs @@ -0,0 +1,164 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/2D/Measurement Visualizer 2D")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class MeasurementVisualizer2D : VisualizerParent + { + public enum MeasurementType { distanceBetweenPoints, distanceThresholdBetweenPoints, distanceFromPointToLine, angleBetweenVectors, angleFromLineToLine }; + [SerializeField] MeasurementType measurementType = MeasurementType.distanceBetweenPoints; + + [SerializeField] Color color1 = DrawMeasurements.defaultColor1; + [SerializeField] Color color2 = DrawMeasurements.defaultColor2; + [SerializeField] public bool appearanceBlock_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public float measuredResultValue; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] Color color = DrawBasics.defaultColor; + [SerializeField] float linesWidth = 0.0f; + [SerializeField] float enlargeSmallTextToThisMinTextSize = 0.005f; + [SerializeField] bool addTextForAlternativeAngleUnit = true; + [SerializeField] MeasurementVisualizer.AngleUnit angleUnitToDisplay = MeasurementVisualizer.AngleUnit.degree; + [SerializeField] float forceRadius_value = 1.0f; + [SerializeField] bool useReflexAngleOver180deg = false; + [SerializeField] bool drawBoundaryLines = true; + [SerializeField] bool returnObtuseAngleOver90deg = false; + [SerializeField] string name_ofGeoObject1 = null; + [SerializeField] string name_ofGeoObject2 = null; + [SerializeField] MeasurementVisualizer.DistanceThresholdType distanceThresholdType = MeasurementVisualizer.DistanceThresholdType.one; + [SerializeField] MeasurementVisualizer.PointerConfigOfAngleBetweenVectors pointerConfigOfAngleBetweenVectors = MeasurementVisualizer.PointerConfigOfAngleBetweenVectors.atBothEnds; + [SerializeField] float minimumLineLength_forDistancePointToLine = DrawMeasurements2D.minimumLineLength_forDistancePointToLine; + [SerializeField] float minimumLineLength_forAngleLineToLine = DrawMeasurements2D.minimumLineLength_forAngleLineToLine; + + //only for distanceThreshold: + [SerializeField] float smallerThresholdDistance = 1.0f; + [SerializeField] float biggerThresholdDistance = 2.0f; + [SerializeField] bool displayDistanceAlsoAsText = false; + [SerializeField] MeasurementVisualizer.ExactlyOnThresholdBehaviour exactlyOnThresholdBehaviour = MeasurementVisualizer.ExactlyOnThresholdBehaviour.countAsShorterThanThreshold; + + [SerializeField] DrawBasics.LineStyle overwriteStyle_forNear = DrawBasics.LineStyle.electricNoise; + [SerializeField] DrawBasics.LineStyle overwriteStyle_forMiddle = DrawBasics.LineStyle.electricImpulses; + [SerializeField] DrawBasics.LineStyle overwriteStyle_forFar = DrawBasics.LineStyle.solid; + + [SerializeField] Color overwriteColor_forNear_oneThresholdVersion = UtilitiesDXXL_Colors.red_boolFalse; + [SerializeField] Color overwriteColor_forFar_oneThresholdVersion = UtilitiesDXXL_Colors.green_boolTrue; + + [SerializeField] Color overwriteColor_forNear_twoThresholdsVersion = UtilitiesDXXL_Colors.red_lineThresholdFarDistance; + [SerializeField] Color overwriteColor_forMiddle_twoThresholdsVersion = UtilitiesDXXL_Colors.orange_lineThresholdMiddleDistance; + [SerializeField] Color overwriteColor_forFar_twoThresholdsVersion = UtilitiesDXXL_Colors.green_lineThresholdNearDistance; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + endPlates_size = 0.0f; + coneLength_forStraightVectors = 0.10f; + coneLength_forCircledVectors = 0.13f; + drawPosOffset2DSection_isOutfolded = true; + drawPosOffset2DSection_ofPartnerGameobject_isOutfolded = true; + + customVector2Configs[0].picker_isOutfolded = true; + customVector2Configs[0].source = CustomVector2Source.transformsRight; + customVector2Configs[0].clipboardForManualInput = Vector2.right; + customVector2Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector2Configs[1].picker_isOutfolded = true; + customVector2Configs[1].source = CustomVector2Source.manualInput; + customVector2Configs[1].clipboardForManualInput = Vector2.one; + customVector2Configs[1].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector2Configs[2].picker_isOutfolded = true; + customVector2Configs[2].source = CustomVector2Source.transformsRight; + customVector2Configs[2].clipboardForManualInput = Vector2.one; + customVector2Configs[2].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector2ofPartnerGameobject_picker_isOutfolded = true; + source_ofCustomVector2ofPartnerGameobject = CustomVector2Source.transformsRight; + customVector2ofPartnerGameobject_clipboardForManualInput = Vector2.one; + vectorInterpretation_ofCustomVector2ofPartnerGameobject = VectorInterpretation.globalSpace; + } + + public override void DrawVisualizedObject() + { + UtilitiesDXXL_Measurements.Set_defaultColor1_reversible(color1); + UtilitiesDXXL_Measurements.Set_defaultColor2_reversible(color2); + switch (measurementType) + { + case MeasurementType.distanceBetweenPoints: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(coneLength_interpretation_forStraightVectors); + measuredResultValue = DrawMeasurements2D.Distance(GetDrawPos2D_global(), GetDrawPos2D_ofPartnerGameobject_global(), color, linesWidth, text_inclGlobalMarkupTags, GetZPos_global_for2D(), coneLength_forStraightVectors, enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + break; + case MeasurementType.distanceThresholdBetweenPoints: + switch (distanceThresholdType) + { + case MeasurementVisualizer.DistanceThresholdType.one: + UtilitiesDXXL_DrawBasics.Set_endPlates_sizeInterpretation_reversible(endPlates_sizeInterpretation); + DrawMeasurements2D.DistanceThreshold(GetDrawPos2D_global(), GetDrawPos2D_ofPartnerGameobject_global(), smallerThresholdDistance, text_inclGlobalMarkupTags, displayDistanceAlsoAsText, linesWidth, GetZPos_global_for2D(), ExactlyThresholdLength_countsAsShorter(), endPlates_size, overwriteStyle_forNear, overwriteStyle_forFar, overwriteColor_forNear_oneThresholdVersion, overwriteColor_forFar_oneThresholdVersion, enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_endPlates_sizeInterpretation(); + break; + case MeasurementVisualizer.DistanceThresholdType.two: + UtilitiesDXXL_DrawBasics.Set_endPlates_sizeInterpretation_reversible(endPlates_sizeInterpretation); + DrawMeasurements2D.DistanceThresholds(GetDrawPos2D_global(), GetDrawPos2D_ofPartnerGameobject_global(), smallerThresholdDistance, biggerThresholdDistance, text_inclGlobalMarkupTags, displayDistanceAlsoAsText, linesWidth, GetZPos_global_for2D(), ExactlyThresholdLength_countsAsShorter(), endPlates_size, overwriteStyle_forNear, overwriteStyle_forMiddle, overwriteStyle_forFar, overwriteColor_forNear_twoThresholdsVersion, overwriteColor_forMiddle_twoThresholdsVersion, overwriteColor_forFar_twoThresholdsVersion, enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_endPlates_sizeInterpretation(); + break; + default: + break; + } + break; + case MeasurementType.distanceFromPointToLine: + UtilitiesDXXL_Measurements2D.Set_minimumLineLength_forDistancePointToLine_reversible(minimumLineLength_forDistancePointToLine); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(coneLength_interpretation_forStraightVectors); + measuredResultValue = DrawMeasurements2D.DistancePointToLine(GetDrawPos2D_global(), GetDrawPos2D_ofPartnerGameobject_global(), Get_customVector2ofPartnerGameobject_inGlobalSpaceUnits(), color, linesWidth, text_inclGlobalMarkupTags, name_ofGeoObject2, GetZPos_global_for2D(), coneLength_forStraightVectors, enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + UtilitiesDXXL_Measurements2D.Reverse_minimumLineLength_forDistancePointToLine(); + break; + case MeasurementType.angleBetweenVectors: + switch (pointerConfigOfAngleBetweenVectors) + { + case MeasurementVisualizer.PointerConfigOfAngleBetweenVectors.atBothEnds: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(coneLength_interpretation_forCircledVectors); + measuredResultValue = DrawMeasurements2D.AngleSpan(Get_customVector2_1_inGlobalSpaceUnits(), Get_customVector2_2_inGlobalSpaceUnits(), GetDrawPos2D_global_independentAlternativeValue(), color, forceRadius_value, linesWidth, text_inclGlobalMarkupTags, GetZPos_global_for2D(), useReflexAngleOver180deg, DisplayAndReturn_radInsteadOfDeg(), coneLength_forCircledVectors, drawBoundaryLines, addTextForAlternativeAngleUnit, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + break; + case MeasurementVisualizer.PointerConfigOfAngleBetweenVectors.onlyAtStart: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(coneLength_interpretation_forCircledVectors); + measuredResultValue = DrawMeasurements2D.Angle(Get_customVector2_2_inGlobalSpaceUnits(), Get_customVector2_1_inGlobalSpaceUnits(), GetDrawPos2D_global_independentAlternativeValue(), color, forceRadius_value, linesWidth, text_inclGlobalMarkupTags, GetZPos_global_for2D(), useReflexAngleOver180deg, DisplayAndReturn_radInsteadOfDeg(), coneLength_forCircledVectors, drawBoundaryLines, addTextForAlternativeAngleUnit, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + break; + case MeasurementVisualizer.PointerConfigOfAngleBetweenVectors.onlyAtEnd: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(coneLength_interpretation_forCircledVectors); + measuredResultValue = DrawMeasurements2D.Angle(Get_customVector2_1_inGlobalSpaceUnits(), Get_customVector2_2_inGlobalSpaceUnits(), GetDrawPos2D_global_independentAlternativeValue(), color, forceRadius_value, linesWidth, text_inclGlobalMarkupTags, GetZPos_global_for2D(), useReflexAngleOver180deg, DisplayAndReturn_radInsteadOfDeg(), coneLength_forCircledVectors, drawBoundaryLines, addTextForAlternativeAngleUnit, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + break; + default: + break; + } + break; + case MeasurementType.angleFromLineToLine: + UtilitiesDXXL_Measurements2D.Set_minimumLineLength_forAngleLineToLine_reversible(minimumLineLength_forAngleLineToLine); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(coneLength_interpretation_forCircledVectors); + measuredResultValue = DrawMeasurements2D.AngleLineToLine(GetDrawPos2D_global(), Get_customVector2_3_inGlobalSpaceUnits(), GetDrawPos2D_ofPartnerGameobject_global(), Get_customVector2ofPartnerGameobject_inGlobalSpaceUnits(), color, linesWidth, text_inclGlobalMarkupTags, name_ofGeoObject1, name_ofGeoObject2, GetZPos_global_for2D(), returnObtuseAngleOver90deg, DisplayAndReturn_radInsteadOfDeg(), coneLength_forCircledVectors, addTextForAlternativeAngleUnit, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + UtilitiesDXXL_Measurements2D.Reverse_minimumLineLength_forAngleLineToLine(); + break; + default: + break; + } + + UtilitiesDXXL_Measurements.Reverse_defaultColor1(); + UtilitiesDXXL_Measurements.Reverse_defaultColor2(); + } + + bool DisplayAndReturn_radInsteadOfDeg() + { + return (angleUnitToDisplay == MeasurementVisualizer.AngleUnit.radians); + } + + bool ExactlyThresholdLength_countsAsShorter() + { + return (exactlyOnThresholdBehaviour == MeasurementVisualizer.ExactlyOnThresholdBehaviour.countAsShorterThanThreshold); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/2D/MeasurementVisualizer2D.cs.meta b/Runtime/DrawDebugLibrary/components/2D/MeasurementVisualizer2D.cs.meta new file mode 100644 index 0000000..bad5eb6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/MeasurementVisualizer2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a20ecf25dae628a4db9e03f54e332a15 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/2D/PhysicsVisualizer2D.cs b/Runtime/DrawDebugLibrary/components/2D/PhysicsVisualizer2D.cs new file mode 100644 index 0000000..b6001df --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/PhysicsVisualizer2D.cs @@ -0,0 +1,907 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/2D/Physics Visualizer 2D")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class PhysicsVisualizer2D : VisualizerParent + { + public enum Shape { collidersOnThisGameobject, box, circle, capsule, rayOrPoint, ray3D }; + [SerializeField] Shape shape = Shape.collidersOnThisGameobject; + + [SerializeField] CollisionType collisionType = CollisionType.cast; + + [SerializeField] WantedHits wantedHits = WantedHits.all; + + [SerializeField] bool distanceIsInfinityRespToOtherGO = true; + [SerializeField] float adjustedDistance = 10.0f; + float used_distance; + + [SerializeField] Vector2 sizeScaleFactors_ofCastRespCheckedBox = Vector2.one; + [SerializeField] float radiusScaleFactor_ofCastRespCheckedCircle = 0.5f; + [SerializeField] Vector2 sizeScaleFactors_ofCastRespCheckedCapsule = new Vector2(0.5f, 1.0f); + [SerializeField] CapsuleDirection2D capsuleDirection2D_ofManuallyConstructedCapsuleMeaningNotFromCollider = CapsuleDirection2D.Vertical; + public enum ShapeRotationType { transformsRotationPlusOptionalAdditionalRotation, customRotationIndependentFromTransform }; + [SerializeField] public ShapeRotationType shapeRotationType = ShapeRotationType.transformsRotationPlusOptionalAdditionalRotation; + + [SerializeField] [Range(0.0f, 360.0f)] float rotationAngleOfShape_additionallyToTransformsAngle = 0.0f; + + BoxCollider2D[] boxColliders2D_onThisGameobject; + CircleCollider2D[] circleColliders2D_onThisGameobject; + CapsuleCollider2D[] capsuleColliders2D_onThisGameobject; + [SerializeField] public bool theGameobjectHasACompatibleAndEnabledCollider; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + List unusedRaycastHitResults = new List(); + List unusedResultColliders = new List(); + + [SerializeField] public bool otherSettings_isFoldedOut = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + [SerializeField] bool excludeCollidersOnThisGO = true; + [SerializeField] bool excludeCollidersOnParentGOs = true; + [SerializeField] bool excludeCollidersOnChildrenGOs = true; + + Collider2D[] allColliders2DOnThisGameobject; + List enabledState_ofAllColliders2DOnThisGO_beforeCurrentDrawOperation = new List(); + [SerializeField] public bool aVisualizedBoxCollider2DOnThisComponent_hasANonZeroEdge; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool aVisualizedBoxCollider2DOnThisComponent_hasAutoTiling; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + Collider2D[] allColliders2DOnThisGameobjectAndOnParents; + List enabledState_ofAllColliders2DOnThisGOPlusParents_beforeCurrentDrawOperation = new List(); + List isOnThisGO_forAllColliders2DOnThisGOPlusParents_beforeCurrentDrawOperation = new List(); + + Collider2D[] allColliders2DOnThisGameobjectAndOnChildren; + List enabledState_ofAllColliders2DOnThisGOPlusChildren_beforeCurrentDrawOperation = new List(); + List isOnThisGO_forAllColliders2DOnThisGOPlusChildren_beforeCurrentDrawOperation = new List(); + + [SerializeField] LayerMask layerMask = Physics2D.DefaultRaycastLayers; //The "Physics2D.DefaultRaycastLayers" already inludes the layer slots that are not yet defined by the users. That means this doesn't have to updated in cases where a user adds a custom defined layer AFTER the creation of this component + + [SerializeField] bool useDepth = false; + [SerializeField] float minDepth = Mathf.NegativeInfinity; + [SerializeField] float maxDepth = Mathf.Infinity; + [SerializeField] bool useOutsideDepth = false; + + [SerializeField] bool useNormalAngle = false; + [SerializeField] [Range(0.0f, 360.0f)] float minNormalAngle = 0.0f; + [SerializeField] [Range(0.0f, 360.0f)] float maxNormalAngle = 360.0f; + [SerializeField] bool useOutsideNormalAngle = false; + + [SerializeField] bool useTriggers = true; + [SerializeField] int numberOfFoundHits = 0; + + //DrawPhysics2D' class global settings: + [SerializeField] Color colorForNonHittingCasts = DrawPhysics2D.colorForNonHittingCasts; + [SerializeField] Color colorForHittingCasts = DrawPhysics2D.colorForHittingCasts; + [SerializeField] Color colorForCastLineBeyondHit = DrawPhysics2D.colorForCastLineBeyondHit; + [SerializeField] Color colorForCastsHitText = DrawPhysics2D.colorForCastsHitText; + [SerializeField] bool doOverwriteColorForCastsHitNormals = false; + [SerializeField] Color overwriteColorForCastsHitNormals = UtilitiesDXXL_Physics2D.Get_defaultColor_ofNormal(); //-> not using "DrawPhysics2D.overwriteColorForCastsHitNormals", since this would be the default color that doesn't represent what the user sees as normal color in the Scene + [SerializeField] float scaleFactor_forCastHitTextSize = DrawPhysics2D.scaleFactor_forCastHitTextSize; + [SerializeField] float castCorridorVisualizerDensity = DrawPhysics2D.castCorridorVisualizerDensity; + [SerializeField] bool drawCastNameTag_atCastOrigin = DrawPhysics2D.drawCastNameTag_atCastOrigin; + [SerializeField] bool drawCastNameTag_atHitPositions = DrawPhysics2D.drawCastNameTag_atHitPositions; + [SerializeField] int maxListedColliders_inOverlapVolumesTextList = DrawPhysics2D.MaxListedColliders_inOverlapVolumesTextList; + [SerializeField] int maxOverlapingCollidersWithUntruncatedText = DrawPhysics2D.maxOverlapingCollidersWithUntruncatedText; + [SerializeField] [Range(0.001f, 0.2f)] float forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = 0.01f; + [SerializeField] float forcedConstantWorldspaceTextSize_forOverlapResultTexts = 0.1f; + [SerializeField] PhysicsVisualizer.SaveDrawnLinesType saveDrawnLinesType = PhysicsVisualizer.Map_visualizationQuality_to_saveDrawnLinesType(DrawPhysics2D.visualizationQuality); + [SerializeField] PhysicsVisualizer.OverlapResultTextSizeInterpretation overlapResultTextSizeInterpretation = PhysicsVisualizer.OverlapResultTextSizeInterpretation.relativeToTheSizeOfTheOverlapingPhysicsShape; + [SerializeField] bool useCustomDirectionForHitResultText = false; + [SerializeField] Vector2 customDirectionForHitResultText = GetInitialValueFor_customDirectionForHitResultText(); + + Color colorForNonHittingCasts_before; + Color colorForHittingCasts_before; + Color colorForCastLineBeyondHit_before; + Color colorForCastsHitText_before; + Color overwriteColorForCastsHitNormals_before; + float scaleFactor_forCastHitTextSize_before; + float castCorridorVisualizerDensity_before; + DrawPhysics.VisualizationQuality visualizationQuality_before; + bool drawCastNameTag_atCastOrigin_before; + bool drawCastNameTag_atHitPositions_before; + int maxListedColliders_inOverlapVolumesTextList_before; + int maxOverlapingCollidersWithUntruncatedText_before; + float forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before; + float forcedConstantWorldspaceTextSize_forOverlapResultTexts_before; + DrawBasics.CameraForAutomaticOrientation cameraForAutomaticOrientation_before; + float custom_zPos_forCastVisualisation_before; + Vector2 directionOfHitResultText_before; + + public override void InitializeValues_onceInComponentLifetime() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = "Collisions2D from " + this.gameObject.name; + text_inclGlobalMarkupTags = "Collisions2D from " + this.gameObject.name; + } + + customVector3Configs[0].picker_isOutfolded = true; + customVector3Configs[0].source = CustomVector3Source.manualInput; + customVector3Configs[0].clipboardForManualInput = Vector3.one; + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector2Configs[0].picker_isOutfolded = true; + customVector2Configs[0].source = CustomVector2Source.rotationAroundZStartingFromRight; + customVector2Configs[0].clipboardForManualInput = Vector2.one; + customVector2Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy() + { + if (shape == Shape.collidersOnThisGameobject) + { + if (CheckIfGameobjectHasASupportedCollider() == false) + { + shape = Shape.box; + } + } + } + + public override void DrawVisualizedObject() + { +#if UNITY_EDITOR + TryFetchCurrentEnabledStateOfColliders2DOnThisGameobjectsHierarchy(); + Save_globalDrawPhysics2DOptions_beforeThisDrawOperation(); + try + { + Set_globalDrawPhysics2DOptions_toValuesFromInpsector(); + TryDisableEnabledStateOfColliders2DOnThisGameobjectsHierarchy(); + CastRespCheckTheColliders2D_andDrawThem(); + } + catch { } + TryRestoreEnabledStateOfColliders2DOnThisGameobjectsHierarchy(); + Restore_globalDrawPhysics2DOptions_toValuesFromBefore(); +#endif + } + + bool CheckIfGameobjectHasASupportedCollider() + { + if ((this.gameObject.GetComponent() == null) && (this.gameObject.GetComponent() == null) && (this.gameObject.GetComponent() == null)) + { + return false; + } + else + { + return true; + } + } + + void TryFetchCurrentEnabledStateOfColliders2DOnThisGameobjectsHierarchy() + { + if (excludeCollidersOnThisGO || excludeCollidersOnParentGOs || excludeCollidersOnChildrenGOs) //The other flag's threads need "allCollidersOnThisGameobject" + { + allColliders2DOnThisGameobject = this.gameObject.GetComponents(); + if (allColliders2DOnThisGameobject != null) + { + for (int i = 0; i < allColliders2DOnThisGameobject.Length; i++) + { + if (allColliders2DOnThisGameobject[i] != null) + { + UtilitiesDXXL_List.AddToABoolList(ref enabledState_ofAllColliders2DOnThisGO_beforeCurrentDrawOperation, allColliders2DOnThisGameobject[i].enabled, i); + } + } + } + } + + if (excludeCollidersOnParentGOs) + { + allColliders2DOnThisGameobjectAndOnParents = this.gameObject.GetComponentsInParent(); + if (allColliders2DOnThisGameobjectAndOnParents != null) + { + for (int i = 0; i < allColliders2DOnThisGameobjectAndOnParents.Length; i++) + { + if (allColliders2DOnThisGameobjectAndOnParents[i] != null) + { + UtilitiesDXXL_List.AddToABoolList(ref enabledState_ofAllColliders2DOnThisGOPlusParents_beforeCurrentDrawOperation, allColliders2DOnThisGameobjectAndOnParents[i].enabled, i); + UtilitiesDXXL_List.AddToABoolList(ref isOnThisGO_forAllColliders2DOnThisGOPlusParents_beforeCurrentDrawOperation, CheckIfCollider2DIsOnThisGameobject(allColliders2DOnThisGameobjectAndOnParents[i]), i); + } + } + } + } + + if (excludeCollidersOnChildrenGOs) + { + allColliders2DOnThisGameobjectAndOnChildren = this.gameObject.GetComponentsInChildren(); + + if (allColliders2DOnThisGameobjectAndOnChildren != null) + { + for (int i = 0; i < allColliders2DOnThisGameobjectAndOnChildren.Length; i++) + { + if (allColliders2DOnThisGameobjectAndOnChildren[i] != null) + { + UtilitiesDXXL_List.AddToABoolList(ref enabledState_ofAllColliders2DOnThisGOPlusChildren_beforeCurrentDrawOperation, allColliders2DOnThisGameobjectAndOnChildren[i].enabled, i); + UtilitiesDXXL_List.AddToABoolList(ref isOnThisGO_forAllColliders2DOnThisGOPlusChildren_beforeCurrentDrawOperation, CheckIfCollider2DIsOnThisGameobject(allColliders2DOnThisGameobjectAndOnChildren[i]), i); + } + } + } + } + } + + bool CheckIfCollider2DIsOnThisGameobject(Collider2D collider2D_toCheckIfItIsOnThisGameobject) + { + if (collider2D_toCheckIfItIsOnThisGameobject != null) + { + if (allColliders2DOnThisGameobject != null) + { + for (int i = 0; i < allColliders2DOnThisGameobject.Length; i++) + { + if (allColliders2DOnThisGameobject[i] != null) + { + if (allColliders2DOnThisGameobject[i] == collider2D_toCheckIfItIsOnThisGameobject) + { + return true; + } + } + } + } + } + return false; + } + + bool GetEnabledStateBeforeCurrentDrawOperation_ofCollider2DComponentOnThisGameobject(Collider2D collider2DD_toRetrieveEnabledStateFor) + { + if (collider2DD_toRetrieveEnabledStateFor != null) + { + if (allColliders2DOnThisGameobject != null) + { + for (int i = 0; i < allColliders2DOnThisGameobject.Length; i++) + { + if (allColliders2DOnThisGameobject[i] != null) + { + if (allColliders2DOnThisGameobject[i] == collider2DD_toRetrieveEnabledStateFor) + { + return enabledState_ofAllColliders2DOnThisGO_beforeCurrentDrawOperation[i]; + } + } + } + } + } + return false; + } + + void TryDisableEnabledStateOfColliders2DOnThisGameobjectsHierarchy() + { + if (excludeCollidersOnThisGO) + { + if (allColliders2DOnThisGameobject != null) + { + for (int i = 0; i < allColliders2DOnThisGameobject.Length; i++) + { + if (allColliders2DOnThisGameobject[i] != null) + { + allColliders2DOnThisGameobject[i].enabled = false; + } + } + } + } + + if (excludeCollidersOnParentGOs) + { + if (allColliders2DOnThisGameobjectAndOnParents != null) + { + for (int i = 0; i < allColliders2DOnThisGameobjectAndOnParents.Length; i++) + { + if (allColliders2DOnThisGameobjectAndOnParents[i] != null) + { + if (isOnThisGO_forAllColliders2DOnThisGOPlusParents_beforeCurrentDrawOperation[i] == false) + { + allColliders2DOnThisGameobjectAndOnParents[i].enabled = false; + } + } + } + } + } + + if (excludeCollidersOnChildrenGOs) + { + if (allColliders2DOnThisGameobjectAndOnChildren != null) + { + for (int i = 0; i < allColliders2DOnThisGameobjectAndOnChildren.Length; i++) + { + if (allColliders2DOnThisGameobjectAndOnChildren[i] != null) + { + if (isOnThisGO_forAllColliders2DOnThisGOPlusChildren_beforeCurrentDrawOperation[i] == false) + { + allColliders2DOnThisGameobjectAndOnChildren[i].enabled = false; + } + } + } + } + } + } + + void TryRestoreEnabledStateOfColliders2DOnThisGameobjectsHierarchy() + { + if (excludeCollidersOnThisGO) + { + if (allColliders2DOnThisGameobject != null) + { + for (int i = 0; i < allColliders2DOnThisGameobject.Length; i++) + { + if (allColliders2DOnThisGameobject[i] != null) + { + allColliders2DOnThisGameobject[i].enabled = enabledState_ofAllColliders2DOnThisGO_beforeCurrentDrawOperation[i]; + } + } + } + } + + if (excludeCollidersOnParentGOs) + { + if (allColliders2DOnThisGameobjectAndOnParents != null) + { + for (int i = 0; i < allColliders2DOnThisGameobjectAndOnParents.Length; i++) + { + if (allColliders2DOnThisGameobjectAndOnParents[i] != null) + { + if (isOnThisGO_forAllColliders2DOnThisGOPlusParents_beforeCurrentDrawOperation[i] == false) + { + allColliders2DOnThisGameobjectAndOnParents[i].enabled = enabledState_ofAllColliders2DOnThisGOPlusParents_beforeCurrentDrawOperation[i]; + } + } + } + } + } + + if (excludeCollidersOnChildrenGOs) + { + if (allColliders2DOnThisGameobjectAndOnChildren != null) + { + for (int i = 0; i < allColliders2DOnThisGameobjectAndOnChildren.Length; i++) + { + if (allColliders2DOnThisGameobjectAndOnChildren[i] != null) + { + if (isOnThisGO_forAllColliders2DOnThisGOPlusChildren_beforeCurrentDrawOperation[i] == false) + { + allColliders2DOnThisGameobjectAndOnChildren[i].enabled = enabledState_ofAllColliders2DOnThisGOPlusChildren_beforeCurrentDrawOperation[i]; + } + } + } + } + } + } + + void Save_globalDrawPhysics2DOptions_beforeThisDrawOperation() + { + colorForNonHittingCasts_before = DrawPhysics2D.colorForNonHittingCasts; + colorForHittingCasts_before = DrawPhysics2D.colorForHittingCasts; + colorForCastLineBeyondHit_before = DrawPhysics2D.colorForCastLineBeyondHit; + colorForCastsHitText_before = DrawPhysics2D.colorForCastsHitText; + scaleFactor_forCastHitTextSize_before = DrawPhysics2D.scaleFactor_forCastHitTextSize; + castCorridorVisualizerDensity_before = DrawPhysics2D.castCorridorVisualizerDensity; + visualizationQuality_before = DrawPhysics2D.visualizationQuality; + drawCastNameTag_atCastOrigin_before = DrawPhysics2D.drawCastNameTag_atCastOrigin; + drawCastNameTag_atHitPositions_before = DrawPhysics2D.drawCastNameTag_atHitPositions; + custom_zPos_forCastVisualisation_before = DrawPhysics2D.custom_zPos_forCastVisualisation; + maxListedColliders_inOverlapVolumesTextList_before = DrawPhysics2D.MaxListedColliders_inOverlapVolumesTextList; + maxOverlapingCollidersWithUntruncatedText_before = DrawPhysics2D.maxOverlapingCollidersWithUntruncatedText; + forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before = DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts; + forcedConstantWorldspaceTextSize_forOverlapResultTexts_before = DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts; + cameraForAutomaticOrientation_before = DrawBasics.cameraForAutomaticOrientation; + + if (doOverwriteColorForCastsHitNormals) + { + overwriteColorForCastsHitNormals_before = DrawPhysics2D.overwriteColorForCastsHitNormals; + } + + if (useCustomDirectionForHitResultText) + { + directionOfHitResultText_before = DrawPhysics2D.directionOfHitResultText; + } + } + + void Set_globalDrawPhysics2DOptions_toValuesFromInpsector() + { + DrawPhysics2D.colorForNonHittingCasts = colorForNonHittingCasts; + DrawPhysics2D.colorForHittingCasts = colorForHittingCasts; + DrawPhysics2D.colorForCastLineBeyondHit = colorForCastLineBeyondHit; + DrawPhysics2D.colorForCastsHitText = colorForCastsHitText; + DrawPhysics2D.scaleFactor_forCastHitTextSize = scaleFactor_forCastHitTextSize; + DrawPhysics2D.castCorridorVisualizerDensity = castCorridorVisualizerDensity; + DrawPhysics2D.visualizationQuality = PhysicsVisualizer.Map_saveDrawnLinesType_to_visualizationQuality(saveDrawnLinesType); + DrawPhysics2D.drawCastNameTag_atCastOrigin = drawCastNameTag_atCastOrigin; + DrawPhysics2D.drawCastNameTag_atHitPositions = drawCastNameTag_atHitPositions; + DrawPhysics2D.custom_zPos_forCastVisualisation = GetZPos_global_for2D(); + DrawPhysics2D.MaxListedColliders_inOverlapVolumesTextList = maxListedColliders_inOverlapVolumesTextList; + DrawPhysics2D.maxOverlapingCollidersWithUntruncatedText = maxOverlapingCollidersWithUntruncatedText; + + switch (overlapResultTextSizeInterpretation) + { + case PhysicsVisualizer.OverlapResultTextSizeInterpretation.relativeToTheSizeOfTheOverlapingPhysicsShape: + DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = 0.0f; + DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts = 0.0f; + break; + case PhysicsVisualizer.OverlapResultTextSizeInterpretation.fixedWorldSpaceSize: + DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = 0.0f; + DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts = forcedConstantWorldspaceTextSize_forOverlapResultTexts; + break; + case PhysicsVisualizer.OverlapResultTextSizeInterpretation.relativeToTheSceneViewWindowSize: + DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts; + DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + break; + case PhysicsVisualizer.OverlapResultTextSizeInterpretation.relativeToTheGameViewWindowSize: + DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts; + DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + break; + default: + break; + } + + if (doOverwriteColorForCastsHitNormals) + { + DrawPhysics2D.overwriteColorForCastsHitNormals = overwriteColorForCastsHitNormals; + } + + if (useCustomDirectionForHitResultText) + { + DrawPhysics2D.directionOfHitResultText = customDirectionForHitResultText; + } + } + + void Restore_globalDrawPhysics2DOptions_toValuesFromBefore() + { + DrawPhysics2D.colorForNonHittingCasts = colorForNonHittingCasts_before; + DrawPhysics2D.colorForHittingCasts = colorForHittingCasts_before; + DrawPhysics2D.colorForCastLineBeyondHit = colorForCastLineBeyondHit_before; + DrawPhysics2D.colorForCastsHitText = colorForCastsHitText_before; + DrawPhysics2D.scaleFactor_forCastHitTextSize = scaleFactor_forCastHitTextSize_before; + DrawPhysics2D.castCorridorVisualizerDensity = castCorridorVisualizerDensity_before; + DrawPhysics2D.visualizationQuality = visualizationQuality_before; + DrawPhysics2D.drawCastNameTag_atCastOrigin = drawCastNameTag_atCastOrigin_before; + DrawPhysics2D.drawCastNameTag_atHitPositions = drawCastNameTag_atHitPositions_before; + DrawPhysics2D.custom_zPos_forCastVisualisation = custom_zPos_forCastVisualisation_before; + DrawPhysics2D.MaxListedColliders_inOverlapVolumesTextList = maxListedColliders_inOverlapVolumesTextList_before; + DrawPhysics2D.maxOverlapingCollidersWithUntruncatedText = maxOverlapingCollidersWithUntruncatedText_before; + DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before; + DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts = forcedConstantWorldspaceTextSize_forOverlapResultTexts_before; + DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts = forcedConstantWorldspaceTextSize_forOverlapResultTexts_before; + DrawBasics.cameraForAutomaticOrientation = cameraForAutomaticOrientation_before; + + if (doOverwriteColorForCastsHitNormals) + { + DrawPhysics2D.overwriteColorForCastsHitNormals = overwriteColorForCastsHitNormals_before; + } + + if (useCustomDirectionForHitResultText) + { + DrawPhysics2D.directionOfHitResultText = directionOfHitResultText_before; + } + } + + void CastRespCheckTheColliders2D_andDrawThem() + { + used_distance = Get_used_distance(); + switch (shape) + { + case Shape.collidersOnThisGameobject: + theGameobjectHasACompatibleAndEnabledCollider = false; + aVisualizedBoxCollider2DOnThisComponent_hasANonZeroEdge = false; + aVisualizedBoxCollider2DOnThisComponent_hasAutoTiling = false; + CastRespOverlap_boxColliders2DOnThisGameobject(); + CastRespOverlap_circleColliders2DOnThisGameobject(); + CastRespOverlap_capsuleColliders2DOnThisGameobject(); + break; + case Shape.box: + switch (collisionType) + { + case CollisionType.cast: + BoxCast2D(GetDrawPos2D_global(), Get_sizeOfFinalBoxShape(sizeScaleFactors_ofCastRespCheckedBox), GetUsedRotation()); + break; + case CollisionType.overlap: + Box2D_checkRespOverlap(GetDrawPos2D_global(), Get_sizeOfFinalBoxShape(sizeScaleFactors_ofCastRespCheckedBox), GetUsedRotation()); + break; + default: + break; + } + break; + case Shape.circle: + switch (collisionType) + { + case CollisionType.cast: + CircleCast2D(GetDrawPos2D_global(), GetRadiusOfFinalCircleShape(radiusScaleFactor_ofCastRespCheckedCircle)); + break; + case CollisionType.overlap: + Circle2D_checkRespOverlap(GetDrawPos2D_global(), GetRadiusOfFinalCircleShape(radiusScaleFactor_ofCastRespCheckedCircle)); + break; + default: + break; + } + break; + case Shape.capsule: + switch (collisionType) + { + case CollisionType.cast: + CapsuleCast2D(GetDrawPos2D_global(), Get_sizeOfFinalBoxShape(sizeScaleFactors_ofCastRespCheckedCapsule), capsuleDirection2D_ofManuallyConstructedCapsuleMeaningNotFromCollider, GetUsedRotation()); + break; + case CollisionType.overlap: + Capsule2D_checkRespOverlap(GetDrawPos2D_global(), Get_sizeOfFinalBoxShape(sizeScaleFactors_ofCastRespCheckedCapsule), capsuleDirection2D_ofManuallyConstructedCapsuleMeaningNotFromCollider, GetUsedRotation()); + break; + default: + break; + } + break; + case Shape.rayOrPoint: + switch (collisionType) + { + case CollisionType.cast: + RayCast2D(); + break; + case CollisionType.overlap: + Point2D_checkRespOverlap(); + break; + default: + break; + } + break; + case Shape.ray3D: + Ray3DCastIn2D(); + break; + default: + break; + } + } + + float Get_used_distance() + { + if (distanceIsInfinityRespToOtherGO) + { + if (shape == Shape.ray3D) + { + if (customVector3Configs[0].source == VisualizerParent.CustomVector3Source.toOtherGameobject) + { + if (customVector3Configs[0].targetGameObject != null) + { + return (transform.position - customVector3Configs[0].targetGameObject.transform.position).magnitude; + } + else + { + return Mathf.Infinity; + } + } + else + { + return Mathf.Infinity; + } + } + else + { + if (customVector2Configs[0].source == VisualizerParent.CustomVector2Source.toOtherGameobject) + { + if (customVector2Configs[0].targetGameObject != null) + { + Vector2 thisTransformPos_asV2 = new Vector2(transform.position.x, transform.position.y); + Vector2 otherGameobjectPos_asV2 = new Vector2(customVector2Configs[0].targetGameObject.transform.position.x, customVector2Configs[0].targetGameObject.transform.position.y); + return (thisTransformPos_asV2 - otherGameobjectPos_asV2).magnitude; + } + else + { + return Mathf.Infinity; + } + } + else + { + return Mathf.Infinity; + } + } + } + else + { + return adjustedDistance; + } + } + + float GetUsedRotation() + { + switch (shapeRotationType) + { + case ShapeRotationType.transformsRotationPlusOptionalAdditionalRotation: + return (transform.rotation.eulerAngles.z + rotationAngleOfShape_additionallyToTransformsAngle); + case ShapeRotationType.customRotationIndependentFromTransform: + return rotationAngleOfShape_additionallyToTransformsAngle; + default: + return 0.0f; + } + } + + void CastRespOverlap_boxColliders2DOnThisGameobject() + { + boxColliders2D_onThisGameobject = this.gameObject.GetComponents(); + if (boxColliders2D_onThisGameobject != null) + { + for (int i = 0; i < boxColliders2D_onThisGameobject.Length; i++) + { + if (boxColliders2D_onThisGameobject[i] != null) + { + if (boxColliders2D_onThisGameobject[i].enabled || GetEnabledStateBeforeCurrentDrawOperation_ofCollider2DComponentOnThisGameobject(boxColliders2D_onThisGameobject[i])) + { + theGameobjectHasACompatibleAndEnabledCollider = true; //this is intentionally outside the "autoTiling"-check + if (UtilitiesDXXL_Math.ApproximatelyZero(boxColliders2D_onThisGameobject[i].edgeRadius) == false) { aVisualizedBoxCollider2DOnThisComponent_hasANonZeroEdge = true; } + + if (boxColliders2D_onThisGameobject[i].autoTiling == true) + { + aVisualizedBoxCollider2DOnThisComponent_hasAutoTiling = true; + } + else + { + Vector2 center = GetCenterPosGlobalOfCollider(boxColliders2D_onThisGameobject[i].offset); + Vector2 size = Get_sizeOfFinalBoxShape(boxColliders2D_onThisGameobject[i].size); + float angle = transform.rotation.eulerAngles.z; + switch (collisionType) + { + case CollisionType.cast: + BoxCast2D(center, size, angle); + break; + case CollisionType.overlap: + Box2D_checkRespOverlap(center, size, angle); + break; + default: + break; + } + } + } + } + } + } + } + + void CastRespOverlap_circleColliders2DOnThisGameobject() + { + circleColliders2D_onThisGameobject = this.gameObject.GetComponents(); + if (circleColliders2D_onThisGameobject != null) + { + for (int i = 0; i < circleColliders2D_onThisGameobject.Length; i++) + { + if (circleColliders2D_onThisGameobject[i] != null) + { + if (circleColliders2D_onThisGameobject[i].enabled || GetEnabledStateBeforeCurrentDrawOperation_ofCollider2DComponentOnThisGameobject(circleColliders2D_onThisGameobject[i])) + { + theGameobjectHasACompatibleAndEnabledCollider = true; + Vector2 origin = GetCenterPosGlobalOfCollider(circleColliders2D_onThisGameobject[i].offset); + float radius = GetRadiusOfFinalCircleShape(circleColliders2D_onThisGameobject[i].radius); + switch (collisionType) + { + case CollisionType.cast: + CircleCast2D(origin, radius); + break; + case CollisionType.overlap: + Circle2D_checkRespOverlap(origin, radius); + break; + default: + break; + } + } + } + } + } + } + + void CastRespOverlap_capsuleColliders2DOnThisGameobject() + { + capsuleColliders2D_onThisGameobject = this.gameObject.GetComponents(); + if (capsuleColliders2D_onThisGameobject != null) + { + for (int i = 0; i < capsuleColliders2D_onThisGameobject.Length; i++) + { + if (capsuleColliders2D_onThisGameobject[i] != null) + { + if (capsuleColliders2D_onThisGameobject[i].enabled || GetEnabledStateBeforeCurrentDrawOperation_ofCollider2DComponentOnThisGameobject(capsuleColliders2D_onThisGameobject[i])) + { + theGameobjectHasACompatibleAndEnabledCollider = true; + Vector2 colliderCenter_global = GetCenterPosGlobalOfCollider(capsuleColliders2D_onThisGameobject[i].offset); + Vector2 size = Get_sizeOfFinalBoxShape(capsuleColliders2D_onThisGameobject[i].size); + float angle = transform.rotation.eulerAngles.z; + switch (collisionType) + { + case CollisionType.cast: + CapsuleCast2D(colliderCenter_global, size, capsuleColliders2D_onThisGameobject[i].direction, angle); + break; + case CollisionType.overlap: + Capsule2D_checkRespOverlap(colliderCenter_global, size, capsuleColliders2D_onThisGameobject[i].direction, angle); + break; + default: + break; + } + } + } + } + } + } + + float GetRadiusOfFinalCircleShape(float radiusScaleFactor_fromComponentProperty) + { + return (radiusScaleFactor_fromComponentProperty * UtilitiesDXXL_Math.GetBiggestAbsComponent_butReassignTheSign(transform.lossyScale, UtilitiesDXXL_Math.Dimension.z)); + } + + Vector2 Get_sizeOfFinalBoxShape(Vector2 sizeScaleFactors_fromComponentProperty) + { + Vector2 transformsLossyScale_asV2 = new Vector2(transform.lossyScale.x, transform.lossyScale.y); + return Vector2.Scale(transformsLossyScale_asV2, sizeScaleFactors_fromComponentProperty); + } + + Vector2 GetCenterPosGlobalOfCollider(Vector2 collidersLocalCenter) + { + Vector3 xOffset = transform.right * transform.lossyScale.x * collidersLocalCenter.x; + Vector3 yOffset = transform.up * transform.lossyScale.y * collidersLocalCenter.y; + return (transform.position + xOffset + yOffset); + } + + void BoxCast2D(Vector2 origin, Vector2 size, float angle) + { + if (wantedHits == WantedHits.all) + { + numberOfFoundHits = DrawPhysics2D.BoxCast(origin, size, angle, Get_customVector2_1_inGlobalSpaceUnits(), GetContactFilter2D_fromInspectorSpecifiedOptions(), unusedRaycastHitResults, used_distance, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + Get_minAndMaxDepth(out float used_minDepth, out float used_maxDepth); + RaycastHit2D result = DrawPhysics2D.BoxCast(origin, size, angle, Get_customVector2_1_inGlobalSpaceUnits(), used_distance, layerMask, used_minDepth, used_maxDepth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (result.collider != null) ? 1 : 0; + } + } + + void CircleCast2D(Vector2 origin, float radius) + { + if (wantedHits == WantedHits.all) + { + numberOfFoundHits = DrawPhysics2D.CircleCast(origin, radius, Get_customVector2_1_inGlobalSpaceUnits(), GetContactFilter2D_fromInspectorSpecifiedOptions(), unusedRaycastHitResults, used_distance, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + Get_minAndMaxDepth(out float used_minDepth, out float used_maxDepth); + RaycastHit2D result = DrawPhysics2D.CircleCast(origin, radius, Get_customVector2_1_inGlobalSpaceUnits(), used_distance, layerMask, used_minDepth, used_maxDepth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (result.collider != null) ? 1 : 0; + } + } + + void CapsuleCast2D(Vector2 origin, Vector2 size, CapsuleDirection2D capsuleDirection, float angle) + { + if (wantedHits == WantedHits.all) + { + numberOfFoundHits = DrawPhysics2D.CapsuleCast(origin, size, capsuleDirection, angle, Get_customVector2_1_inGlobalSpaceUnits(), GetContactFilter2D_fromInspectorSpecifiedOptions(), unusedRaycastHitResults, used_distance, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + Get_minAndMaxDepth(out float used_minDepth, out float used_maxDepth); + RaycastHit2D result = DrawPhysics2D.CapsuleCast(origin, size, capsuleDirection, angle, Get_customVector2_1_inGlobalSpaceUnits(), used_distance, layerMask, used_minDepth, used_maxDepth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (result.collider != null) ? 1 : 0; + } + } + + void RayCast2D() + { + if (wantedHits == WantedHits.all) + { + numberOfFoundHits = DrawPhysics2D.Raycast(GetDrawPos2D_global(), Get_customVector2_1_inGlobalSpaceUnits(), GetContactFilter2D_fromInspectorSpecifiedOptions(), unusedRaycastHitResults, used_distance, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + Get_minAndMaxDepth(out float used_minDepth, out float used_maxDepth); + RaycastHit2D result = DrawPhysics2D.Raycast(GetDrawPos2D_global(), Get_customVector2_1_inGlobalSpaceUnits(), used_distance, layerMask, used_minDepth, used_maxDepth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (result.collider != null) ? 1 : 0; + } + } + + void Ray3DCastIn2D() + { + Ray ray = new Ray(GetDrawPos3D_global(), Get_customVector3_1_inGlobalSpaceUnits()); + if (wantedHits == WantedHits.all) + { + RaycastHit2D[] results = DrawPhysics2D.GetRayIntersectionAll(ray, used_distance, layerMask, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (results != null) ? results.Length : 0; + } + else + { + RaycastHit2D result = DrawPhysics2D.GetRayIntersection(ray, used_distance, layerMask, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (result.collider != null) ? 1 : 0; + } + } + + void Box2D_checkRespOverlap(Vector2 point, Vector2 size, float angle) + { + if (wantedHits == WantedHits.all) + { + numberOfFoundHits = DrawPhysics2D.OverlapBox(point, size, angle, GetContactFilter2D_fromInspectorSpecifiedOptions(), unusedResultColliders, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + Get_minAndMaxDepth(out float used_minDepth, out float used_maxDepth); + Collider2D overlappingCollider = DrawPhysics2D.OverlapBox(point, size, angle, layerMask, used_minDepth, used_maxDepth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (overlappingCollider != null) ? 1 : 0; + } + } + + void Circle2D_checkRespOverlap(Vector2 point, float radius) + { + if (wantedHits == WantedHits.all) + { + numberOfFoundHits = DrawPhysics2D.OverlapCircle(point, radius, GetContactFilter2D_fromInspectorSpecifiedOptions(), unusedResultColliders, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + Get_minAndMaxDepth(out float used_minDepth, out float used_maxDepth); + Collider2D overlappingCollider = DrawPhysics2D.OverlapCircle(point, radius, layerMask, used_minDepth, used_maxDepth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (overlappingCollider != null) ? 1 : 0; + } + } + + void Capsule2D_checkRespOverlap(Vector2 point, Vector2 size, CapsuleDirection2D direction, float angle) + { + if (wantedHits == WantedHits.all) + { + numberOfFoundHits = DrawPhysics2D.OverlapCapsule(point, size, direction, angle, GetContactFilter2D_fromInspectorSpecifiedOptions(), unusedResultColliders, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + Get_minAndMaxDepth(out float used_minDepth, out float used_maxDepth); + Collider2D overlappingCollider = DrawPhysics2D.OverlapCapsule(point, size, direction, angle, layerMask, used_minDepth, used_maxDepth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (overlappingCollider != null) ? 1 : 0; + } + } + + void Point2D_checkRespOverlap() + { + if (wantedHits == WantedHits.all) + { + numberOfFoundHits = DrawPhysics2D.OverlapPoint(GetDrawPos2D_global(), GetContactFilter2D_fromInspectorSpecifiedOptions(), unusedResultColliders, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + Get_minAndMaxDepth(out float used_minDepth, out float used_maxDepth); + Collider2D overlappingCollider = DrawPhysics2D.OverlapPoint(GetDrawPos2D_global(), layerMask, used_minDepth, used_maxDepth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (overlappingCollider != null) ? 1 : 0; + } + } + + ContactFilter2D GetContactFilter2D_fromInspectorSpecifiedOptions() + { + ContactFilter2D created_contactFilter2D = new ContactFilter2D(); + + created_contactFilter2D.useLayerMask = true; + created_contactFilter2D.layerMask = layerMask; + + created_contactFilter2D.useDepth = useDepth; + created_contactFilter2D.minDepth = minDepth; + created_contactFilter2D.maxDepth = maxDepth; + created_contactFilter2D.useOutsideDepth = useOutsideDepth; + + created_contactFilter2D.useNormalAngle = useNormalAngle; + created_contactFilter2D.minNormalAngle = minNormalAngle; + created_contactFilter2D.maxNormalAngle = maxNormalAngle; + created_contactFilter2D.useOutsideNormalAngle = useOutsideNormalAngle; + + created_contactFilter2D.useTriggers = useTriggers; + + return created_contactFilter2D; + } + + void Get_minAndMaxDepth(out float used_minDepth, out float used_maxDepth) + { + if (useDepth) + { + used_minDepth = minDepth; + used_maxDepth = maxDepth; + } + else + { + used_minDepth = Mathf.NegativeInfinity; + used_maxDepth = Mathf.Infinity; + } + } + + static Vector2 GetInitialValueFor_customDirectionForHitResultText() + { + if (UtilitiesDXXL_Math.IsDefaultVector(DrawPhysics2D.directionOfHitResultText)) + { + return DrawBasics.Default_textOffsetDirection_forPointTags; + } + else + { + return DrawPhysics2D.directionOfHitResultText; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/2D/PhysicsVisualizer2D.cs.meta b/Runtime/DrawDebugLibrary/components/2D/PhysicsVisualizer2D.cs.meta new file mode 100644 index 0000000..365e805 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/PhysicsVisualizer2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8450f185e9b2ff3498d5f48b567f7655 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/2D/ShapeDrawer2D.cs b/Runtime/DrawDebugLibrary/components/2D/ShapeDrawer2D.cs new file mode 100644 index 0000000..73c06d8 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/ShapeDrawer2D.cs @@ -0,0 +1,352 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/2D/Shape Drawer 2D")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class ShapeDrawer2D : VisualizerParent + { + public enum ShapeType { circle, ellipse, star, capsule, icon, triangle, square, pentagon, hexagon, septagon, octagon, decagon, dot } + [SerializeField] ShapeType shapeType = ShapeType.circle; + public enum ShapeSizeDefinition { relativeToGlobalScaleOfTheTransformUsingTheBiggestAbsoluteComponentButIgnoringZ, absoluteUnits, relativeToTheSceneViewWindowSize, relativeToTheGameViewWindowSize }; + [SerializeField] ShapeSizeDefinition sizeDefinition = ShapeSizeDefinition.relativeToGlobalScaleOfTheTransformUsingTheBiggestAbsoluteComponentButIgnoringZ; + [SerializeField] ShapeDrawer.ShapeAttachedTextsizeReferenceContext shapeAttachedTextsizeReferenceContext = ShapeDrawer.ShapeAttachedTextsizeReferenceContext.sceneViewWindowSize; + [SerializeField] float textSize_value = 0.1f; + [SerializeField] [Range(0.001f, 0.2f)] float textSize_value_relToScreen = 0.02f; + + float lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + float biggestAbsGlobalSizeComponentOfTransform_ignoringZ = 1.0f; + [SerializeField] bool cameraForSizeDefinitionIsAvailable = false; + Camera gameviewCameraForDrawing; + + //general settings: + [SerializeField] [Range(-360.0f, 360.0f)] float rotation_angleDegCC = 0.0f; + [SerializeField] Color color = DrawBasics.defaultColor; + [SerializeField] DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid; + [SerializeField] DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible; + [SerializeField] float shapeFillDensity = 1.0f; + [SerializeField] bool textBlockAboveLine = false; + + //shape specific settings: + [SerializeField] DrawBasics.IconType iconType = DrawBasics.IconType.car; + [SerializeField] bool iconIsMirroredHorizontally = false; + [SerializeField] bool showAtlasOfAllAvailableIcons = false; + [SerializeField] ShapeDrawer.CornerOptionsForIrregularStar cornerOptionsForIrregularStar = ShapeDrawer.CornerOptionsForIrregularStar._5; + [SerializeField] CapsuleDirection2D capusleDirection2D = CapsuleDirection2D.Vertical; + [SerializeField] float dotDensity = 1.0f; + + //general - scale type dependent: + [SerializeField] ScreenRelativeValue linesWidth = new ScreenRelativeValue(0.0f, 0.0f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue stylePatternScaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + + //shape specific - scale type dependent: + [SerializeField] ScreenRelativeValue radiusScaleFactor = new ScreenRelativeValue(0.5f, 0.05f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue sizeOfIconScaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue width_scaleFactor_initialValue1 = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue height_scaleFactor_initialValue1 = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue height_scaleFactor_initialValue2 = new ScreenRelativeValue(2.0f, 0.2f, ScreenRelativeValue.ScaleMode.absolute); + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + } + + public override void DrawVisualizedObject() + { + CacheSizeScaleFactors(); + switch (shapeType) + { + case ShapeType.circle: + float size_asFloat = 2.0f * GetRadius(); + Vector2 size = new Vector2(size_asFloat, size_asFloat); + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawBasics2D.Shape(GetDrawPos2D_global(), DrawShapes.Shape2DType.circle, size, color, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.ellipse: + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawBasics2D.Shape(GetDrawPos2D_global(), DrawShapes.Shape2DType.circle, Get_size_initialValueNonUniform(), color, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.star: + Set_globalTextSizeSpecs_reversible(); + DrawBasics2D.Shape(GetDrawPos2D_global(), ShapeDrawer.Get_shape2DType_forIrregularStar(cornerOptionsForIrregularStar), Get_size_initialValueUniform(), color, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), DrawBasics.LineStyle.invisible, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.capsule: + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawBasics2D.Capsule(GetDrawPos2D_global(), Get_size_initialValueNonUniform(), color, capusleDirection2D, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), fillStyle, false, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.icon: + float sizeOfIcon = GetSizeOfIcon(); + int strokeWidth_asPPMofSize = 0; + if ((UtilitiesDXXL_Math.ApproximatelyZero(sizeOfIcon) == false) && (UtilitiesDXXL_Math.ApproximatelyZero(Get_linesWidth()) == false)) + { + strokeWidth_asPPMofSize = (int)(1000000.0f * (Get_linesWidth() / sizeOfIcon)); + } + DrawBasics2D.Icon(GetDrawPos2D_global(), iconType, color, sizeOfIcon, text_inclGlobalMarkupTags, rotation_angleDegCC, strokeWidth_asPPMofSize, GetZPos_global_for2D(), iconIsMirroredHorizontally, 0.0f, hiddenByNearerObjects); + + if (showAtlasOfAllAvailableIcons) + { + DrawBasics.DrawAtlasOfAllIconsWithTheirNames(GetDrawPos3D_ofA2DModeTransform_global(), default(Color), default(Color), true, biggestAbsGlobalSizeComponentOfTransform_ignoringZ); + } + break; + case ShapeType.triangle: + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawBasics2D.Shape(GetDrawPos2D_global(), DrawShapes.Shape2DType.triangle, Get_size_initialValueUniform(), color, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.square: + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawBasics2D.Shape(GetDrawPos2D_global(), DrawShapes.Shape2DType.square, Get_size_initialValueUniform(), color, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.pentagon: + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawBasics2D.Shape(GetDrawPos2D_global(), DrawShapes.Shape2DType.pentagon, Get_size_initialValueUniform(), color, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.hexagon: + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawBasics2D.Shape(GetDrawPos2D_global(), DrawShapes.Shape2DType.hexagon, Get_size_initialValueUniform(), color, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.septagon: + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawBasics2D.Shape(GetDrawPos2D_global(), DrawShapes.Shape2DType.septagon, Get_size_initialValueUniform(), color, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.octagon: + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawBasics2D.Shape(GetDrawPos2D_global(), DrawShapes.Shape2DType.octagon, Get_size_initialValueUniform(), color, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.decagon: + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawBasics2D.Shape(GetDrawPos2D_global(), DrawShapes.Shape2DType.decagon, Get_size_initialValueUniform(), color, rotation_angleDegCC, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, GetZPos_global_for2D(), Get_stylePatternScaleFactor(), fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType.dot: + DrawBasics2D.Dot(GetDrawPos2D_global(), 0.5f * GetSizeOfIcon(), color, text_inclGlobalMarkupTags, GetZPos_global_for2D(), dotDensity, 0.0f, hiddenByNearerObjects); + break; + default: + break; + } + } + + void CacheSizeScaleFactors() + { + biggestAbsGlobalSizeComponentOfTransform_ignoringZ = UtilitiesDXXL_Math.GetBiggestAbsComponent_ignoringZ(transform.lossyScale); + cameraForSizeDefinitionIsAvailable = false; + switch (sizeDefinition) + { + case ShapeSizeDefinition.relativeToGlobalScaleOfTheTransformUsingTheBiggestAbsoluteComponentButIgnoringZ: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + case ShapeSizeDefinition.absoluteUnits: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + case ShapeSizeDefinition.relativeToTheSceneViewWindowSize: +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + cameraForSizeDefinitionIsAvailable = true; + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_ofA2DModeTransform_global() - UnityEditor.SceneView.lastActiveSceneView.camera.transform.position).magnitude; + lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(UnityEditor.SceneView.lastActiveSceneView.camera, distance_ofDrawnObject_toCamera); + } + else + { + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + } +#else + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; +#endif + break; + case ShapeSizeDefinition.relativeToTheGameViewWindowSize: + cameraForSizeDefinitionIsAvailable = UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out gameviewCameraForDrawing, "Shape Drawer 2D Component", false); + if (cameraForSizeDefinitionIsAvailable) + { + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_ofA2DModeTransform_global() - gameviewCameraForDrawing.transform.position).magnitude; + lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(gameviewCameraForDrawing, distance_ofDrawnObject_toCamera); + } + else + { + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + } + break; + default: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + } + } + + float GetRadius() + { + return ScaleInputFloat_accordingToSizeDefinition(radiusScaleFactor); + } + + float GetSizeOfIcon() + { + return ScaleInputFloat_accordingToSizeDefinition(sizeOfIconScaleFactor); + } + + float Get_width_initialValue1() + { + return ScaleInputFloat_accordingToSizeDefinition(width_scaleFactor_initialValue1); + } + + float Get_height_initialValue1() + { + return ScaleInputFloat_accordingToSizeDefinition(height_scaleFactor_initialValue1); + } + + Vector2 Get_size_initialValueUniform() + { + return new Vector2(Get_width_initialValue1(), Get_height_initialValue1()); + } + + float Get_height_initialValue2() + { + return ScaleInputFloat_accordingToSizeDefinition(height_scaleFactor_initialValue2); + } + + Vector2 Get_size_initialValueNonUniform() + { + return new Vector2(Get_width_initialValue1(), Get_height_initialValue2()); + } + + float Get_linesWidth() + { + return ScaleInputFloat_accordingToSizeDefinition(linesWidth); + } + + float Get_stylePatternScaleFactor() + { + float stylePatternScaleFactor_unclamped = ScaleInputFloat_accordingToSizeDefinition(stylePatternScaleFactor); + return Mathf.Max(stylePatternScaleFactor_unclamped, UtilitiesDXXL_LineStyles.minStylePatternScaleFactor); + } + + float ScaleInputFloat_accordingToSizeDefinition(float inputFloatToScale_versionThatIsRelToScreen, float inputFloatToScale) + { + switch (sizeDefinition) + { + case ShapeSizeDefinition.relativeToGlobalScaleOfTheTransformUsingTheBiggestAbsoluteComponentButIgnoringZ: + return biggestAbsGlobalSizeComponentOfTransform_ignoringZ * inputFloatToScale; + case ShapeSizeDefinition.absoluteUnits: + return inputFloatToScale; + case ShapeSizeDefinition.relativeToTheSceneViewWindowSize: + if (cameraForSizeDefinitionIsAvailable) + { + return lengthOfScreenDiagonal_atDrawnObjectsPosition * inputFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputFloatToScale; + } + case ShapeSizeDefinition.relativeToTheGameViewWindowSize: + if (cameraForSizeDefinitionIsAvailable) + { + return lengthOfScreenDiagonal_atDrawnObjectsPosition * inputFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputFloatToScale; + } + default: + return inputFloatToScale; + } + } + + float ScaleInputFloat_accordingToSizeDefinition(ScreenRelativeValue value) + { + return ScaleInputFloat_accordingToSizeDefinition(value.relativeToScreen, value.absolute); + } + + float forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before; + float forcedConstantWorldspaceTextSize_forTextAtShapes_before; + DrawBasics.CameraForAutomaticOrientation cameraForAutomaticOrientation_before; + DrawText.AutomaticTextOrientation automaticTextOrientation_before; + void Set_globalTextSizeSpecs_reversible() + { + forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before = DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes; + forcedConstantWorldspaceTextSize_forTextAtShapes_before = DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes; + cameraForAutomaticOrientation_before = DrawBasics.cameraForAutomaticOrientation; + automaticTextOrientation_before = DrawText.automaticTextOrientation; + + if (sizeDefinition == ShapeSizeDefinition.relativeToTheSceneViewWindowSize) + { + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + DrawText.automaticTextOrientation = DrawText.AutomaticTextOrientation.screen; + } + else + { + if (sizeDefinition == ShapeSizeDefinition.relativeToTheGameViewWindowSize) + { + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + DrawText.automaticTextOrientation = DrawText.AutomaticTextOrientation.screen; + } + else + { + switch (shapeAttachedTextsizeReferenceContext) + { + case ShapeDrawer.ShapeAttachedTextsizeReferenceContext.sizeOfShape: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = 0.0f; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + break; + case ShapeDrawer.ShapeAttachedTextsizeReferenceContext.globalSpace: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = 0.0f; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = textSize_value; + break; + case ShapeDrawer.ShapeAttachedTextsizeReferenceContext.sceneViewWindowSize: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = textSize_value_relToScreen; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + DrawText.automaticTextOrientation = DrawText.AutomaticTextOrientation.screen; + break; + case ShapeDrawer.ShapeAttachedTextsizeReferenceContext.gameViewWindowSize: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = textSize_value_relToScreen; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + DrawText.automaticTextOrientation = DrawText.AutomaticTextOrientation.screen; + break; + default: + break; + } + } + } + } + + void Reverse_globalTextSizeSpecs() + { + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = forcedConstantWorldspaceTextSize_forTextAtShapes_before; + DrawBasics.cameraForAutomaticOrientation = cameraForAutomaticOrientation_before; + DrawText.automaticTextOrientation = automaticTextOrientation_before; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/2D/ShapeDrawer2D.cs.meta b/Runtime/DrawDebugLibrary/components/2D/ShapeDrawer2D.cs.meta new file mode 100644 index 0000000..41c368f --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/ShapeDrawer2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 48d0fe42b7a205a48b4d85c8c91c8486 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/2D/TagDrawer2D.cs b/Runtime/DrawDebugLibrary/components/2D/TagDrawer2D.cs new file mode 100644 index 0000000..8a239d1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/TagDrawer2D.cs @@ -0,0 +1,221 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/2D/Tag Drawer 2D")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class TagDrawer2D : VisualizerParent + { + [SerializeField] float linesWidth = 0.0f; + [SerializeField] [Range(0.0f, 0.02f)] float linesWidth_relToScreen = 0.0f; + [SerializeField] Color color = DrawBasics.defaultColor; + [SerializeField] bool drawGlobalCoordinates = false; + [SerializeField] [Range(0.0f, 1.0f)] float strokeWidth_forCoordinateTexts_onPointVisualiation_in0to1 = 0.0f; + [SerializeField] float sizeOfMarkingCross = 1.0f; + [SerializeField] [Range(0.005f, 1.0f)] float sizeOfMarkingCross_relToScreen = 0.1f; + [SerializeField] bool skipConeDrawing = false; + [SerializeField] bool forcePointerDirection = false; + [SerializeField] float pointerTextSize_value = 0.1f; + [SerializeField] [Range(0.001f, 0.3f)] float pointerTextSize_value_relToScreen = 0.01f; + [SerializeField] public bool textOffsetDistance_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] float textOffsetDistance = 1.0f; + [SerializeField] [Range(0.0025f, 0.2f)] float textOffsetDistance_relToScreen = 0.1f; + [SerializeField] TagDrawer.PointerSizeInterpretation pointerSizeInterpretation = TagDrawer.PointerSizeInterpretation.absoluteUnits; + [SerializeField] TagDrawer.AttachedTextsizeReferenceContext attachedTextsizeReferenceContext = TagDrawer.AttachedTextsizeReferenceContext.sceneViewWindowSize; + float lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + float biggestAbsGlobalSizeComponentOfTransform_ignoringZ = 1.0f; + [SerializeField] bool cameraForSizeDefinitionIsAvailable = false; + Camera gameviewCameraForDrawing; + + public override void InitializeValues_onceInComponentLifetime() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = "tag text of " + this.gameObject.name; + text_inclGlobalMarkupTags = "tag text of " + this.gameObject.name; + } + textSection_isOutfolded = true; + + customVector2Configs[0].source = CustomVector2Source.manualInput; + customVector2Configs[0].clipboardForManualInput = (-DrawBasics.Default_textOffsetDirection_forPointTags); + customVector2Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void DrawVisualizedObject() + { + CacheSizeScaleFactors(); + Vector2 drawPos2D_global = GetDrawPos2D_global(); + TryDrawCoordinates(drawPos2D_global); + Vector2 used_textOffsetDir = forcePointerDirection ? (-Get_customVector2_1_inGlobalSpaceUnits()) : Vector2.zero; + float used_linesWidth = ScaleInputFloat_accordingToSizeDefinition(linesWidth_relToScreen, linesWidth); + float used_textOffsetDistance_unclamped = ScaleInputFloat_accordingToSizeDefinition(textOffsetDistance_relToScreen, textOffsetDistance); + float used_textOffsetDistance = UtilitiesDXXL_DrawBasics.GetClamped_pointTagSize_asTextOffsetDistance(used_textOffsetDistance_unclamped, used_linesWidth); + float used_relTextSizeScaling = Get_used_relTextSizeScaling(used_textOffsetDistance); + DrawBasics2D.PointTag(drawPos2D_global, text_inclGlobalMarkupTags, color, used_linesWidth, used_textOffsetDistance, used_textOffsetDir, GetZPos_global_for2D(), used_relTextSizeScaling, skipConeDrawing, 0.0f, hiddenByNearerObjects); + } + + void CacheSizeScaleFactors() + { + biggestAbsGlobalSizeComponentOfTransform_ignoringZ = UtilitiesDXXL_Math.GetBiggestAbsComponent_ignoringZ(transform.lossyScale); + cameraForSizeDefinitionIsAvailable = false; + switch (pointerSizeInterpretation) + { + case TagDrawer.PointerSizeInterpretation.absoluteUnits: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + case TagDrawer.PointerSizeInterpretation.relativeToGameobjectSize: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + case TagDrawer.PointerSizeInterpretation.relativeToTheSceneViewWindowSize: +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + cameraForSizeDefinitionIsAvailable = true; + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_ofA2DModeTransform_global() - UnityEditor.SceneView.lastActiveSceneView.camera.transform.position).magnitude; + lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(UnityEditor.SceneView.lastActiveSceneView.camera, distance_ofDrawnObject_toCamera); + } + else + { + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + } +#else + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; +#endif + break; + case TagDrawer.PointerSizeInterpretation.relativeToTheGameViewWindowSize: + cameraForSizeDefinitionIsAvailable = UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out gameviewCameraForDrawing, "Tag Drawer 2D Component", false); + if (cameraForSizeDefinitionIsAvailable) + { + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_ofA2DModeTransform_global() - gameviewCameraForDrawing.transform.position).magnitude; + lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(gameviewCameraForDrawing, distance_ofDrawnObject_toCamera); + } + else + { + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + } + break; + default: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + } + } + + void TryDrawCoordinates(Vector2 drawPos2D_global) + { + if (drawGlobalCoordinates) + { + UtilitiesDXXL_DrawBasics.Set_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_reversible(Convert_strokeWidthForCoordinateTexts_toPPM()); + DrawBasics2D.Point(drawPos2D_global, null, default(Color), ScaleInputFloat_accordingToSizeDefinition(sizeOfMarkingCross_relToScreen, sizeOfMarkingCross), 0.0f, GetZPos_global_for2D(), default(Color), 0.0f, false, true, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM(); + } + } + + int Convert_strokeWidthForCoordinateTexts_toPPM() + { + if (strokeWidth_forCoordinateTexts_onPointVisualiation_in0to1 <= 0.0f) + { + return 0; + } + else + { + return Mathf.CeilToInt(strokeWidth_forCoordinateTexts_onPointVisualiation_in0to1 * UtilitiesDXXL_Text.maxRelStrokeWidth_inPPMofSize); + } + } + + float Get_used_relTextSizeScaling(float used_textOffsetDistance) + { + if (CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace() == false) + { + switch (attachedTextsizeReferenceContext) + { + case TagDrawer.AttachedTextsizeReferenceContext.extentOfTag: + return 1.0f; + case TagDrawer.AttachedTextsizeReferenceContext.globalSpace: + return Get_used_relTextSizeScaling_toReachAFixedWorldSpaceTextSize(pointerTextSize_value, used_textOffsetDistance); + case TagDrawer.AttachedTextsizeReferenceContext.sceneViewWindowSize: + //cannot reuse "cameraForSizeDefinitionIsAvailable" here, since "pointerAttachedTextsizeReferenceContext" is another setting than "pointerSizeInterpretation" +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_ofA2DModeTransform_global() - UnityEditor.SceneView.lastActiveSceneView.camera.transform.position).magnitude; + float lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(UnityEditor.SceneView.lastActiveSceneView.camera, distance_ofDrawnObject_toCamera); + float worldSpaceTextSize_toReachWantedScreenspaceTextSize = lengthOfScreenDiagonal_atDrawnObjectsPosition * pointerTextSize_value_relToScreen; + return Get_used_relTextSizeScaling_toReachAFixedWorldSpaceTextSize(worldSpaceTextSize_toReachWantedScreenspaceTextSize, used_textOffsetDistance); + } + else + { + return 1.0f; + } +#else + return 1.0f; +#endif + case TagDrawer.AttachedTextsizeReferenceContext.gameViewWindowSize: + //cannot reuse "cameraForSizeDefinitionIsAvailable" here, since "pointerAttachedTextsizeReferenceContext" is another setting than "pointerSizeInterpretation" + bool cameraForTextSizeDefinitionIsAvailable = UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out gameviewCameraForDrawing, "Tag Drawer Component", false); + if (cameraForTextSizeDefinitionIsAvailable) + { + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_ofA2DModeTransform_global() - gameviewCameraForDrawing.transform.position).magnitude; + float lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(gameviewCameraForDrawing, distance_ofDrawnObject_toCamera); + float worldSpaceTextSize_toReachWantedScreenspaceTextSize = lengthOfScreenDiagonal_atDrawnObjectsPosition * pointerTextSize_value_relToScreen; + return Get_used_relTextSizeScaling_toReachAFixedWorldSpaceTextSize(worldSpaceTextSize_toReachWantedScreenspaceTextSize, used_textOffsetDistance); + } + else + { + return 1.0f; + } + default: + return 1.0f; + } + } + else + { + return 1.0f; + } + } + + float Get_used_relTextSizeScaling_toReachAFixedWorldSpaceTextSize(float fixedWorldSpaceTextSize_toReach, float used_textOffsetDistance) + { + //"used_textOffsetDistance" is guaranteed bigger than 0 here -> no "division by 0" check necessary + return (fixedWorldSpaceTextSize_toReach / (used_textOffsetDistance * UtilitiesDXXL_DrawBasics.pointTagsTextSize_relToOffset)); + } + + bool CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace() + { + return ((pointerSizeInterpretation == TagDrawer.PointerSizeInterpretation.relativeToTheSceneViewWindowSize) || (pointerSizeInterpretation == TagDrawer.PointerSizeInterpretation.relativeToTheGameViewWindowSize)); + } + + float ScaleInputFloat_accordingToSizeDefinition(float inputFloatToScale_versionThatIsRelToScreen, float inputFloatToScale) + { + switch (pointerSizeInterpretation) + { + case TagDrawer.PointerSizeInterpretation.absoluteUnits: + return inputFloatToScale; + case TagDrawer.PointerSizeInterpretation.relativeToGameobjectSize: + return biggestAbsGlobalSizeComponentOfTransform_ignoringZ * inputFloatToScale; + case TagDrawer.PointerSizeInterpretation.relativeToTheSceneViewWindowSize: + if (cameraForSizeDefinitionIsAvailable) + { + return lengthOfScreenDiagonal_atDrawnObjectsPosition * inputFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputFloatToScale; + } + case TagDrawer.PointerSizeInterpretation.relativeToTheGameViewWindowSize: + if (cameraForSizeDefinitionIsAvailable) + { + return lengthOfScreenDiagonal_atDrawnObjectsPosition * inputFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputFloatToScale; + } + default: + return inputFloatToScale; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/2D/TagDrawer2D.cs.meta b/Runtime/DrawDebugLibrary/components/2D/TagDrawer2D.cs.meta new file mode 100644 index 0000000..5a7d17e --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/TagDrawer2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca3f9a25118722445b01b0d8c9081b04 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/2D/TextDrawer2D.cs b/Runtime/DrawDebugLibrary/components/2D/TextDrawer2D.cs new file mode 100644 index 0000000..1ebdc99 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/TextDrawer2D.cs @@ -0,0 +1,51 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/2D/Text Drawer 2D")] + public class TextDrawer2D : TextDrawer + { + public override void InitializeValues_onceInComponentLifetime() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = "text to draw"; + text_inclGlobalMarkupTags = "text to draw"; + } + textSection_isOutfolded = true; + + customVector2Configs[0].picker_isOutfolded = false; + customVector2Configs[0].source = CustomVector2Source.transformsRight; + customVector2Configs[0].clipboardForManualInput = Vector2.right; + customVector2Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void DrawVisualizedObject() + { + CacheSizeScaleFactors("Text Drawer 2D Component"); + float used_size = Get_used_size(); + if (text_inclGlobalMarkupTags != null && text_inclGlobalMarkupTags != "") + { + if (UtilitiesDXXL_Math.ApproximatelyZero(used_size) == false) + { + GetScaledTextBlockConstraintValues(out float used_forceTextEnlargementToThisMinWidth_value, out float used_forceRestrictTextSizeToThisMaxTextWidth_value, out float used_autoLineBreakWidth_value); + Vector2 textDir = Get_customVector2_1_inGlobalSpaceUnits(); + UtilitiesDXXL_Text.Write2DFramed(text_inclGlobalMarkupTags, GetDrawPos2D_global(), color, used_size, textDir, textAnchor, GetZPos_global_for2D(), enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, used_forceTextEnlargementToThisMinWidth_value, used_forceRestrictTextSizeToThisMaxTextWidth_value, used_autoLineBreakWidth_value, autoFlipToPreventMirrorInverted, 0.0f, hiddenByNearerObjects); + } + } + } + + public override float Get_biggestAbsGlobalSizeComponentOfTransform() + { + return UtilitiesDXXL_Math.GetBiggestAbsComponent_ignoringZ(transform.lossyScale); + } + + public override Vector3 Get_used_drawPos3D_global() + { + return GetDrawPos3D_ofA2DModeTransform_global(); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/2D/TextDrawer2D.cs.meta b/Runtime/DrawDebugLibrary/components/2D/TextDrawer2D.cs.meta new file mode 100644 index 0000000..622247a --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/2D/TextDrawer2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f28f48059dc6a1a4dac5118f2bc8f106 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/BezierSplineDrawer.cs b/Runtime/DrawDebugLibrary/components/BezierSplineDrawer.cs new file mode 100644 index 0000000..e4876a1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/BezierSplineDrawer.cs @@ -0,0 +1,1467 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Bezier Spline Drawer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class BezierSplineDrawer : BezierSplineDrawerBase + { + public static Color default_color_ofAnchorPoints = new Color(1.0f, 0.859f, 0.41f, 1.0f); + public static Color default_color_ofHelperPoints = new Color(1.0f, 0.642f, 0.4588f, 1.0f); + + public static Color color_ofControlPointListBackgroundInInspecor = new Color(0.5f, 0.5f, 0.5f, 1.0f); //-> this is right in the middle between the default background colors of the Editors bright theme and dark theme. Since the control point rects in the inspector list are drawn semi-transparent they turn out different depending on the background color and also different for each overdrawn semi-transparent hue. So drawing an encapsulating rect behind the whole control points list with this color makes it independent from Editor color themes. + public static Color color_ofControlPointListBackgroundFrameInInspecor = new Color(0.824f, 0.824f, 0.824f, 1.0f); + + public enum DrawSpace { global, localDefinedByThisGameobject }; + [SerializeField] public bool drawSpaceSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public DrawSpace drawSpace; + [SerializeField] bool keepWorldPos_duringDrawSpaceChange = false; + + [SerializeField] public Color color_ofAnchorPoints = default_color_ofAnchorPoints; + [SerializeField] public Color color_ofHelperPoints = default_color_ofHelperPoints; + [SerializeField] public bool gapFromEndToStart_isClosed = false; + + public enum PositionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal { localDrawSpace, globalSpace }; + [SerializeField] public PositionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal positionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal = PositionHandleOrientation_forEditorPivotIsGlobal_butDrawSpaceIsLocal.localDrawSpace; + + public static float default_handleSizeOf_customHandle_atAnchors = 0.3f; + static float default_handleSizeOf_customHandle_atHelpers = 0.225f; + static float default_handleSizeOf_plusButtons = 0.2f; + + [SerializeField] public bool handlesSection_isOutfolded = false; + [SerializeField] public bool hideAllHandles = false; + [SerializeField] public bool showHandleFor_position_atAnchors = true; + [SerializeField] public bool showHandleFor_position_atHelpers = true; + [SerializeField] [Range(0.2f, 2.0f)] public float handleSizeFor_position_atAnchors = 1.0f; + [SerializeField] [Range(0.2f, 2.0f)] public float handleSizeFor_position_atHelpers = 1.0f; + [SerializeField] public bool showHandleFor_rotation = true; + [SerializeField] [Range(0.15f, 1.5f)] public float handleSizeFor_rotation = 0.6666f; + [SerializeField] public bool showCustomHandleFor_anchorPoints = true; + [SerializeField] public bool showCustomHandleFor_helperPoints = true; + [SerializeField] [Range(0.08f, 0.75f)] public float handleSizeOf_customHandle_atAnchors = default_handleSizeOf_customHandle_atAnchors; + [SerializeField] [Range(0.08f, 0.75f)] public float handleSizeOf_customHandle_atHelpers = default_handleSizeOf_customHandle_atHelpers; + [SerializeField] public bool showHandleFor_plusButtons_atSplineStartAndEnd = true; + [SerializeField] public bool showHandleFor_plusButtons_insideSegments = true; + [SerializeField] [Range(0.08f, 0.75f)] public float handleSizeOf_plusButtons = default_handleSizeOf_plusButtons; + + [SerializeField] public bool controlPointsList_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool defaultPosRotWeightOffsetOfNewlyCreatedPoints_section_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool defaultPosOffsetOfNewlyCreatedPoints_subSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool defaultRotOfNewlyCreatedPoints_subSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool defaultWeightsOfNewlyCreatedPoints_subSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + public enum DefinitionType_ofDefaultPosOffset { straightExtentionOfCurveEnd, customOffset }; + [SerializeField] public DefinitionType_ofDefaultPosOffset definitionType_ofDefaultPosOffset = DefinitionType_ofDefaultPosOffset.straightExtentionOfCurveEnd; + [SerializeField] public float distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace = 3.0f; + + public enum DefinitionType_ofDefaultRot { sameAsCurveEnd, customOrientation }; + [SerializeField] public DefinitionType_ofDefaultRot definitionType_ofDefaultRot = DefinitionType_ofDefaultRot.sameAsCurveEnd; + + public static readonly float default_forwardWeightDistance_ofNewlyCreatedPoints = 1.0f; + public static readonly float default_backwardWeightDistance_ofNewlyCreatedPoints = 1.0f; + + [SerializeField] public float forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace = default_forwardWeightDistance_ofNewlyCreatedPoints; + [SerializeField] public float backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace = default_backwardWeightDistance_ofNewlyCreatedPoints; + [SerializeField] public InternalDXXL_BezierControlAnchorSubPoint.JunctureType junctureType_ofNewlyCreatedPoints = InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned; + + //Serialization of the list: + //-> In the serialized context the items and subItems of the list behave like structs that are copied by value, even if they are classes + //-> The list contains controlPoints and sub-controlPoints with cross references that should be copied by reference. There are constructions how this is possible via using "[SerializeReference]", but serialized lists/arrays/reorderableList seem not to be fully compatible with it. Obscure errors appear, for example when clicking the "choose presets symbol" in the component inspector, then these lists dissolve into nullRefExceptions, even if there aren't any presets available. Also other obscure errors for reorderable list like "list item not found" after deleting control points via custom buttons. + //-> see also Unitys documenation on Serialization: "Avoid nested, recursive structures where you reference other classes." + //-> Therefore the cross references of the subItems are implemented via fake properties: They don't "reference each other", but they reference only the list-carrying MonoBehaviour-inherited spline-component here and ask for the position of the "(quasi)referenced" other subItem inside the (quasi)struct. References from other gameobjects (that are bound to controlSubPoints via the "SplineConnection"-component) have to act in the same way: They cannot reference the subPoint where they are bound to "directly", but have to obtain it via the position inside the list-(quasi)struct. + [SerializeField] public List listOfControlPointTriplets = new List(); + + [SerializeField] Vector3 lastGlobalPositionOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf; + [SerializeField] Quaternion lastGlobalRotationOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf; + [SerializeField] Vector3 lastLossyScaleOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf; //known issue: if a parent transform scale is set to 0/0/0 in local draw space, then after setting the scale to a valid value again the spline shape cannot be retrieved and is melted to a single point + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + + customVector3Configs[0].picker_isOutfolded = true; + customVector3Configs[0].source = CustomVector3Source.manualInput; + customVector3Configs[0].clipboardForManualInput = Vector3.forward; + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[1].picker_isOutfolded = true; + customVector3Configs[1].source = CustomVector3Source.manualInput; + customVector3Configs[1].clipboardForManualInput = Vector3.forward; + customVector3Configs[1].vectorInterpretation = VectorInterpretation.globalSpace; + + drawSpace = DrawSpace.global; + + //-> Sidenote: Unitys documentation states that "Awake()" and "Start()" get called only once in the lifetime of a component. Thought there are still cases where this may be not fully true, or at least ambiguous: + //---> Case 1: If you create a component, then Awake()/Start() get called the first time. Then delete the component. Then undo the deletion with Unitys build-in Undo-functionality -> Awake()/Start() fire again. + //---> Case 2: If you create a component (first time Awake()/Start()), then copy the component, or the whole gameobject -> Awake()/Start() fire again. It is of course a new component, so the statement, that each component gets his Awake()/Start() only once is true, but if you initialize same data inside Awake()/Start(), then the already initialized data also gets copied to the new component. So then at least the DATA "has seen Awake()/Start() twice". + //---> Case 3: If you create the component in Edit mode (first time Awake()/Start()), then enter Playmode: -> Awake()/Start() fire again. Similar to "Case 2": The component is created newly onPlaymodeStart, so it is a "new" component...but it's data has seen "Awake()/Start()" twice. + + //-> "CreateFirstTwoControlPointsOfNewlyCreatedSpline()" should be executed in "Start()" and not in "Awake()", because: + //-> Unitys behaviour when copying a component in the editor seems to be somehow inconsistent. + //-> It can be observed at the "splineIsAlreadyInitialized"-bool. + //-> This bool is set to "true" as soon as a component is created, and from then on is never touched, so remains at "true" forever. + //-> When copying such a component which already has "splineIsAlreadyInitialized == true", there are different behaviours: + //---> When copying "the whole gameobject that hosts the component", then "splineIsAlreadyInitialized" is true in "Awake()" and "Start()" of the copied componet. This is as expected, because it's just a copy of the previous component, which already has it's "splineIsAlreadyInitialized" at true. + //---> Though when "copying only the component and attaching it somewhere else" (be it as copy on the same hosting gameobject or onto another gameobject) then "splineIsAlreadyInitialized" is "false" in "Awake()" (and in "OnEnable()"), but is "true" in "Start()". Maybe in this case internally a new component is created from scratch, and then AFTER firing "Awake()" and "OnEnable()" the serialized copied data is applied to the newly created object. The same behaviour happens for "create spline component -> undo create -> redo create". + //-> Why does it matter? + //---> The first two controlPoints are already created upfront when creating a new spline component from scratch. Though when copying an existing spline then there shouldn't be two additonal controlPoints added automatically. This behaviour depends on the "splineIsAlreadyInitialized"-bool + //---> More serious though is this: The Undo-functionality of the Editor can get into an errorneous state: + //------> If the assignments and functions called here in "Start()"-function would instead be executed in "Awake()" for a copied component, then the following sequences of actions produces the following repruducible errors (in Unity 2019.4 LTS): + //--------> Sequence 1: + //----------> Create spline component + //----------> Then "Undo" produces these error log messages: "CheckConsistency: GameObject does not reference component MonoBehaviour. Fixing." and "MissingReferenceException: The object of type 'BezierSplineDrawer' has been destroyed but you are still trying to access it." and "GUI Error: You are pushing more GUIClips than you are popping. Make sure they are balanced." + //----------> Then "Redo" crashes the Unity editor + //--------> Sequence 2: + //----------> Create spline component + //----------> Copy spline component to clipboard + //----------> Paste spline component as new (no matter if as copy on the same hosting gameobject or onto another gameobject) + //----------> So far it works. + //----------> But then "Undo" produces the same error mesages as in "Sequence 1": "CheckConsistency: ..." etc. + //----------> Then "Redo" crashes the Unity editor + //------> Other components don't have this problem. It might have something to do with the serialized list that is contained in this class. + CreateFirstTwoControlPointsOfNewlyCreatedSpline(); + } + + void CreateFirstTwoControlPointsOfNewlyCreatedSpline() + { + CreateNewControlPoint_atSplineEnd(); + CreateNewControlPoint_atSplineEnd(); + + Vector3 initialPosOfSecondControlPoint = listOfControlPointTriplets[1].anchorPoint.GetPos_inUnitsOfGlobalSpace() + 2.0f * Vector3.up - 0.75f * Vector3.forward; + listOfControlPointTriplets[1].anchorPoint.SetPos_inUnitsOfGlobalSpace(initialPosOfSecondControlPoint, true, null); + listOfControlPointTriplets[1].isHighlighted = false; + } + + void OnDestroy() + { + //"OnDestroy" is sometimes not fired. I don't see the clear reason for this. It is not always tied to the reason which the Unity documentation mentions (which is "OnDestroy() is not called for inactive gameobjects"). In the cases where it is not fired the boundGameobject.connectionComponent-references don't get reverted via "Undo (the spline deletion)". + TryDeleteAllBoundGameobjectConnectionsInclUndo(); + } + + public override void DrawVisualizedObject() + { + TryReApplyLocalDrawSpaceValues(); + + bool textHasBeenDrawn = false; + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + InternalDXXL_BezierControlPointTriplet currControlPointTriplet = listOfControlPointTriplets[i]; + InternalDXXL_BezierControlPointTriplet nextControlPointTriplet = GetNextControlPointTriplet(i, true); + textHasBeenDrawn = DrawBezierSegmentBetweenTwoControlPointTriplets(textHasBeenDrawn, currControlPointTriplet, nextControlPointTriplet); + } + DrawTextIfThereArentAnyControlPoints(); + } + + void TryReApplyLocalDrawSpaceValues() + { + bool reApplyLocalDrawSpaceValues = false; + if (drawSpace == DrawSpace.localDefinedByThisGameobject) + { + if (false == UtilitiesDXXL_Math.CheckIf_twoVectorsAreExactlyEqual(transform.position, lastGlobalPositionOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf)) + { + reApplyLocalDrawSpaceValues = true; + } + + if (false == UtilitiesDXXL_Math.CheckIf_twoQuaternionsAreExactlyEqual(transform.rotation, lastGlobalRotationOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf)) + { + reApplyLocalDrawSpaceValues = true; + } + + if (false == UtilitiesDXXL_Math.CheckIf_twoVectorsAreExactlyEqual(transform.lossyScale, lastLossyScaleOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf)) + { + reApplyLocalDrawSpaceValues = true; + } + } + + if (reApplyLocalDrawSpaceValues) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].Save_currentPosConfigInUnitsOfActiveDrawSpace_as_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace(); + listOfControlPointTriplets[i].ApplySaved_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace(); + } + Save_lastTransformStateOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf(); + } + } + + bool DrawBezierSegmentBetweenTwoControlPointTriplets(bool textHasBeenDrawn, InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentStart, InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentEnd) + { + if (controlPointTriplet_atSegmentEnd != null) + { + if (controlPointTriplet_atSegmentStart.forwardHelperPoint.isUsed == true) + { + if (controlPointTriplet_atSegmentEnd.backwardHelperPoint.isUsed == true) + { + DrawBasics.BezierSegmentCubic(controlPointTriplet_atSegmentStart.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentStart.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), color, GetTextForCurrentSegment(textHasBeenDrawn), lineWidth, straightSubDivisionsPerSegment, false, textSize, 0.0f, hiddenByNearerObjects); + } + else + { + DrawBasics.BezierSegmentQuadratic(controlPointTriplet_atSegmentStart.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentStart.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), color, GetTextForCurrentSegment(textHasBeenDrawn), lineWidth, straightSubDivisionsPerSegment, textSize, 0.0f, hiddenByNearerObjects); + } + } + else + { + if (controlPointTriplet_atSegmentEnd.backwardHelperPoint.isUsed == true) + { + DrawBasics.BezierSegmentQuadratic(controlPointTriplet_atSegmentStart.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(), color, GetTextForCurrentSegment(textHasBeenDrawn), lineWidth, straightSubDivisionsPerSegment, textSize, 0.0f, hiddenByNearerObjects); + } + else + { + Line_fadeableAnimSpeed.InternalDraw(controlPointTriplet_atSegmentStart.anchorPoint.GetPos_inUnitsOfGlobalSpace(), controlPointTriplet_atSegmentEnd.anchorPoint.GetPos_inUnitsOfGlobalSpace(), color, lineWidth, GetTextForCurrentSegment(textHasBeenDrawn), DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, 0.0f, hiddenByNearerObjects, false, false); + } + } + } + + textHasBeenDrawn = true; + return textHasBeenDrawn; + } + + string GetTextForCurrentSegment(bool textHasBeenDrawn) + { + return textHasBeenDrawn ? null : text_inclGlobalMarkupTags; + } + + void DrawTextIfThereArentAnyControlPoints() + { + Vector3 textPosGlobal = default; + if (text_inclGlobalMarkupTags != null && text_inclGlobalMarkupTags != "") + { + if (listOfControlPointTriplets.Count == 0) + { + textPosGlobal = Get_originPos_ofActiveDrawSpace_inUnitsOfGlobalSpace(); + } + + if ((listOfControlPointTriplets.Count == 1) && (gapFromEndToStart_isClosed == false)) + { + textPosGlobal = listOfControlPointTriplets[0].anchorPoint.GetPos_inUnitsOfGlobalSpace(); + } + + if (listOfControlPointTriplets.Count == 0 || ((listOfControlPointTriplets.Count == 1) && (gapFromEndToStart_isClosed == false))) + { + UtilitiesDXXL_Text.WriteFramed(text_inclGlobalMarkupTags, textPosGlobal, color, textSize, default(Vector3), default(Vector3), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, hiddenByNearerObjects); + } + } + } + + public void ResetAll_rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation() + { + if (listOfControlPointTriplets != null) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + switch (drawSpace) + { + case DrawSpace.global: + listOfControlPointTriplets[i].anchorPoint.rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation = Quaternion.identity; + break; + case DrawSpace.localDefinedByThisGameobject: + listOfControlPointTriplets[i].anchorPoint.rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation = transform.rotation; + break; + default: + break; + } + } + } + } + + public void CreateNewControlPoint_dueToPlusButtonBelowControlPointsListHasBeenClicked() + { + CreateNewControlPoint_atSplineEnd(); + } + + public void DeleteSelectedControlPoint_dueToMinusButtonBelowReorderableListHasBeenClicked() + { + //this function could be used for a "control points multiselection" feature + RegisterStateForUndo("Delete Spline Point(s)", true, true); + + bool atLeastOnePointHasBeenDeleted = false; + for (int i = listOfControlPointTriplets.Count - 1; i >= 0; i--) + { + if (listOfControlPointTriplets[i].isHighlighted) + { + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet(i); + listOfControlPointTriplets.RemoveAt(i); + atLeastOnePointHasBeenDeleted = true; + } + } + + if (atLeastOnePointHasBeenDeleted) + { + ReassignIndexesToAllControlPoints(); + TryDeactivateHelperPointsAtSplineEndsToVoid(); + } + } + + public void TryDeleteControlPoint_dueToMinusButtonAtControlPointListItemHasBeenClicked(int i_ofItemToDelete) + { + RegisterStateForUndo("Delete Spline Point(s)", true, true); + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet(i_ofItemToDelete); + listOfControlPointTriplets.RemoveAt(i_ofItemToDelete); + ReassignIndexesToAllControlPoints(); + TryDeactivateHelperPointsAtSplineEndsToVoid(); + } + + void TryDeleteAllBoundGameobjectConnectionsInclUndo() + { + //-> this ensures the retrieval of the boundGameobject-references if after spline-deletion "Editor/Undo" is used + if (listOfControlPointTriplets != null) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet(i); + } + } + } + + void DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet(int i_ofControlPointTripletWhereConnectionsGetDeleted) + { + if (Application.isPlaying) + { + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet_nonImmediate(i_ofControlPointTripletWhereConnectionsGetDeleted); + } + else + { + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet_immediate(i_ofControlPointTripletWhereConnectionsGetDeleted); + } + } + + void DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet_nonImmediate(int i_ofControlPointTripletWhereConnectionsGetDeleted) + { + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].backwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + Destroy(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].backwardHelperPoint.connectionComponent_onBoundGameobject); + } + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].anchorPoint.connectionComponent_onBoundGameobject != null) + { + Destroy(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].anchorPoint.connectionComponent_onBoundGameobject); + } + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].forwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + Destroy(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].forwardHelperPoint.connectionComponent_onBoundGameobject); + } + } + + void DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet_immediate(int i_ofControlPointTripletWhereConnectionsGetDeleted) + { +#if UNITY_EDITOR + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].backwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.DestroyObjectImmediate(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].backwardHelperPoint.connectionComponent_onBoundGameobject); + } + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].anchorPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.DestroyObjectImmediate(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].anchorPoint.connectionComponent_onBoundGameobject); + } + if (listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].forwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.DestroyObjectImmediate(listOfControlPointTriplets[i_ofControlPointTripletWhereConnectionsGetDeleted].forwardHelperPoint.connectionComponent_onBoundGameobject); + } +#else + DeleteConnectionComponentsOfBoundGameobjects_onWholeControlPointTriplet_nonImmediate(i_ofControlPointTripletWhereConnectionsGetDeleted); +#endif + } + + public void DeleteConnectionComponentOfBoundGameobject_onControlSubPoint(int i_ofControlPointWhereConnectionsGetDeleted, InternalDXXL_BezierControlSubPoint.SubPointType subPointType_whereConnectionsGetDeleted) + { + if (Application.isPlaying) + { + DeleteConnectionComponentOfBoundGameobject_onControlSubPoint_nonImmediate(i_ofControlPointWhereConnectionsGetDeleted, subPointType_whereConnectionsGetDeleted); + } + else + { + DeleteConnectionComponentOfBoundGameobject_onControlSubPoint_immediate(i_ofControlPointWhereConnectionsGetDeleted, subPointType_whereConnectionsGetDeleted); + } + } + + public void DeleteConnectionComponentOfBoundGameobject_onControlSubPoint_nonImmediate(int i_ofControlPointWhereConnectionsGetDeleted, InternalDXXL_BezierControlSubPoint.SubPointType subPointType_whereConnectionsGetDeleted) + { + if (listOfControlPointTriplets[i_ofControlPointWhereConnectionsGetDeleted].GetASubPoint(subPointType_whereConnectionsGetDeleted).connectionComponent_onBoundGameobject != null) + { + Destroy(listOfControlPointTriplets[i_ofControlPointWhereConnectionsGetDeleted].GetASubPoint(subPointType_whereConnectionsGetDeleted).connectionComponent_onBoundGameobject); + } + } + + public void DeleteConnectionComponentOfBoundGameobject_onControlSubPoint_immediate(int i_ofControlPointWhereConnectionsGetDeleted, InternalDXXL_BezierControlSubPoint.SubPointType subPointType_whereConnectionsGetDeleted) + { +#if UNITY_EDITOR + if (listOfControlPointTriplets[i_ofControlPointWhereConnectionsGetDeleted].GetASubPoint(subPointType_whereConnectionsGetDeleted).connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.DestroyObjectImmediate(listOfControlPointTriplets[i_ofControlPointWhereConnectionsGetDeleted].GetASubPoint(subPointType_whereConnectionsGetDeleted).connectionComponent_onBoundGameobject); + } +#else + DeleteConnectionComponentOfBoundGameobject_onControlSubPoint_nonImmediate(i_ofControlPointWhereConnectionsGetDeleted, subPointType_whereConnectionsGetDeleted); +#endif + } + + void TryDeactivateHelperPointsAtSplineEndsToVoid() + { + if (gapFromEndToStart_isClosed == false) + { + if (listOfControlPointTriplets.Count > 0) + { + listOfControlPointTriplets[0].backwardHelperPoint.ChangeUsedState(false, false); + listOfControlPointTriplets[0].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + + int i_ofLastControlPoint = listOfControlPointTriplets.Count - 1; + listOfControlPointTriplets[i_ofLastControlPoint].forwardHelperPoint.ChangeUsedState(false, false); + listOfControlPointTriplets[i_ofLastControlPoint].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + } + } + } + + public void CreateNewControlPoint_atSplineEnd() + { + RegisterStateForUndo("Add Spline Point", false, false); + InternalDXXL_BezierControlPointTriplet newControlPointTriplet = new InternalDXXL_BezierControlPointTriplet(); + listOfControlPointTriplets.Add(newControlPointTriplet); + ReassignIndexesToAllControlPoints(); + + if (listOfControlPointTriplets.Count >= 2) + { + InitializeNewlyCreatedControlPoint_atSplineEnd(); + } + else + { + InitializeFirstControlPoint(); + } + + SetSelectedListSlot(listOfControlPointTriplets.Count - 1); + } + + public void CreateNewControlPoint_atSplineStart() + { + RegisterStateForUndo("Add Spline Point", false, false); + InternalDXXL_BezierControlPointTriplet newControlPointTriplet = new InternalDXXL_BezierControlPointTriplet(); + listOfControlPointTriplets.Insert(0, newControlPointTriplet); + ReassignIndexesToAllControlPoints(); + + if (listOfControlPointTriplets.Count >= 2) + { + InitializeNewControlPoint_atSplineStart(); + SetSelectedListSlot(0); + } + else + { + UtilitiesDXXL_Log.PrintErrorCode("56-" + listOfControlPointTriplets.Count); + } + } + + public void CreateNewControlPoint_somewhereOnUpcomingSplineSegment(int i_startOfSegmentPreInsert) + { + RegisterStateForUndo("Add Spline Point", false, false); + + InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentStartPreInsert = listOfControlPointTriplets[i_startOfSegmentPreInsert]; + InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentEndPreInsert = controlPointTriplet_atSegmentStartPreInsert.GetNextControlPointTripletAlongSplineDir(true); + + if (controlPointTriplet_atSegmentEndPreInsert != null) + { + Vector3 posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentStartPreInsert.GetPosAtPlusButton_onUpcomingBezierSegment_inUnitsOfGlobalSpace(); + + if (controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.isUsed == true) + { + if (controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.isUsed == true) + { + CreateSubdividingControlPoint_insideCubicSegment(i_startOfSegmentPreInsert, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentStartPreInsert, controlPointTriplet_atSegmentEndPreInsert); + } + else + { + CreateSubdividingControlPoint_insideQuadraticSegmentThatHasOnlyStartPointsForwardHelper(i_startOfSegmentPreInsert, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentStartPreInsert, controlPointTriplet_atSegmentEndPreInsert); + } + } + else + { + if (controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.isUsed == true) + { + CreateSubdividingControlPoint_insideQuadraticSegmentThatHasOnlyEndPointsBackwardHelper(i_startOfSegmentPreInsert, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentStartPreInsert, controlPointTriplet_atSegmentEndPreInsert); + } + else + { + CreateSubdividingControlPoint_insideStraightSegmentThatHasNoHelpers(i_startOfSegmentPreInsert, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentStartPreInsert, controlPointTriplet_atSegmentEndPreInsert); + } + } + + controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment = 0.5f; + } + else + { + UtilitiesDXXL_Log.PrintErrorCode("33-" + i_startOfSegmentPreInsert + "-" + listOfControlPointTriplets.Count + "" + gapFromEndToStart_isClosed); + } + } + + void CreateSubdividingControlPoint_insideCubicSegment(int i_startOfSegmentPreInsert, Vector3 posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentStartPreInsert, InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentEndPreInsert) + { + InternalDXXL_BezierControlPointTriplet newlyCreatedControlPointTriplet = InsertUninitializedNewControlPointIntoList(i_startOfSegmentPreInsert); + Vector3 initialDirection_normalized = Vector3.forward; //-> is anyway not used, but immediately overwritten inside this function + newlyCreatedControlPointTriplet.Initialize(this, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialDirection_normalized, InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned); + + //all vectors are meant "_inUnitsOfGlobalSpace": + float progress0to1_insidePreInsertSegment = controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + + Vector3 from_preInsertStartForwardHelper_to_preInsertEndBackwardHelper = controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace() - controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 interpolatedPosOnStrech_from_preInsertForwardHelper_to_preInsertEndBackwardHelper = controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace() + from_preInsertStartForwardHelper_to_preInsertEndBackwardHelper * progress0to1_insidePreInsertSegment; + Vector3 from_anchorOfStartPointPreInsert_to_forwardHelperOfStartPointPostInsert = (controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace() - controlPointTriplet_atSegmentStartPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace()) * progress0to1_insidePreInsertSegment; + Vector3 startPointsForwardHelperPostInsert = controlPointTriplet_atSegmentStartPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace() + from_anchorOfStartPointPreInsert_to_forwardHelperOfStartPointPostInsert; + Vector3 from_forwardHelperOfStartPointPostInsert_interpolatedPosOnPreInsertStartHelperToEndHelper = interpolatedPosOnStrech_from_preInsertForwardHelper_to_preInsertEndBackwardHelper - startPointsForwardHelperPostInsert; + Vector3 posOfBackwardHelper_ofNewlyCreatedControlPoint = startPointsForwardHelperPostInsert + from_forwardHelperOfStartPointPostInsert_interpolatedPosOnPreInsertStartHelperToEndHelper * progress0to1_insidePreInsertSegment; + newlyCreatedControlPointTriplet.backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfBackwardHelper_ofNewlyCreatedControlPoint, true, null); + + float new_absDistanceOfBackwardHelperOfPreInsertEndPoint_ifSegmentWouldNotBeMirrorForced = controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace() * (1.0f - progress0to1_insidePreInsertSegment); + Vector3 vector_fromPreInsertSegmentEndAnchor_toPreInsertSegmentEndBackwardHelperAfterInsert_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized() * new_absDistanceOfBackwardHelperOfPreInsertEndPoint_ifSegmentWouldNotBeMirrorForced; + Vector3 pos_ofPreInsertSegmentEndBackwardHelperAfterInsert_inUnitsOfGlobalSpace_ifSegmentWouldNotBeMirrorForced = controlPointTriplet_atSegmentEndPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace() + vector_fromPreInsertSegmentEndAnchor_toPreInsertSegmentEndBackwardHelperAfterInsert_inUnitsOfGlobalSpace; + if (controlPointTriplet_atSegmentEndPreInsert.anchorPoint.junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(pos_ofPreInsertSegmentEndBackwardHelperAfterInsert_inUnitsOfGlobalSpace_ifSegmentWouldNotBeMirrorForced, true, null); + } + else + { + LogMessageThatExplainsWhyTheSplineShapeChangedOnPointCreation(false); + } + + Vector3 from_interpolatedPosOnPreInsertStartHelperToEndHelper_to_endPointsBackwardHelperPostInsert = pos_ofPreInsertSegmentEndBackwardHelperAfterInsert_inUnitsOfGlobalSpace_ifSegmentWouldNotBeMirrorForced - interpolatedPosOnStrech_from_preInsertForwardHelper_to_preInsertEndBackwardHelper; + Vector3 posOfForwardHelper_ofNewlyCreatedControlPoint = interpolatedPosOnStrech_from_preInsertForwardHelper_to_preInsertEndBackwardHelper + from_interpolatedPosOnPreInsertStartHelperToEndHelper_to_endPointsBackwardHelperPostInsert * progress0to1_insidePreInsertSegment; + newlyCreatedControlPointTriplet.forwardHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfForwardHelper_ofNewlyCreatedControlPoint, true, null); + + ScaleForwardDistance_ofPreInsertStartPoint(controlPointTriplet_atSegmentStartPreInsert); + SetDefaultJunctureType_forCase_createInsideCubicSegment(newlyCreatedControlPointTriplet); + } + + void SetDefaultJunctureType_forCase_createInsideCubicSegment(InternalDXXL_BezierControlPointTriplet newlyCreatedControlPointTriplet) + { + if (junctureType_ofNewlyCreatedPoints == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored); + Debug.Log("Spline Position Creation Information: The spline segment before the newly created control point doesn't fit the spline shape from before the point was created. The reason for this is that the default juncture type of newly created control points is 'mirrored'. It is not possible to keep the spline shape with this constraint."); + } + + if (junctureType_ofNewlyCreatedPoints == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + } + } + + void CreateSubdividingControlPoint_insideQuadraticSegmentThatHasOnlyStartPointsForwardHelper(int i_startOfSegmentPreInsert, Vector3 posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentStartPreInsert, InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentEndPreInsert) + { + if (controlPointTriplet_atSegmentEndPreInsert.anchorPoint.junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + UtilitiesDXXL_Log.PrintErrorCode("43-" + i_startOfSegmentPreInsert + "-" + listOfControlPointTriplets.Count + "-" + gapFromEndToStart_isClosed + "-" + controlPointTriplet_atSegmentStartPreInsert.anchorPoint.junctureType + "-" + controlPointTriplet_atSegmentEndPreInsert.anchorPoint.junctureType); + return; + } + + InternalDXXL_BezierControlPointTriplet newlyCreatedControlPointTriplet = InsertUninitializedNewControlPointIntoList(i_startOfSegmentPreInsert); + Vector3 initialDirection_normalized = Vector3.forward; //-> is anyway not used, but immediately overwritten inside this function + newlyCreatedControlPointTriplet.Initialize(this, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialDirection_normalized, junctureType_ofNewlyCreatedPoints); + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + newlyCreatedControlPointTriplet.backwardHelperPoint.ChangeUsedState(false, false); + + Vector3 from_forwardHelperPosOfPreInsertStartPoint_to_preInsertEndPointAnchor_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentEndPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace() - controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 posOfForwardHelper_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.GetPos_inUnitsOfGlobalSpace() + from_forwardHelperPosOfPreInsertStartPoint_to_preInsertEndPointAnchor_inUnitsOfGlobalSpace * controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + newlyCreatedControlPointTriplet.forwardHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfForwardHelper_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace, true, null); + + ScaleForwardDistance_ofPreInsertStartPoint(controlPointTriplet_atSegmentStartPreInsert); + SetDefaultJunctureType_forCase_createInsideQuadraticSegment(newlyCreatedControlPointTriplet, "before", "end"); + } + + void CreateSubdividingControlPoint_insideQuadraticSegmentThatHasOnlyEndPointsBackwardHelper(int i_startOfSegmentPreInsert, Vector3 posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentStartPreInsert, InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentEndPreInsert) + { + if (controlPointTriplet_atSegmentStartPreInsert.anchorPoint.junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + UtilitiesDXXL_Log.PrintErrorCode("44-" + i_startOfSegmentPreInsert + "-" + listOfControlPointTriplets.Count + "-" + gapFromEndToStart_isClosed + "-" + controlPointTriplet_atSegmentStartPreInsert.anchorPoint.junctureType + "-" + controlPointTriplet_atSegmentEndPreInsert.anchorPoint.junctureType); + return; + } + + InternalDXXL_BezierControlPointTriplet newlyCreatedControlPointTriplet = InsertUninitializedNewControlPointIntoList(i_startOfSegmentPreInsert); + Vector3 initialDirection_normalized = Vector3.forward; //-> is anyway not used, but immediately overwritten inside this function + newlyCreatedControlPointTriplet.Initialize(this, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialDirection_normalized, junctureType_ofNewlyCreatedPoints); + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + newlyCreatedControlPointTriplet.forwardHelperPoint.ChangeUsedState(false, false); + + Vector3 from_anchorPosOfPreInsertStartPoint_to_preInsertEndPointsBackwardHelper_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace() - controlPointTriplet_atSegmentStartPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 posOfBackwardHelper_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentStartPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace() + from_anchorPosOfPreInsertStartPoint_to_preInsertEndPointsBackwardHelper_inUnitsOfGlobalSpace * controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + newlyCreatedControlPointTriplet.backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(posOfBackwardHelper_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace, true, null); + + if (controlPointTriplet_atSegmentEndPreInsert.anchorPoint.junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + float new_absDistanceOfBackwardHelperOfPreInsertEndPoint_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace() * (1.0f - controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment); + controlPointTriplet_atSegmentEndPreInsert.backwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(new_absDistanceOfBackwardHelperOfPreInsertEndPoint_inUnitsOfGlobalSpace, true, null); + } + else + { + LogMessageThatExplainsWhyTheSplineShapeChangedOnPointCreation(false); + } + + SetDefaultJunctureType_forCase_createInsideQuadraticSegment(newlyCreatedControlPointTriplet, "after", "start"); + } + + void SetDefaultJunctureType_forCase_createInsideQuadraticSegment(InternalDXXL_BezierControlPointTriplet newlyCreatedControlPointTriplet, string segment_identifier, string disabledWeightPoint_identifier) + { + if (junctureType_ofNewlyCreatedPoints == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned) + { + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned); + LogInfoThatSplineShapeChangedOnPointCreation_dueToDefaultJunctureTypeDoesntFitQuadraticSegment(segment_identifier, disabledWeightPoint_identifier, "an"); + } + + if (junctureType_ofNewlyCreatedPoints == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + newlyCreatedControlPointTriplet.anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored); + LogInfoThatSplineShapeChangedOnPointCreation_dueToDefaultJunctureTypeDoesntFitQuadraticSegment(segment_identifier, disabledWeightPoint_identifier, "a"); + } + } + + void LogInfoThatSplineShapeChangedOnPointCreation_dueToDefaultJunctureTypeDoesntFitQuadraticSegment(string segment_identifier, string disabledWeightPoint_identifier, string indefiniteArticle_ofDefaultJunctureType) + { + Debug.Log("Spline Position Creation Information: The spline segment " + segment_identifier + " the newly created control point doesn't fit the spline shape from before the point was created. The reason for this is that the default juncture type of newly created control points is '" + junctureType_ofNewlyCreatedPoints + "', but the weight point at the " + disabledWeightPoint_identifier + " of the pre-insert segment is disabled. It is not possible to keep the spline shape with " + indefiniteArticle_ofDefaultJunctureType + " " + junctureType_ofNewlyCreatedPoints + " juncture type if not both weight points of the pre-insert segment are enabled."); + } + + void ScaleForwardDistance_ofPreInsertStartPoint(InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentStartPreInsert) + { + if (controlPointTriplet_atSegmentStartPreInsert.anchorPoint.junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + float new_absDistanceOfForwardHelperOfPreInsertStartPoint_inUnitsOfGlobalSpace = controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace() * controlPointTriplet_atSegmentStartPreInsert.progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + controlPointTriplet_atSegmentStartPreInsert.forwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(new_absDistanceOfForwardHelperOfPreInsertStartPoint_inUnitsOfGlobalSpace, true, null); + } + else + { + LogMessageThatExplainsWhyTheSplineShapeChangedOnPointCreation(true); + } + } + + void LogMessageThatExplainsWhyTheSplineShapeChangedOnPointCreation(bool theMessageCorrespondsTo_theSplinePartAtPreInsertSTARTpoint_notAtPreInsertENDpoint) + { + string segment_identifier; //-> this is actually only specified to prevent the confusion that the same message could be thrown twice for a single point creation + if (theMessageCorrespondsTo_theSplinePartAtPreInsertSTARTpoint_notAtPreInsertENDpoint) + { + segment_identifier = "before"; + } + else + { + segment_identifier = "after"; + } + Debug.Log("Spline Position Creation Information: The spline segment " + segment_identifier + " the newly created control point doesn't fit the spline shape from before the point was created. The reason for this is that the neighboring control point has a 'mirrored' juncture type. Otherwise the neighboring segment would have changed it's shape."); + } + + void CreateSubdividingControlPoint_insideStraightSegmentThatHasNoHelpers(int i_startOfSegmentPreInsert, Vector3 posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentStartPreInsert, InternalDXXL_BezierControlPointTriplet controlPointTriplet_atSegmentEndPreInsert) + { + InternalDXXL_BezierControlPointTriplet newlyCreatedControlPointTriplet = InsertUninitializedNewControlPointIntoList(i_startOfSegmentPreInsert); + Vector3 initialDirection_normalized = Vector3.forward; //-> is anyway not used, but immediately overwritten inside this function + newlyCreatedControlPointTriplet.Initialize(this, posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialDirection_normalized, junctureType_ofNewlyCreatedPoints); + + Vector3 initialPosOfForwardHelper_inUnitsOfGlobalSpace = UtilitiesDXXL_Math.GetCenterBetweenTwoPoints(posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentEndPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace()); + newlyCreatedControlPointTriplet.forwardHelperPoint.SetPos_inUnitsOfGlobalSpace(initialPosOfForwardHelper_inUnitsOfGlobalSpace, true, null); + + Vector3 initialPosOfBackwardHelper_inUnitsOfGlobalSpace = UtilitiesDXXL_Math.GetCenterBetweenTwoPoints(posOfNewlyCreatedControlPoint_inUnitsOfGlobalSpace, controlPointTriplet_atSegmentStartPreInsert.anchorPoint.GetPos_inUnitsOfGlobalSpace()); + newlyCreatedControlPointTriplet.backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(initialPosOfBackwardHelper_inUnitsOfGlobalSpace, true, null); + } + + InternalDXXL_BezierControlPointTriplet InsertUninitializedNewControlPointIntoList(int i_startOfSegmentPreInsert) + { + InternalDXXL_BezierControlPointTriplet newControlPointTriplet = new InternalDXXL_BezierControlPointTriplet(); + int i_insertionSlot = i_startOfSegmentPreInsert + 1; + listOfControlPointTriplets.Insert(i_insertionSlot, newControlPointTriplet); + ReassignIndexesToAllControlPoints(); + return newControlPointTriplet; + } + + public void ReassignIndexesToAllControlPoints() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].ReassignIndexInsideControlPointsList(i); + } + } + + void InitializeFirstControlPoint() + { + Vector3 initialPos_inUnitsOfGlobalSpace = Get_originPos_ofActiveDrawSpace_inUnitsOfGlobalSpace(); + Vector3 initialForwardDir_inUnitsOfGlobalSpace_normalized = Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + + listOfControlPointTriplets[0].Initialize(this, initialPos_inUnitsOfGlobalSpace, initialForwardDir_inUnitsOfGlobalSpace_normalized, junctureType_ofNewlyCreatedPoints); + + if (gapFromEndToStart_isClosed == false) + { + listOfControlPointTriplets[0].backwardHelperPoint.ChangeUsedState(false, false); + listOfControlPointTriplets[0].forwardHelperPoint.ChangeUsedState(false, false); + listOfControlPointTriplets[0].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + } + ResetAll_rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation(); + } + + void InitializeNewlyCreatedControlPoint_atSplineEnd() + { + int i_ofNewControlPoint = listOfControlPointTriplets.Count - 1; //"i_ofNewControlPoint" is guaranteed bigger than 0 here, so the controlPoint list has at least 2 items + InternalDXXL_BezierControlPointTriplet previouslyLastControlPointTriplet = GetPreviousControlPointTriplet(i_ofNewControlPoint, false); + Vector3 previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized = Get_previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized(previouslyLastControlPointTriplet); + float distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace = Get_distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace(); + Vector3 initialPos_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace = previouslyLastControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace() + previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized * distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace; + Vector3 initialForwardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized = Get_initialFowardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized(previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized); + + listOfControlPointTriplets[i_ofNewControlPoint].Initialize(this, initialPos_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialForwardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized, junctureType_ofNewlyCreatedPoints); + + if (gapFromEndToStart_isClosed == false) + { + listOfControlPointTriplets[i_ofNewControlPoint].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + listOfControlPointTriplets[i_ofNewControlPoint].forwardHelperPoint.ChangeUsedState(false, false); + + int i_ofPreviouslyLastControlPoint = i_ofNewControlPoint - 1; + if (listOfControlPointTriplets[i_ofPreviouslyLastControlPoint].IsEndPointToVoid_atStartOrEndOfAnUnclosedSpline() == false) + { + listOfControlPointTriplets[i_ofPreviouslyLastControlPoint].anchorPoint.SetJunctureType(junctureType_ofNewlyCreatedPoints); + } + listOfControlPointTriplets[i_ofPreviouslyLastControlPoint].forwardHelperPoint.ChangeUsedState(true, false); //-> this is for the case when "junctureType_ofNewlyCreatedPoints == kinked". Then "SetJunctureType" doesn't do anything (since the new junctureType doesn't differ from the previous one) and therefore also didn't activate the formerly unused forwardHelper + } + ResetAll_rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation(); + } + + void InitializeNewControlPoint_atSplineStart() + { + //"listOfControlPointRefs.Count" is guaranteed bigger than 0 here, so the controlPoint list has at least 2 items + InternalDXXL_BezierControlPointTriplet previouslyFirstControlPointTriplet = listOfControlPointTriplets[1]; + Vector3 previouslyFirstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized = Get_firstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized(previouslyFirstControlPointTriplet); + float distance_from_prevFirstControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace = Get_distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace(); + Vector3 initialPos_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace = previouslyFirstControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace() + previouslyFirstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized * distance_from_prevFirstControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace; + Vector3 initialForwardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized = Get_initialFowardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized(-previouslyFirstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized); + + listOfControlPointTriplets[0].Initialize(this, initialPos_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace, initialForwardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized, junctureType_ofNewlyCreatedPoints); + + if (gapFromEndToStart_isClosed == false) + { + listOfControlPointTriplets[0].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + listOfControlPointTriplets[0].backwardHelperPoint.ChangeUsedState(false, false); + + int i_ofPreviouslyFirstControlPoint = 1; + if (listOfControlPointTriplets[i_ofPreviouslyFirstControlPoint].IsEndPointToVoid_atStartOrEndOfAnUnclosedSpline() == false) + { + listOfControlPointTriplets[i_ofPreviouslyFirstControlPoint].anchorPoint.SetJunctureType(junctureType_ofNewlyCreatedPoints); + } + listOfControlPointTriplets[i_ofPreviouslyFirstControlPoint].backwardHelperPoint.ChangeUsedState(true, false); //-> this is for the case when "junctureType_ofNewlyCreatedPoints == kinked". Then "SetJunctureType" doesn't do anything (since the new junctureType doesn't differ from the previous one) and therefore also didn't activate the formerly unused backwardHelper + } + ResetAll_rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation(); + } + + public Vector3 Get_previouslyLastControlPoint_to_newlyCreatedControlPointAtSplineEnd_inUnitsOfGlobalSpace_normalized(InternalDXXL_BezierControlPointTriplet previouslyLastControlPointTriplet) + { + //Caller has to take into account: This function may return the zero vector + switch (definitionType_ofDefaultPosOffset) + { + case DefinitionType_ofDefaultPosOffset.straightExtentionOfCurveEnd: + return Get_forwardTangent_ofControlPointThatDoesntKnowOfANextOne_inUnitsOfGlobalSpace_normalized(previouslyLastControlPointTriplet); + case DefinitionType_ofDefaultPosOffset.customOffset: + Vector3 posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace = Get_posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace(); + return UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace); + default: + return Vector3.forward; + } + } + + public Vector3 Get_forwardTangent_ofControlPointThatDoesntKnowOfANextOne_inUnitsOfGlobalSpace_normalized(InternalDXXL_BezierControlPointTriplet controlPointTriplet_thatDoesntKnowOfANextOne) + { + if (controlPointTriplet_thatDoesntKnowOfANextOne.backwardHelperPoint.isUsed) + { + return (-controlPointTriplet_thatDoesntKnowOfANextOne.anchorPoint.Get_direction_toBackward_inUnitsOfGlobalSpace_normalized()); + } + else + { + InternalDXXL_BezierControlSubPoint previousUsedNonSuperimposedSubPoint = controlPointTriplet_thatDoesntKnowOfANextOne.backwardHelperPoint.GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + if (previousUsedNonSuperimposedSubPoint != null) + { + Vector3 previousUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace = controlPointTriplet_thatDoesntKnowOfANextOne.anchorPoint.GetPos_inUnitsOfGlobalSpace() - previousUsedNonSuperimposedSubPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 previousUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(previousUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(previousUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized)) + { + return Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + else + { + return previousUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized; + } + } + else + { + return Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + } + } + + public Vector3 Get_firstControlPoint_to_newlyCreatedControlPointAtSplineStart_inUnitsOfGlobalSpace_normalized(InternalDXXL_BezierControlPointTriplet previouslyFirstControlPointTriplet) + { + //Caller has to take into account: This function may return the zero vector + switch (definitionType_ofDefaultPosOffset) + { + case DefinitionType_ofDefaultPosOffset.straightExtentionOfCurveEnd: + return Get_backwardTangent_ofControlPointThatDoesntKnowOfAPreviousOne_inUnitsOfGlobalSpace_normalized(previouslyFirstControlPointTriplet); + case DefinitionType_ofDefaultPosOffset.customOffset: + Vector3 posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace = Get_posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace(); + return (-UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace)); + default: + return Vector3.forward; + } + } + + public Vector3 Get_backwardTangent_ofControlPointThatDoesntKnowOfAPreviousOne_inUnitsOfGlobalSpace_normalized(InternalDXXL_BezierControlPointTriplet controlPointTriplet_thatDoesntKnowOfAPreviousOne) + { + if (controlPointTriplet_thatDoesntKnowOfAPreviousOne.forwardHelperPoint.isUsed) + { + return (-controlPointTriplet_thatDoesntKnowOfAPreviousOne.anchorPoint.Get_direction_toForward_inUnitsOfGlobalSpace_normalized()); + } + else + { + InternalDXXL_BezierControlSubPoint nextUsedNonSuperimposedSubPoint = controlPointTriplet_thatDoesntKnowOfAPreviousOne.forwardHelperPoint.GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + if (nextUsedNonSuperimposedSubPoint != null) + { + Vector3 nextUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace = controlPointTriplet_thatDoesntKnowOfAPreviousOne.anchorPoint.GetPos_inUnitsOfGlobalSpace() - nextUsedNonSuperimposedSubPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 nextUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(nextUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(nextUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized)) + { + return (-Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized()); + } + else + { + return nextUsedNonSuperimposedSubPoint_to_requestingControlPointsAnchor_inUnitsOfGlobalSpace_normalized; + } + } + else + { + return (-Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized()); + } + } + } + + public float Get_distance_from_prevLastControlPoint_to_newlyCreatedControlPoint_inUnitsOfGlobalSpace() + { + switch (definitionType_ofDefaultPosOffset) + { + case DefinitionType_ofDefaultPosOffset.straightExtentionOfCurveEnd: + return TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(distanceBetweenTriplets_forNewlyCreatedTriplets_caseOf_straightExtentionOfCurveEnd_inUnitsOfActiveDrawSpace); + case DefinitionType_ofDefaultPosOffset.customOffset: + return Get_posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace().magnitude; + default: + return 1.0f; + } + } + + Vector3 Get_initialFowardDir_ofNewlyCreatedControlPoint_inUnitsOfGlobalSpace_normalized(Vector3 forwardDirThatRepresents_asCurveEnd_inUnitsOfGlobalSpace_normalized) + { + //"forwardDirThatRepresents_asCurveEnd_inUnitsOfGlobalSpace_normalized" may be zero vector here. + switch (definitionType_ofDefaultRot) + { + case DefinitionType_ofDefaultRot.sameAsCurveEnd: + return ReturnGivenVector_orForTooShortVectorsFallbackToActiveDrawSpaceForward(forwardDirThatRepresents_asCurveEnd_inUnitsOfGlobalSpace_normalized); + case DefinitionType_ofDefaultRot.customOrientation: + Vector3 forwardDirOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace = Get_orientationOfNewlyCreatedPointAsForwardDirection_atSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace(); + Vector3 forwardDirOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(forwardDirOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace); + return ReturnGivenVector_orForTooShortVectorsFallbackToActiveDrawSpaceForward(forwardDirOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace_normalized); + default: + return Vector3.forward; + } + } + + Vector3 ReturnGivenVector_orForTooShortVectorsFallbackToActiveDrawSpaceForward(Vector3 givenVector_normalizedOrTooShort) + { + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(givenVector_normalizedOrTooShort)) + { + return Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + else + { + return givenVector_normalizedOrTooShort; + } + } + + public void SetSelectedListSlot(int i_toSelect) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].isHighlighted = (i == i_toSelect); + } + } + + public int Get_i_ofFirstHighlightedControlPoint() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].isHighlighted) + { + return i; + } + } + return (-1); + } + + public int GetNumberOfHighlightedControlPoints() + { + int number = 0; + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].isHighlighted) + { + number++; + } + } + return number; + } + + public bool IsFirstControlPoint(int i) + { + return (i == 0); + } + + public bool IsLastControlPoint(int i) + { + return (i == (listOfControlPointTriplets.Count - 1)); + } + + public bool IsFirstControlPoint(InternalDXXL_BezierControlPointTriplet controlPoint_toCheck) + { + if (listOfControlPointTriplets.Count > 0) + { + return (listOfControlPointTriplets[0] == controlPoint_toCheck); + } + else + { + return false; + } + } + + public bool IsLastControlPoint(InternalDXXL_BezierControlPointTriplet controlPoint_toCheck) + { + if (listOfControlPointTriplets.Count > 0) + { + return (listOfControlPointTriplets[listOfControlPointTriplets.Count - 1] == controlPoint_toCheck); + } + else + { + return false; + } + } + + public InternalDXXL_BezierControlPointTriplet GetNextControlPointTriplet(int i_ofRequestingControlPoint, bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (gapFromEndToStart_isClosed) + { + if (listOfControlPointTriplets.Count == 0) + { + return null; + } + else + { + if (listOfControlPointTriplets.Count == 1) + { + if (allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (i_ofRequestingControlPoint != 0) + { + UtilitiesDXXL_Log.PrintErrorCode("47-" + i_ofRequestingControlPoint); + } + return listOfControlPointTriplets[0]; + } + else + { + return null; + } + } + else + { + int i_ofNextControlPoint = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i_ofRequestingControlPoint + 1, listOfControlPointTriplets.Count); + return listOfControlPointTriplets[i_ofNextControlPoint]; + } + } + } + else + { + if (IsLastControlPoint(i_ofRequestingControlPoint)) + { + return null; + } + else + { + return listOfControlPointTriplets[i_ofRequestingControlPoint + 1]; + } + } + } + + public InternalDXXL_BezierControlPointTriplet GetPreviousControlPointTriplet(int i_ofRequestingControlPoint, bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (gapFromEndToStart_isClosed) + { + if (listOfControlPointTriplets.Count == 0) + { + return null; + } + else + { + if (listOfControlPointTriplets.Count == 1) + { + if (allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (i_ofRequestingControlPoint != 0) + { + UtilitiesDXXL_Log.PrintErrorCode("48-" + i_ofRequestingControlPoint); + } + return listOfControlPointTriplets[0]; + } + else + { + return null; + } + } + else + { + int i_ofPreviousControlPoint = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i_ofRequestingControlPoint - 1, listOfControlPointTriplets.Count); + return listOfControlPointTriplets[i_ofPreviousControlPoint]; + } + } + } + else + { + if (IsFirstControlPoint(i_ofRequestingControlPoint)) + { + return null; + } + else + { + return listOfControlPointTriplets[i_ofRequestingControlPoint - 1]; + } + } + } + + public InternalDXXL_BezierControlPointTriplet GetNextControlPointTriplet(InternalDXXL_BezierControlPointTriplet controlPoint_forWhichToGetTheNextNeighbor, bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return GetNextControlPointTriplet(controlPoint_forWhichToGetTheNextNeighbor.i_ofThisPoint_insideControlPointsList, allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + + public InternalDXXL_BezierControlPointTriplet GetPreviousControlPointTriplet(InternalDXXL_BezierControlPointTriplet controlPoint_forWhichToGetThePreviousNeighbor, bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return GetPreviousControlPointTriplet(controlPoint_forWhichToGetThePreviousNeighbor.i_ofThisPoint_insideControlPointsList, allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + + Vector3 Get_posOffsetOfNewlyCreatedPointAtSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace() + { + return Get_customVector3_1_inGlobalSpaceUnits(); + } + + Vector3 Get_orientationOfNewlyCreatedPointAsForwardDirection_atSplineEnd_case_definedViaCustomVector_inUnitsOfGlobalSpace() + { + return Get_customVector3_2_inGlobalSpaceUnits(); + } + + public Vector3 Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized() + { + switch (drawSpace) + { + case DrawSpace.global: + return Vector3.forward; + case DrawSpace.localDefinedByThisGameobject: + return transform.forward; + default: + return Vector3.forward; + } + } + + public Vector3 Get_up_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized() + { + switch (drawSpace) + { + case DrawSpace.global: + return Vector3.up; + case DrawSpace.localDefinedByThisGameobject: + return transform.up; + default: + return Vector3.up; + } + } + + public Vector3 Get_originPos_ofActiveDrawSpace_inUnitsOfGlobalSpace() + { + switch (drawSpace) + { + case DrawSpace.global: + return Vector3.zero; + case DrawSpace.localDefinedByThisGameobject: + return transform.position; + default: + return Vector3.zero; + } + } + + public void ChangeDrawSpace(DrawSpace newDrawSpace) + { + if (newDrawSpace != drawSpace) + { + if (keepWorldPos_duringDrawSpaceChange) + { + //same for both draw space change directions (i.e. "to local space" and "to global space"): + ConvertSplineShape_onDrawSpaceChange_butKeepWorldPos(newDrawSpace); + } + else + { + switch (newDrawSpace) + { + case DrawSpace.global: + ConvertSplineShape_fromOldLocalDrawSpace_to_newGlobalDrawSpace(); + break; + case DrawSpace.localDefinedByThisGameobject: + ConvertSplineShape_fromOldGlobalDrawSpace_to_newLocalDrawSpace(); + Save_lastTransformStateOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf(); + break; + default: + break; + } + } + ResetAll_rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation(); + SheduleSceneViewRepaint(); + } + } + + void ConvertSplineShape_onDrawSpaceChange_butKeepWorldPos(DrawSpace newDrawSpace) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].Save_currentPosConfigInUnitsOfGlobalSpace_as_posConfigAfterSpaceChangeInUnitsOfGlobalSpace(); + } + + drawSpace = newDrawSpace; + + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].ApplySaved_posConfigAfterSpaceChangeInUnitsOfGlobalSpace(); + } + } + + void ConvertSplineShape_fromOldLocalDrawSpace_to_newGlobalDrawSpace() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].Save_currentPosConfigInUnitsOfActiveDrawSpace_as_posConfigAfterSpaceChangeInUnitsOfGlobalSpace(); + } + + drawSpace = DrawSpace.global; + + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].ApplySaved_posConfigAfterSpaceChangeInUnitsOfGlobalSpace(); + } + } + + void ConvertSplineShape_fromOldGlobalDrawSpace_to_newLocalDrawSpace() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].Save_currentPosConfigInUnitsOfGlobalSpace_as_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace(); + } + + drawSpace = DrawSpace.localDefinedByThisGameobject; + + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].ApplySaved_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace(); + } + } + + void Save_lastTransformStateOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf() + { + lastGlobalPositionOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf = transform.position; + lastGlobalRotationOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf = transform.rotation; + lastLossyScaleOfTheSplineComponentHostingGameobject_thatTheLocalDrawSpaceSplineKnowsOf = transform.lossyScale; + } + + public void ChangeCloseGapState(bool newStateOf_gapIsClosed) + { + RegisterStateForUndo("Spline Ring State", false, false); + + gapFromEndToStart_isClosed = newStateOf_gapIsClosed; + int i_lastControlPoint = listOfControlPointTriplets.Count - 1; + + if (newStateOf_gapIsClosed == true) + { + //change from "unclosed" to "closed": + listOfControlPointTriplets[0].anchorPoint.SetJunctureType(junctureType_ofNewlyCreatedPoints); + listOfControlPointTriplets[i_lastControlPoint].anchorPoint.SetJunctureType(junctureType_ofNewlyCreatedPoints); + } + else + { + //change from "closed" to "unclosed": + listOfControlPointTriplets[0].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + listOfControlPointTriplets[i_lastControlPoint].anchorPoint.SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + } + + listOfControlPointTriplets[0].backwardHelperPoint.ChangeUsedState(newStateOf_gapIsClosed, false); + listOfControlPointTriplets[i_lastControlPoint].forwardHelperPoint.ChangeUsedState(newStateOf_gapIsClosed, false); + + SheduleSceneViewRepaint(); + } + + public bool CheckIf_allFoldableHelperPoints_areUnfolded_inTheInspectorList() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].CheckIf_foldableHelperPoints_areUnfolded_inTheInspectorList() == false) + { + return false; + } + } + return true; + } + + public bool CheckIf_allFoldableHelperPoints_areCollapsed_inTheInspectorList() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].CheckIf_foldableHelperPoints_areCollapsed_inTheInspectorList() == false) + { + return false; + } + } + return true; + } + + public void UnfoldAllHelperPointInTheInspectorList() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].UnfoldBothHelperPointInTheInspectorList(); + } + } + + public void CollapseAllHelperPointInTheInspectorList() + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + listOfControlPointTriplets[i].CollapseBothHelperPointInTheInspectorList(); + } + } + + public bool CheckIf_gameobjectToAssign_isAlreadyAssignedAtAnotherSubPointOfTheSpline(GameObject gameobjectToAssign, out int i_ofTripletThatContainsTheSubPointThatAlreadyHasTheGameobjectAssigned, out InternalDXXL_BezierControlSubPoint.SubPointType subPointThatAlreadyHasTheGameobjectAssigned) + { + i_ofTripletThatContainsTheSubPointThatAlreadyHasTheGameobjectAssigned = -1; //not further used + subPointThatAlreadyHasTheGameobjectAssigned = InternalDXXL_BezierControlSubPoint.SubPointType.anchor; //not further used + if (gameobjectToAssign == null) + { + return false; + } + else + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + i_ofTripletThatContainsTheSubPointThatAlreadyHasTheGameobjectAssigned = i; + + if (listOfControlPointTriplets[i].backwardHelperPoint.boundGameobject == gameobjectToAssign) + { + subPointThatAlreadyHasTheGameobjectAssigned = InternalDXXL_BezierControlSubPoint.SubPointType.backwardHelper; + return true; + } + + if (listOfControlPointTriplets[i].anchorPoint.boundGameobject == gameobjectToAssign) + { + subPointThatAlreadyHasTheGameobjectAssigned = InternalDXXL_BezierControlSubPoint.SubPointType.anchor; + return true; + } + + if (listOfControlPointTriplets[i].forwardHelperPoint.boundGameobject == gameobjectToAssign) + { + subPointThatAlreadyHasTheGameobjectAssigned = InternalDXXL_BezierControlSubPoint.SubPointType.forwardHelper; + return true; + } + } + } + return false; + } + + public void RegisterStateForUndo(string nameOfUndoEntry, bool includeTransformsOfAllBoundGameobjects, bool includeConnectionComponentsOfAllBoundGameobjects) + { +#if UNITY_EDITOR + UnityEditor.Undo.RegisterCompleteObjectUndo(this, nameOfUndoEntry); + + if (includeTransformsOfAllBoundGameobjects) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].backwardHelperPoint.boundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].backwardHelperPoint.boundGameobject.transform, nameOfUndoEntry); + } + + if (listOfControlPointTriplets[i].anchorPoint.boundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].anchorPoint.boundGameobject.transform, nameOfUndoEntry); + } + + if (listOfControlPointTriplets[i].forwardHelperPoint.boundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].forwardHelperPoint.boundGameobject.transform, nameOfUndoEntry); + } + } + } + + if (includeConnectionComponentsOfAllBoundGameobjects) + { + for (int i = 0; i < listOfControlPointTriplets.Count; i++) + { + if (listOfControlPointTriplets[i].backwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].backwardHelperPoint.connectionComponent_onBoundGameobject, nameOfUndoEntry); + } + + if (listOfControlPointTriplets[i].anchorPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].anchorPoint.connectionComponent_onBoundGameobject, nameOfUndoEntry); + } + + if (listOfControlPointTriplets[i].forwardHelperPoint.connectionComponent_onBoundGameobject != null) + { + UnityEditor.Undo.RegisterCompleteObjectUndo(listOfControlPointTriplets[i].forwardHelperPoint.connectionComponent_onBoundGameobject, nameOfUndoEntry); + } + } + } +#endif + } + + public bool sheduledSceneViewRepaint_hasBeenExecuted = true; + public void SheduleSceneViewRepaint() + { +#if UNITY_EDITOR + sheduledSceneViewRepaint_hasBeenExecuted = false; + UnityEditor.EditorUtility.SetDirty(this); +#endif + } + + public void TryResheduleSceneViewRepaint() + { + //-> This function is necessary, because "EditorUtility.SetDirty(this)" does not reliably lead to scene view repaints + //-> When in "OnInspectorGUI().*.DrawNonSerializedControlPointsList()" a "SheduleSceneViewRepaint()" is issued due to a changed inspector input value, it "mostly" works. + //-> "mostly" means: + //---> if the changed inspector field is e.g. a "Vector3" or "float" then it works + //---> if the changed inspector field is a "enumPopup" then it doesn't work + //-> This function repeats the "SetDirty" until the scene view repaint finally happens. + + if (sheduledSceneViewRepaint_hasBeenExecuted == false) + { + SheduleSceneViewRepaint(); + } + } + + public Vector3 TransformPos_fromUnitsOfActiveDrawSpace_toGlobalSpace(Vector3 posToTransform_inUnitsOfActiveDrawSpace) + { + if (drawSpace == DrawSpace.localDefinedByThisGameobject) + { + return transform.TransformPoint(posToTransform_inUnitsOfActiveDrawSpace); + } + else + { + return posToTransform_inUnitsOfActiveDrawSpace; + } + } + + public Vector3 TransformPos_fromGlobalSpace_toUnitsOfActiveDrawSpace(Vector3 posToTransform_inUnitsOfGlobalSpace) + { + if (drawSpace == DrawSpace.localDefinedByThisGameobject) + { + return transform.InverseTransformPoint(posToTransform_inUnitsOfGlobalSpace); + } + else + { + return posToTransform_inUnitsOfGlobalSpace; + } + } + + public Vector3 TransformVector_fromUnitsOfActiveDrawSpace_toGlobalSpace(Vector3 vectorToTransform_inUnitsOfActiveDrawSpace) + { + if (drawSpace == DrawSpace.localDefinedByThisGameobject) + { + return transform.TransformVector(vectorToTransform_inUnitsOfActiveDrawSpace); + } + else + { + return vectorToTransform_inUnitsOfActiveDrawSpace; + } + } + + public Vector3 TransformVector_fromGlobalSpace_toUnitsOfActiveDrawSpace(Vector3 vectorToTransform_inUnitsOfGlobalSpace) + { + if (drawSpace == DrawSpace.localDefinedByThisGameobject) + { + return transform.InverseTransformVector(vectorToTransform_inUnitsOfGlobalSpace); + } + else + { + return vectorToTransform_inUnitsOfGlobalSpace; + } + } + + public Vector3 TransformDirection_fromUnitsOfActiveDrawSpace_toGlobalSpace(Vector3 directionToTransform_inUnitsOfActiveDrawSpace) + { + if (drawSpace == DrawSpace.localDefinedByThisGameobject) + { + return transform.TransformDirection(directionToTransform_inUnitsOfActiveDrawSpace); + } + else + { + return directionToTransform_inUnitsOfActiveDrawSpace; + } + } + + public Vector3 TransformDirection_fromGlobalSpace_toUnitsOfActiveDrawSpace(Vector3 directionToTransform_inUnitsOfGlobalSpace) + { + if (drawSpace == DrawSpace.localDefinedByThisGameobject) + { + return transform.InverseTransformDirection(directionToTransform_inUnitsOfGlobalSpace); + } + else + { + return directionToTransform_inUnitsOfGlobalSpace; + } + } + + public Quaternion TransformRotation_fromUnitsOfActiveDrawSpace_toGlobalSpace(Quaternion rotToTransform_inUnitsOfActiveDrawSpace) + { + if (drawSpace == DrawSpace.localDefinedByThisGameobject) + { + return (transform.rotation * rotToTransform_inUnitsOfActiveDrawSpace); + } + else + { + return rotToTransform_inUnitsOfActiveDrawSpace; + } + } + + public Quaternion TransformRotation_fromGlobalSpace_toUnitsOfActiveDrawSpace(Quaternion rotToTransform_inUnitsOfGlobalSpace) + { + if (drawSpace == DrawSpace.localDefinedByThisGameobject) + { + return (Quaternion.Inverse(transform.rotation) * rotToTransform_inUnitsOfGlobalSpace); + } + else + { + return rotToTransform_inUnitsOfGlobalSpace; + } + } + + public float TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(float lengthToTransform_inUnitsOfActiveDrawSpace) + { + //This function only works correctly if all transforms of the parenting hierarchy have a homogeneous scale + if (drawSpace == DrawSpace.localDefinedByThisGameobject) + { + return (lengthToTransform_inUnitsOfActiveDrawSpace * transform.lossyScale.x); + } + else + { + return lengthToTransform_inUnitsOfActiveDrawSpace; + } + } + + public float TransformLength_fromGlobalSpace_toUnitsOfActiveDrawSpace(float lengthToTransform_inUnitsOfGlobalSpace) + { + //This function only works correctly if all transforms of the parenting hierarchy have a homogeneous scale + if ((drawSpace == DrawSpace.localDefinedByThisGameobject) && (UtilitiesDXXL_Math.ApproximatelyZero(transform.lossyScale.x) == false)) + { + return (lengthToTransform_inUnitsOfGlobalSpace / transform.lossyScale.x); + } + else + { + return lengthToTransform_inUnitsOfGlobalSpace; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/BezierSplineDrawer.cs.meta b/Runtime/DrawDebugLibrary/components/BezierSplineDrawer.cs.meta new file mode 100644 index 0000000..25a1ee4 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/BezierSplineDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 03dfcb5e8bbf797408cede6295c69a16 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/BoundsVisualizer.cs b/Runtime/DrawDebugLibrary/components/BoundsVisualizer.cs new file mode 100644 index 0000000..48f2de4 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/BoundsVisualizer.cs @@ -0,0 +1,98 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Bounds Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class BoundsVisualizer : VisualizerParent + { + public enum AttachedTextsizeReferenceContext { extentOfBounds, globalSpace, sceneViewWindowSize, gameViewWindowSize }; + [SerializeField] AttachedTextsizeReferenceContext attachedTextsizeReferenceContext = AttachedTextsizeReferenceContext.sceneViewWindowSize; + [SerializeField] float textSize_value = 0.1f; + [SerializeField] [Range(0.001f, 0.2f)] float textSize_value_relToScreen = 0.01f; + + [SerializeField] bool global = true; + [SerializeField] bool local = true; + + [SerializeField] bool includeChildren = true; + [SerializeField] [Range(0.0f, 0.5f)] float lineWidth = 0.01f; + [SerializeField] Color color = new Color(1.0f, 0.7954724f, 0.3254902f, 1.0f); + + public override void InitializeValues_onceInComponentLifetime() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = this.gameObject.name + " / children"; + text_inclGlobalMarkupTags = this.gameObject.name + " / children"; + } + } + + public override void DrawVisualizedObject() + { + Set_globalTextSizeSpecs_reversible(); + if (global) + { + if (local) + { + DrawEngineBasics.Bounds(this.gameObject, color, true, includeChildren, lineWidth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + DrawEngineBasics.Bounds(this.gameObject, color, false, includeChildren, lineWidth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + } + else + { + if (local) + { + DrawEngineBasics.LocalBounds(this.gameObject, color, includeChildren, lineWidth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + } + Reverse_globalTextSizeSpecs(); + } + + float forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before; + float forcedConstantWorldspaceTextSize_forTextAtShapes_before; + DrawBasics.CameraForAutomaticOrientation cameraForAutomaticOrientation_before; + void Set_globalTextSizeSpecs_reversible() + { + forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before = DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes; + forcedConstantWorldspaceTextSize_forTextAtShapes_before = DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes; + cameraForAutomaticOrientation_before = DrawBasics.cameraForAutomaticOrientation; + + switch (attachedTextsizeReferenceContext) + { + case AttachedTextsizeReferenceContext.extentOfBounds: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = 0.0f; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + break; + case AttachedTextsizeReferenceContext.globalSpace: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = 0.0f; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = textSize_value; + break; + case AttachedTextsizeReferenceContext.sceneViewWindowSize: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = textSize_value_relToScreen; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + break; + case AttachedTextsizeReferenceContext.gameViewWindowSize: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = textSize_value_relToScreen; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + break; + default: + break; + } + } + + void Reverse_globalTextSizeSpecs() + { + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = forcedConstantWorldspaceTextSize_forTextAtShapes_before; + DrawBasics.cameraForAutomaticOrientation = cameraForAutomaticOrientation_before; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/BoundsVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/BoundsVisualizer.cs.meta new file mode 100644 index 0000000..e060d68 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/BoundsVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff0a9bb3a07cbc54f808922890477108 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/CameraVisualizer.cs b/Runtime/DrawDebugLibrary/components/CameraVisualizer.cs new file mode 100644 index 0000000..f260020 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/CameraVisualizer.cs @@ -0,0 +1,136 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Camera Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class CameraVisualizer : VisualizerScreenspaceParent + { + static Color initialCameraColor = new Color(0.96f, 0.9f, 0.24f, 1.0f); + + //symmetric fields for both: + [SerializeField] bool drawCamera = true; + [SerializeField] bool drawFrustum = true; + [SerializeField] Color color_ofCamera_enabledCam = initialCameraColor; + [SerializeField] Color color_ofCamera_disabledCam = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(initialCameraColor, 0.2f); + [SerializeField] Color color_ofFrustum_enabledCam = DrawBasics.defaultColor; + [SerializeField] Color color_ofFrustum_disabledCam = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawBasics.defaultColor, 0.1f); + [SerializeField] float linesWidth_camera = 0.0f; + [SerializeField] float linesWidth_frustum = 0.0f; + + //only for frustum: + [SerializeField] [Range(0.0f, 1.0f)] float alphaFactor_forBoundarySurfaceLines = 0.18f; + [SerializeField] int linesPerBoundarySurface = 60; + [SerializeField] bool forceTextOnNearPlaneUnmirroredTowardsCam = true; + [SerializeField] float distanceOfHighlightedPlane = 0.0f; + [SerializeField] float distanceOfHighlightedPlane_offsetFromPosition = 0.0f; + [SerializeField] bool drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane = true; + [SerializeField] bool doOverwriteColorForFrustumsHighlightedPlane = false; + [SerializeField] Color overwriteColorForFrustumsHighlightedPlane; //-> not using "DrawPhysics.overwriteColorForCastsHitNormals", since this would be the default color that doesn't represent what the user sees as normal color in the Scene + + public enum HighlightedPlaneDefintionType { disabled, definedByDistanceFromCamera, definedByAPosition }; + [SerializeField] HighlightedPlaneDefintionType highlightedPlaneDefintionType = HighlightedPlaneDefintionType.disabled; + + public enum HighlightedPlaneViaPosDefintionType { fixedPosition, gameobject }; + [SerializeField] HighlightedPlaneViaPosDefintionType highlightedPlaneViaPosDefintionType = HighlightedPlaneViaPosDefintionType.fixedPosition; + + [SerializeField] Vector3 vector3_thatSpecifiesThePosOfTheAdditionalFrustumPlane; + [SerializeField] GameObject gameobject_thatSpecifiesThePosOfTheAdditionalFrustumPlane; + + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + overwriteColorForFrustumsHighlightedPlane = UtilitiesDXXL_EngineBasics.Get_defaultColor_ofFrustumsHighlightedPlane(color_ofFrustum_enabledCam); + } + + public override void InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy() + { + TryFetchCamOnThisGO_andDecideScreenspaceDefiningCamera(); + } + + public override void DrawVisualizedObject() + { + Camera usedCamera = Get_usedCamera("Camera Visualizer Component"); + if (usedCamera != null) + { + if (drawCamera) + { + Color used_color = CheckIf_usedCameraIsActiveAndEnabled() ? color_ofCamera_enabledCam : color_ofCamera_disabledCam; + DrawEngineBasics.Camera(usedCamera, used_color, drawFrustum ? null : text_inclGlobalMarkupTags, linesWidth_camera, 0.0f, hiddenByNearerObjects); + } + + if (drawFrustum) { DrawFrustum(usedCamera); } + } + } + + void DrawFrustum(Camera usedCamera) + { + Color used_color = CheckIf_usedCameraIsActiveAndEnabled() ? color_ofFrustum_enabledCam : color_ofFrustum_disabledCam; + + UtilitiesDXXL_EngineBasics.Set_drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane_reversible(drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane); + if (doOverwriteColorForFrustumsHighlightedPlane) + { + UtilitiesDXXL_EngineBasics.Set_overwriteColorForFrustumsHighlightedPlane_reversible(overwriteColorForFrustumsHighlightedPlane); + } + + switch (highlightedPlaneDefintionType) + { + case HighlightedPlaneDefintionType.disabled: + UtilitiesDXXL_EngineBasics.Set_distanceOfFrustumsHighlightedPlane_reversible(0.0f); + DrawEngineBasics.CameraFrustum(usedCamera, used_color, alphaFactor_forBoundarySurfaceLines, linesWidth_frustum, linesPerBoundarySurface, text_inclGlobalMarkupTags, forceTextOnNearPlaneUnmirroredTowardsCam, default(Vector3), 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_EngineBasics.Reverse_distanceOfFrustumsHighlightedPlane(); + break; + case HighlightedPlaneDefintionType.definedByDistanceFromCamera: + UtilitiesDXXL_EngineBasics.Set_distanceOfFrustumsHighlightedPlane_reversible(distanceOfHighlightedPlane); + DrawEngineBasics.CameraFrustum(usedCamera, used_color, alphaFactor_forBoundarySurfaceLines, linesWidth_frustum, linesPerBoundarySurface, text_inclGlobalMarkupTags, forceTextOnNearPlaneUnmirroredTowardsCam, default(Vector3), 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_EngineBasics.Reverse_distanceOfFrustumsHighlightedPlane(); + break; + case HighlightedPlaneDefintionType.definedByAPosition: + Vector3 positionOnHighlightedPlane; + bool skipDraw = false; + switch (highlightedPlaneViaPosDefintionType) + { + case HighlightedPlaneViaPosDefintionType.fixedPosition: + positionOnHighlightedPlane = vector3_thatSpecifiesThePosOfTheAdditionalFrustumPlane; + break; + case HighlightedPlaneViaPosDefintionType.gameobject: + if (gameobject_thatSpecifiesThePosOfTheAdditionalFrustumPlane != null) + { + positionOnHighlightedPlane = gameobject_thatSpecifiesThePosOfTheAdditionalFrustumPlane.transform.position; + } + else + { + positionOnHighlightedPlane = Vector3.zero; + skipDraw = true; + } + break; + default: + positionOnHighlightedPlane = Vector3.zero; + break; + } + + positionOnHighlightedPlane = positionOnHighlightedPlane + usedCamera.transform.forward * distanceOfHighlightedPlane_offsetFromPosition; + if (UtilitiesDXXL_Math.IsDefaultVector(positionOnHighlightedPlane)) { positionOnHighlightedPlane = new Vector3(0.0f, 0.0f, 0.0001f); } //-> "DrawEngineBasics.CameraFrustum" would skip drawing the additional plane if the position remains at the default value of (0/0/0) + if (skipDraw) { positionOnHighlightedPlane = (-usedCamera.transform.forward) * 100000.0f; } + + UtilitiesDXXL_EngineBasics.Set_distanceOfFrustumsHighlightedPlane_reversible(0.0f); + DrawEngineBasics.CameraFrustum(usedCamera, used_color, alphaFactor_forBoundarySurfaceLines, linesWidth_frustum, linesPerBoundarySurface, text_inclGlobalMarkupTags, forceTextOnNearPlaneUnmirroredTowardsCam, positionOnHighlightedPlane, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_EngineBasics.Reverse_distanceOfFrustumsHighlightedPlane(); + break; + default: + break; + } + + UtilitiesDXXL_EngineBasics.Reverse_drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane(); + if (doOverwriteColorForFrustumsHighlightedPlane) + { + UtilitiesDXXL_EngineBasics.Reverse_overwriteColorForFrustumsHighlightedPlane(); + } + + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/CameraVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/CameraVisualizer.cs.meta new file mode 100644 index 0000000..438a395 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/CameraVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2452a648d93463a498a8201c827acc3b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/CoordinateAxesGizmoVisualizer.cs b/Runtime/DrawDebugLibrary/components/CoordinateAxesGizmoVisualizer.cs new file mode 100644 index 0000000..79581a3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/CoordinateAxesGizmoVisualizer.cs @@ -0,0 +1,58 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Coordinate Axes Gizmo Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class CoordinateAxesGizmoVisualizer : VisualizerParent + { + public enum VisualizedSpace { global, localDefinedByParent, localDefinedByThis }; + [SerializeField] VisualizedSpace visualizedSpace = VisualizedSpace.global; + [SerializeField] bool drawXYZchars = true; + [SerializeField] bool skipConeDrawing = false; + [SerializeField] bool forceAllAxesLength = false; + [SerializeField] float forceAllAxesLength_lengthValue = 1.0f; + [SerializeField] [Range(0.0f, 1.0f)] float lineWidth = 0.025f; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + } + + public override void DrawVisualizedObject() + { + float used_forceAxesLength_forLocal = forceAllAxesLength ? forceAllAxesLength_lengthValue : 0.0f; + bool aParentHasANonUniformScale; + switch (visualizedSpace) + { + case VisualizedSpace.global: + DrawGizmoForGlobalSpace(); + break; + case VisualizedSpace.localDefinedByParent: + if (transform.parent == null) + { + DrawGizmoForGlobalSpace(); + } + else + { + aParentHasANonUniformScale = UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(transform.parent.parent); + UtilitiesDXXL_EngineBasics.CoordinateAxesGizmoLocal(GetDrawPos3D_global(), transform.parent.rotation, transform.parent.lossyScale, used_forceAxesLength_forLocal, lineWidth, text_inclGlobalMarkupTags, drawXYZchars, skipConeDrawing, 0.0f, hiddenByNearerObjects, aParentHasANonUniformScale); + } + break; + case VisualizedSpace.localDefinedByThis: + aParentHasANonUniformScale = UtilitiesDXXL_EngineBasics.CheckIf_transformOrAParentHasNonUniformScale(transform.parent); + UtilitiesDXXL_EngineBasics.CoordinateAxesGizmoLocal(GetDrawPos3D_global(), transform.rotation, transform.lossyScale, used_forceAxesLength_forLocal, lineWidth, text_inclGlobalMarkupTags, drawXYZchars, skipConeDrawing, 0.0f, hiddenByNearerObjects, aParentHasANonUniformScale); + break; + default: + break; + } + } + + void DrawGizmoForGlobalSpace() + { + UtilitiesDXXL_EngineBasics.CoordinateAxesGizmoLocal(GetDrawPos3D_global(), Quaternion.identity, default(Vector3), forceAllAxesLength_lengthValue, lineWidth, text_inclGlobalMarkupTags, drawXYZchars, skipConeDrawing, 0.0f, hiddenByNearerObjects, false); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/components/CoordinateAxesGizmoVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/CoordinateAxesGizmoVisualizer.cs.meta new file mode 100644 index 0000000..f646feb --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/CoordinateAxesGizmoVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75fc5ac212da31c409066e70d002ca76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/CrossProductVisualizer.cs b/Runtime/DrawDebugLibrary/components/CrossProductVisualizer.cs new file mode 100644 index 0000000..f276d27 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/CrossProductVisualizer.cs @@ -0,0 +1,58 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Cross Product Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class CrossProductVisualizer : VisualizerParent + { + [SerializeField] [Range(0.0f, 0.1f)] float linesWidth = 0.0025f; + [SerializeField] public bool colorSection_isOutfolded = false; + [SerializeField] Color colorOfVector1_forCrossProduct = DrawEngineBasics.colorOfVector1_forCrossProduct; + [SerializeField] Color colorOfVector2_forCrossProduct = DrawEngineBasics.colorOfVector2_forCrossProduct; + [SerializeField] Color colorOfAngle_forCrossProduct = DrawEngineBasics.colorOfAngle_forCrossProduct; + [SerializeField] Color colorOfResultVector_forCrossProduct = DrawEngineBasics.colorOfResultVector_forCrossProduct; + [SerializeField] Color colorOfResultText_forCrossProduct = DrawEngineBasics.colorOfResultText_forCrossProduct; + [SerializeField] Color colorOfResultPlane_forCrossProduct = DrawEngineBasics.colorOfResultPlane_forCrossProduct; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToGameobjectName(); + + customVector3Configs[0].picker_isOutfolded = true; + customVector3Configs[0].source = CustomVector3Source.transformsForward; + customVector3Configs[0].clipboardForManualInput = Vector3.forward; + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[1].picker_isOutfolded = true; + customVector3Configs[1].source = CustomVector3Source.manualInput; + customVector3Configs[1].clipboardForManualInput = Vector3.right; + customVector3Configs[1].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void DrawVisualizedObject() + { + Vector3 vector1_lhs_leftThumb = Get_customVector3_1_inGlobalSpaceUnits(); + Vector3 vector2_rhs_leftIndexFinger = Get_customVector3_2_inGlobalSpaceUnits(); + + UtilitiesDXXL_EngineBasics.Set_colorOfVector1_forCrossProduct_reversible(colorOfVector1_forCrossProduct); + UtilitiesDXXL_EngineBasics.Set_colorOfVector2_forCrossProduct_reversible(colorOfVector2_forCrossProduct); + UtilitiesDXXL_EngineBasics.Set_colorOfAngle_forCrossProduct_reversible(colorOfAngle_forCrossProduct); + UtilitiesDXXL_EngineBasics.Set_colorOfResultVector_forCrossProduct_reversible(colorOfResultVector_forCrossProduct); + UtilitiesDXXL_EngineBasics.Set_colorOfResultText_forCrossProduct_reversible(colorOfResultText_forCrossProduct); + UtilitiesDXXL_EngineBasics.Set_colorOfResultPlane_forCrossProduct_reversible(colorOfResultPlane_forCrossProduct); + + DrawEngineBasics.CrossProduct(vector1_lhs_leftThumb, vector2_rhs_leftIndexFinger, GetDrawPos3D_global(), linesWidth, 0.0f, hiddenByNearerObjects); + + UtilitiesDXXL_EngineBasics.Reverse_colorOfVector1_forCrossProduct(); + UtilitiesDXXL_EngineBasics.Reverse_colorOfVector2_forCrossProduct(); + UtilitiesDXXL_EngineBasics.Reverse_colorOfAngle_forCrossProduct(); + UtilitiesDXXL_EngineBasics.Reverse_colorOfResultVector_forCrossProduct(); + UtilitiesDXXL_EngineBasics.Reverse_colorOfResultText_forCrossProduct(); + UtilitiesDXXL_EngineBasics.Reverse_colorOfResultPlane_forCrossProduct(); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/CrossProductVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/CrossProductVisualizer.cs.meta new file mode 100644 index 0000000..4eda2b9 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/CrossProductVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 750a8359fb5209d40a08444c4500110f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/DotProductVisualizer.cs b/Runtime/DrawDebugLibrary/components/DotProductVisualizer.cs new file mode 100644 index 0000000..6a1bba9 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/DotProductVisualizer.cs @@ -0,0 +1,52 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Dot Product Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class DotProductVisualizer : VisualizerParent + { + [SerializeField] [Range(0.0f, 0.1f)] float linesWidth = 0.0025f; + [SerializeField] public bool colorSection_isOutfolded = false; + [SerializeField] Color colorOfVector1_forDotProduct = DrawEngineBasics.colorOfVector1_forDotProduct; + [SerializeField] Color colorOfVector2_forDotProduct = DrawEngineBasics.colorOfVector2_forDotProduct; + [SerializeField] Color colorOfAngle_forDotProduct = DrawEngineBasics.colorOfAngle_forDotProduct; + [SerializeField] Color colorOfResult_forDotProduct = DrawEngineBasics.colorOfResult_forDotProduct; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToGameobjectName(); + + customVector3Configs[0].picker_isOutfolded = true; + customVector3Configs[0].source = CustomVector3Source.transformsForward; + customVector3Configs[0].clipboardForManualInput = Vector3.forward; + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[1].picker_isOutfolded = true; + customVector3Configs[1].source = CustomVector3Source.manualInput; + customVector3Configs[1].clipboardForManualInput = Vector3.right; + customVector3Configs[1].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void DrawVisualizedObject() + { + Vector3 vector1_lhs = Get_customVector3_1_inGlobalSpaceUnits(); + Vector3 vector2_rhs = Get_customVector3_2_inGlobalSpaceUnits(); + + UtilitiesDXXL_EngineBasics.Set_colorOfVector1_forDotProduct_reversible(colorOfVector1_forDotProduct); + UtilitiesDXXL_EngineBasics.Set_colorOfVector2_forDotProduct_reversible(colorOfVector2_forDotProduct); + UtilitiesDXXL_EngineBasics.Set_colorOfAngle_forDotProduct_reversible(colorOfAngle_forDotProduct); + UtilitiesDXXL_EngineBasics.Set_colorOfResult_forDotProduct_reversible(colorOfResult_forDotProduct); + + DrawEngineBasics.DotProduct(vector1_lhs, vector2_rhs, GetDrawPos3D_global(), linesWidth, 0.0f, hiddenByNearerObjects); + + UtilitiesDXXL_EngineBasics.Reverse_colorOfVector1_forDotProduct(); + UtilitiesDXXL_EngineBasics.Reverse_colorOfVector2_forDotProduct(); + UtilitiesDXXL_EngineBasics.Reverse_colorOfAngle_forDotProduct(); + UtilitiesDXXL_EngineBasics.Reverse_colorOfResult_forDotProduct(); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/DotProductVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/DotProductVisualizer.cs.meta new file mode 100644 index 0000000..22adefc --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/DotProductVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 18424ed73833d4d41a210ac403fbd138 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/GridVisualizer.cs b/Runtime/DrawDebugLibrary/components/GridVisualizer.cs new file mode 100644 index 0000000..a64ad38 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/GridVisualizer.cs @@ -0,0 +1,320 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Grid Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class GridVisualizer : VisualizerParent + { + public enum SpaceType { global, localDefinedByParent, localDefinedByThisGameobject }; + [SerializeField] SpaceType spaceType = SpaceType.global; + + public enum XGridType { linesAlongY, linesAlongZ, planes, invisible }; + public enum YGridType { linesAlongX, linesAlongZ, planes, invisible }; + public enum ZGridType { linesAlongX, linesAlongY, planes, invisible }; + + [SerializeField] XGridType xGridType = XGridType.linesAlongY; + [SerializeField] YGridType yGridType = YGridType.linesAlongX; + [SerializeField] ZGridType zGridType = ZGridType.linesAlongX; + + [SerializeField] public bool magnitudeOrderSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] bool draw1000grid = false; + [SerializeField] bool draw100grid = false; + [SerializeField] bool draw10grid = false; + [SerializeField] bool draw1grid = true; + [SerializeField] bool draw0p1grid = false; + [SerializeField] bool draw0p01grid = false; + [SerializeField] bool draw0p001grid = false; + + public enum LineWidthMode { growAlongVisualizedAxis, growPerpendicularToVisualizedAxis }; + [SerializeField] LineWidthMode lineWidthMode = LineWidthMode.growAlongVisualizedAxis; + public const float max_linesWidth_alongVisualizedAxis = 0.5f; + [SerializeField] [Range(0.0f, max_linesWidth_alongVisualizedAxis)] float linesWidth_alongVisualizedAxis = 0.0f; + [SerializeField] float linesWidth_perpendicularToVisualizedAxis = 0.0f; + + [SerializeField] float coveredGridUnits_rel = 10.0f; + [SerializeField] [Range(0.1f, 10.0f)] float drawDensity = 1.0f; + [SerializeField] float lengthOfEachGridLine_rel = 10.0f; + [SerializeField] float extentOfEachGridPlane_rel = 10.0f; + [SerializeField] Color colorForX = UtilitiesDXXL_Colors.red_xAxisAlpha1; + [SerializeField] Color colorForY = UtilitiesDXXL_Colors.green_yAxisAlpha1; + [SerializeField] Color colorForZ = UtilitiesDXXL_Colors.blue_zAxisAlpha1; + [SerializeField] bool show_positionAroundWhichToDraw_forGrids = true; + [SerializeField] bool show_distanceDisplay_forGrids = !UtilitiesDXXL_Grid.default_hide_distanceDisplay_forGrids; + [SerializeField] float offsetForDistanceDisplays_inGrids = UtilitiesDXXL_Grid.default_offsetForDistanceDisplays_inGrids; + [SerializeField] float offsetForCoordinateTextDisplays_inGrids = UtilitiesDXXL_Grid.default_offsetForCoordinateTextDisplays_inGrids; + [SerializeField] float coveredGridUnits_rel_forGridPlanes = UtilitiesDXXL_Grid.default_coveredGridUnits_rel_forGridPlanes; + [SerializeField] [Range(UtilitiesDXXL_Grid.min_sizeScalingForCoordinateTexts_inGrids, 1.0f)] float sizeScalingForCoordinateTexts_inGrids = UtilitiesDXXL_Grid.default_sizeScalingForCoordinateTexts_inGrids; + + bool skip_drawAroundPosVisualization_forXDim; + bool skip_drawAroundPosVisualization_forYDim; + bool skip_drawAroundPosVisualization_forZDim; + + public enum RepeatingCoordsTextVariant { repeatAfterDistance, displayOnlyOnce, noDisplay }; + [SerializeField] RepeatingCoordsTextVariant repeatingCoordsTextVariant = RepeatingCoordsTextVariant.repeatAfterDistance; + [SerializeField] float distanceBetweenRepeatingCoordsTexts_relToGridDistance = 20.0f; + [SerializeField] bool skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes = DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes; + [SerializeField] bool skipLocalPrefix_inCoordinateTextsOnGridAxes = DrawEngineBasics. skipLocalPrefix_inCoordinateTextsOnGridAxes; + + public override void DrawVisualizedObject() + { + float used_distanceBetweenRepeatingCoordsTexts_relToGridDistance = Get_used_distanceBetweenRepeatingCoordsTexts_relToGridDistance(); + float used_linesWidth = (lineWidthMode == LineWidthMode.growAlongVisualizedAxis) ? linesWidth_alongVisualizedAxis : (-linesWidth_perpendicularToVisualizedAxis); + + UtilitiesDXXL_Grid.forceSkip_drawAroundPosVisualizationLocal = false; + UtilitiesDXXL_Grid.Set_hide_positionAroundWhichToDraw_forGrids_reversible(!show_positionAroundWhichToDraw_forGrids); + UtilitiesDXXL_Grid.Set_hide_distanceDisplay_forGrids_reversible(!show_distanceDisplay_forGrids); + UtilitiesDXXL_Grid.Set_offsetForDistanceDisplays_inGrids_reversible(offsetForDistanceDisplays_inGrids); + UtilitiesDXXL_Grid.Set_offsetForCoordinateTextDisplays_inGrids_reversible(offsetForCoordinateTextDisplays_inGrids); + UtilitiesDXXL_Grid.Set_coveredGridUnits_rel_forGridPlanes_reversible(coveredGridUnits_rel_forGridPlanes); + UtilitiesDXXL_Grid.Set_sizeScalingForCoordinateTexts_inGrids_reversible(0.75f * sizeScalingForCoordinateTexts_inGrids); + UtilitiesDXXL_Grid.Set_skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes_reversible(skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes); + UtilitiesDXXL_Grid.Set_skipLocalPrefix_inCoordinateTextsOnGridAxes_reversible(skipLocalPrefix_inCoordinateTextsOnGridAxes); + + switch (spaceType) + { + case SpaceType.global: + switch (xGridType) + { + case XGridType.linesAlongY: + DrawEngineBasics.XGridLines(GetDrawPos3D_global(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.XGridLinesOrientation.alongY, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForX, 0.0f, hiddenByNearerObjects); + break; + case XGridType.linesAlongZ: + DrawEngineBasics.XGridLines(GetDrawPos3D_global(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.XGridLinesOrientation.alongZ, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForX, 0.0f, hiddenByNearerObjects); + break; + case XGridType.planes: + DrawEngineBasics.XGridPlanes(GetDrawPos3D_global(), extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForX, 0.0f, hiddenByNearerObjects); + break; + case XGridType.invisible: + break; + default: + break; + } + + switch (yGridType) + { + case YGridType.linesAlongX: + DrawEngineBasics.YGridLines(GetDrawPos3D_global(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.YGridLinesOrientation.alongX, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForY, 0.0f, hiddenByNearerObjects); + break; + case YGridType.linesAlongZ: + DrawEngineBasics.YGridLines(GetDrawPos3D_global(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.YGridLinesOrientation.alongZ, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForY, 0.0f, hiddenByNearerObjects); + break; + case YGridType.planes: + DrawEngineBasics.YGridPlanes(GetDrawPos3D_global(), extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForY, 0.0f, hiddenByNearerObjects); + break; + case YGridType.invisible: + break; + default: + break; + } + + switch (zGridType) + { + case ZGridType.linesAlongX: + DrawEngineBasics.ZGridLines(GetDrawPos3D_global(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.ZGridLinesOrientation.alongX, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForZ, 0.0f, hiddenByNearerObjects); + break; + case ZGridType.linesAlongY: + DrawEngineBasics.ZGridLines(GetDrawPos3D_global(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.ZGridLinesOrientation.alongY, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForZ, 0.0f, hiddenByNearerObjects); + break; + case ZGridType.planes: + DrawEngineBasics.ZGridPlanes(GetDrawPos3D_global(), extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForZ, 0.0f, hiddenByNearerObjects); + break; + case ZGridType.invisible: + break; + default: + break; + } + break; + case SpaceType.localDefinedByParent: + SetConfigFor_forceSkip_drawAroundPosVisualzationLocal(); + + UtilitiesDXXL_Grid.forceSkip_drawAroundPosVisualizationLocal = skip_drawAroundPosVisualization_forXDim; + switch (xGridType) + { + case XGridType.linesAlongY: + DrawEngineBasics.XGridLinesLocal(transform.parent, GetDrawPos3D_inLocalSpaceAsDefinedByParent(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.XGridLinesOrientation.alongY, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForX, 0.0f, hiddenByNearerObjects); + break; + case XGridType.linesAlongZ: + DrawEngineBasics.XGridLinesLocal(transform.parent, GetDrawPos3D_inLocalSpaceAsDefinedByParent(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.XGridLinesOrientation.alongZ, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForX, 0.0f, hiddenByNearerObjects); + break; + case XGridType.planes: + DrawEngineBasics.XGridPlanesLocal(transform.parent, GetDrawPos3D_inLocalSpaceAsDefinedByParent(), extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForX, 0.0f, hiddenByNearerObjects); + break; + case XGridType.invisible: + break; + default: + break; + } + + UtilitiesDXXL_Grid.forceSkip_drawAroundPosVisualizationLocal = skip_drawAroundPosVisualization_forYDim; + switch (yGridType) + { + case YGridType.linesAlongX: + DrawEngineBasics.YGridLinesLocal(transform.parent, GetDrawPos3D_inLocalSpaceAsDefinedByParent(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.YGridLinesOrientation.alongX, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForY, 0.0f, hiddenByNearerObjects); + break; + case YGridType.linesAlongZ: + DrawEngineBasics.YGridLinesLocal(transform.parent, GetDrawPos3D_inLocalSpaceAsDefinedByParent(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.YGridLinesOrientation.alongZ, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForY, 0.0f, hiddenByNearerObjects); + break; + case YGridType.planes: + DrawEngineBasics.YGridPlanesLocal(transform.parent, GetDrawPos3D_inLocalSpaceAsDefinedByParent(), extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForY, 0.0f, hiddenByNearerObjects); + break; + case YGridType.invisible: + break; + default: + break; + } + + UtilitiesDXXL_Grid.forceSkip_drawAroundPosVisualizationLocal = skip_drawAroundPosVisualization_forZDim; + switch (zGridType) + { + case ZGridType.linesAlongX: + DrawEngineBasics.ZGridLinesLocal(transform.parent, GetDrawPos3D_inLocalSpaceAsDefinedByParent(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.ZGridLinesOrientation.alongX, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForZ, 0.0f, hiddenByNearerObjects); + break; + case ZGridType.linesAlongY: + DrawEngineBasics.ZGridLinesLocal(transform.parent, GetDrawPos3D_inLocalSpaceAsDefinedByParent(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.ZGridLinesOrientation.alongY, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForZ, 0.0f, hiddenByNearerObjects); + break; + case ZGridType.planes: + DrawEngineBasics.ZGridPlanesLocal(transform.parent, GetDrawPos3D_inLocalSpaceAsDefinedByParent(), extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForZ, 0.0f, hiddenByNearerObjects); + break; + case ZGridType.invisible: + break; + default: + break; + } + break; + case SpaceType.localDefinedByThisGameobject: + SetConfigFor_forceSkip_drawAroundPosVisualzationLocal(); + + UtilitiesDXXL_Grid.forceSkip_drawAroundPosVisualizationLocal = skip_drawAroundPosVisualization_forXDim; + switch (xGridType) + { + case XGridType.linesAlongY: + DrawEngineBasics.XGridLinesLocal(transform, GetDrawPos3D_inLocalSpaceAsDefinedByThisGameobject(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.XGridLinesOrientation.alongY, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForX, 0.0f, hiddenByNearerObjects); + break; + case XGridType.linesAlongZ: + DrawEngineBasics.XGridLinesLocal(transform, GetDrawPos3D_inLocalSpaceAsDefinedByThisGameobject(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.XGridLinesOrientation.alongZ, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForX, 0.0f, hiddenByNearerObjects); + break; + case XGridType.planes: + DrawEngineBasics.XGridPlanesLocal(transform, GetDrawPos3D_inLocalSpaceAsDefinedByThisGameobject(), extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForX, 0.0f, hiddenByNearerObjects); + break; + case XGridType.invisible: + break; + default: + break; + } + + UtilitiesDXXL_Grid.forceSkip_drawAroundPosVisualizationLocal = skip_drawAroundPosVisualization_forYDim; + switch (yGridType) + { + case YGridType.linesAlongX: + DrawEngineBasics.YGridLinesLocal(transform, GetDrawPos3D_inLocalSpaceAsDefinedByThisGameobject(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.YGridLinesOrientation.alongX, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForY, 0.0f, hiddenByNearerObjects); + break; + case YGridType.linesAlongZ: + DrawEngineBasics.YGridLinesLocal(transform, GetDrawPos3D_inLocalSpaceAsDefinedByThisGameobject(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.YGridLinesOrientation.alongZ, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForY, 0.0f, hiddenByNearerObjects); + break; + case YGridType.planes: + DrawEngineBasics.YGridPlanesLocal(transform, GetDrawPos3D_inLocalSpaceAsDefinedByThisGameobject(), extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForY, 0.0f, hiddenByNearerObjects); + break; + case YGridType.invisible: + break; + default: + break; + } + + UtilitiesDXXL_Grid.forceSkip_drawAroundPosVisualizationLocal = skip_drawAroundPosVisualization_forZDim; + switch (zGridType) + { + case ZGridType.linesAlongX: + DrawEngineBasics.ZGridLinesLocal(transform, GetDrawPos3D_inLocalSpaceAsDefinedByThisGameobject(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.ZGridLinesOrientation.alongX, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForZ, 0.0f, hiddenByNearerObjects); + break; + case ZGridType.linesAlongY: + DrawEngineBasics.ZGridLinesLocal(transform, GetDrawPos3D_inLocalSpaceAsDefinedByThisGameobject(), coveredGridUnits_rel, lengthOfEachGridLine_rel, used_linesWidth, DrawEngineBasics.ZGridLinesOrientation.alongY, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForZ, 0.0f, hiddenByNearerObjects); + break; + case ZGridType.planes: + DrawEngineBasics.ZGridPlanesLocal(transform, GetDrawPos3D_inLocalSpaceAsDefinedByThisGameobject(), extentOfEachGridPlane_rel, drawDensity, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid, used_distanceBetweenRepeatingCoordsTexts_relToGridDistance, colorForZ, 0.0f, hiddenByNearerObjects); + break; + case ZGridType.invisible: + break; + default: + break; + } + break; + default: + break; + } + + UtilitiesDXXL_Grid.Reverse_hide_positionAroundWhichToDraw_forGrids(); + UtilitiesDXXL_Grid.Reverse_hide_distanceDisplay_forGrids(); + UtilitiesDXXL_Grid.Reverse_offsetForDistanceDisplays_inGrids(); + UtilitiesDXXL_Grid.Reverse_offsetForCoordinateTextDisplays_inGrids(); + UtilitiesDXXL_Grid.Reverse_coveredGridUnits_rel_forGridPlanes(); + UtilitiesDXXL_Grid.Reverse_sizeScalingForCoordinateTexts_inGrids(); + UtilitiesDXXL_Grid.Reverse_skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes(); + UtilitiesDXXL_Grid.Reverse_skipLocalPrefix_inCoordinateTextsOnGridAxes(); + UtilitiesDXXL_Grid.forceSkip_drawAroundPosVisualizationLocal = false; + } + + float Get_used_distanceBetweenRepeatingCoordsTexts_relToGridDistance() + { + switch (repeatingCoordsTextVariant) + { + case RepeatingCoordsTextVariant.repeatAfterDistance: + return distanceBetweenRepeatingCoordsTexts_relToGridDistance; + case RepeatingCoordsTextVariant.displayOnlyOnce: + return 0.0f; + case RepeatingCoordsTextVariant.noDisplay: + return -1.0f; + default: + return 0.0f; + } + } + + void SetConfigFor_forceSkip_drawAroundPosVisualzationLocal() + { + UtilitiesDXXL_Math.Dimension theSingleDimensionThatGetsADrawAroundPosVisualization = UtilitiesDXXL_Math.Dimension.x; + + if (xGridType != XGridType.invisible) + { + theSingleDimensionThatGetsADrawAroundPosVisualization = UtilitiesDXXL_Math.Dimension.x; + } + else + { + if (yGridType != YGridType.invisible) + { + theSingleDimensionThatGetsADrawAroundPosVisualization = UtilitiesDXXL_Math.Dimension.y; + } + else + { + if (zGridType != ZGridType.invisible) + { + theSingleDimensionThatGetsADrawAroundPosVisualization = UtilitiesDXXL_Math.Dimension.z; + } + } + } + + switch (theSingleDimensionThatGetsADrawAroundPosVisualization) + { + case UtilitiesDXXL_Math.Dimension.x: + skip_drawAroundPosVisualization_forXDim = false; + skip_drawAroundPosVisualization_forYDim = true; + skip_drawAroundPosVisualization_forZDim = true; + break; + case UtilitiesDXXL_Math.Dimension.y: + skip_drawAroundPosVisualization_forXDim = true; + skip_drawAroundPosVisualization_forYDim = false; + skip_drawAroundPosVisualization_forZDim = true; + break; + case UtilitiesDXXL_Math.Dimension.z: + skip_drawAroundPosVisualization_forXDim = true; + skip_drawAroundPosVisualization_forYDim = true; + skip_drawAroundPosVisualization_forZDim = false; + break; + default: + break; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/GridVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/GridVisualizer.cs.meta new file mode 100644 index 0000000..36ebeda --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/GridVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8568878f76ef862459bf52e26f351d38 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/LineDrawer.cs b/Runtime/DrawDebugLibrary/components/LineDrawer.cs new file mode 100644 index 0000000..7a77cf9 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/LineDrawer.cs @@ -0,0 +1,434 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Line Drawer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class LineDrawer : VisualizerParent + { + public enum LineType { standardLine, vector, vectorWithExtention, blinkingLine, lineUnderTension, movingArrowsLine, lineWithAlternatingColors }; + [SerializeField] public LineType lineType = LineType.standardLine; + + public enum LineDefinitionMode { startPositionAndEndPosition, startPositionAndDirectionVectorToEndPosition, endPositionAndDirectionVectorToIt }; + [SerializeField] public LineDefinitionMode lineDefinitionMode = LineDefinitionMode.startPositionAndDirectionVectorToEndPosition; + + public enum PositionDefinitionOption { positionOfThisGameobjectPlusOffset, positionOfOtherGameobjectPlusOffset, chooseFree }; + [SerializeField] public PositionDefinitionOption positionDefinitionOption_ofStartPos = PositionDefinitionOption.positionOfThisGameobjectPlusOffset; + [SerializeField] public PositionDefinitionOption positionDefinitionOption_ofEndPos = PositionDefinitionOption.chooseFree; + [SerializeField] public bool lineDefinitionSection1_isOutfolded = false; + [SerializeField] public bool lineDefinitionSection2_isOutfolded = false; + + public enum CoordinateSpaceForLocalOffset { useLocalSpaceDefinedByTransformOnThisGameobject, useLocalSpaceDefinedByTransformOnOtherGameobject }; + [SerializeField] public CoordinateSpaceForLocalOffset coordinateSpaceForLocalOffsetOnOtherGameobject_forStartPos = CoordinateSpaceForLocalOffset.useLocalSpaceDefinedByTransformOnThisGameobject; + [SerializeField] public CoordinateSpaceForLocalOffset coordinateSpaceForLocalOffsetOnOtherGameobject_forEndPos = CoordinateSpaceForLocalOffset.useLocalSpaceDefinedByTransformOnThisGameobject; + + //Shared: + [SerializeField] public Color startColor = DrawBasics.defaultColor; + [SerializeField] public bool useDifferentEndColor = false; + [SerializeField] public Color endColor = UtilitiesDXXL_Colors.red_boolFalse; + [SerializeField] public float lineWidth = 0.0f; + [SerializeField] public DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid; + [SerializeField] public float stylePatternScaleFactor = 1.0f; + [SerializeField] public bool animationDuringEditMode = true; + [SerializeField] public float animationSpeed = 0.0f; + public LineAnimationProgress precedingLineAnimationProgress = new LineAnimationProgress(); + [SerializeField] public bool enlargeSmallTextToThisMinTextSize = true; + [SerializeField] public float enlargeSmallTextToThisMinTextSize_value = 0.005f; + [SerializeField] public bool skipPatternEnlargementForLongLines = false; + [SerializeField] public bool skipPatternEnlargementForShortLines = false; + public enum AmplitudeAndTextAlignment { verticalInGlobalSpace, perpendicularToSceneViewCamera, perpendicularToGameViewCamera, customAmplitudeDirection }; + [SerializeField] AmplitudeAndTextAlignment amplitudeAndTextAlignment = AmplitudeAndTextAlignment.verticalInGlobalSpace; + public enum EndPlatesConfig { disabled, bothSides, onlyAtStart, onlyAtEnd }; + [SerializeField] public EndPlatesConfig endPlatesConfig = EndPlatesConfig.disabled; + [SerializeField] [Range(0.0f, 0.5f)] public float alphaFadeOutLength_0to1 = 0.0f; + [SerializeField] bool flattenThickRoundLineIntoAmplitudePlane = false; + [SerializeField] public bool shiftTextPosOnLines_toNonIntersecting = false; + [SerializeField] [Range(0.05f, 10.0f)] public float relSizeOfTextOnLines = 0.45f; + + //Vectors: + public enum ConesConfig { bothSides, onlyAtStart, onlyAtEnd }; + [SerializeField] public ConesConfig conesConfig = ConesConfig.onlyAtEnd; + [SerializeField] public bool addNormalizedMarkingText = false; + [SerializeField] public bool writeComponentValuesAsText = false; + + //Vectors With Extention: + [SerializeField] public float extentionLength = 1000.0f; + [SerializeField] public bool forceFixedConeLength = false; + [SerializeField] public float forceFixedConeLength_value = 0.17f; + + //Blinking Line: + [SerializeField] public Color blinkColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawBasics.defaultColor, 0.2f); + [SerializeField] public float blinkDurationInSec = 0.5f; + + //Line under tension: + [SerializeField] public float relaxedLength = 1.0f; + [SerializeField] public float stretchFactor_forStretchedTensionColor = 2.0f; + [SerializeField] public float stretchFactor_forSqueezedTensionColor = 0.0f; + [SerializeField] public DrawBasics.LineStyle lineStyle_underTension = DrawBasics.LineStyle.spiral; + [SerializeField] public Color relaxedColor = UtilitiesDXXL_Colors.green_boolTrue; + [SerializeField] public Color color_forStretchedTension = UtilitiesDXXL_Colors.red_boolFalse; + [SerializeField] public Color color_forSqueezedTension = UtilitiesDXXL_Colors.red_boolFalse; + [SerializeField] [Range(0.0f, 1.0f)] public float alphaOfReferenceLengthDisplay = 0.15f; + + //Moving arrows line: + [SerializeField] public float lineWidth_ofMovingArrowsLine = 0.05f; + [SerializeField] bool flattenThickRoundLineIntoAmplitudePlane_ofMovingArrowsLine = true; + [SerializeField] public float animationSpeed_ofMovingArrowsLine = 0.5f; + [SerializeField] public float distanceBetweenArrows = 0.5f; + [SerializeField] public float lengthOfArrows = 0.15f; + [SerializeField] public bool backwardAnimationFlipsArrowDirection = true; + + //Line with alternating colors: + [SerializeField] public Color alternatingColor = DrawBasics.defaultColor2_ofAlternatingColorLines; + [SerializeField] public float lengthOfStripes = 0.04f; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + + customVector3Configs[0].picker_isOutfolded = true; + customVector3Configs[0].source = CustomVector3Source.transformsForward; + customVector3Configs[0].clipboardForManualInput = Vector3.forward; + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[1].source = CustomVector3Source.manualInput; + customVector3Configs[1].clipboardForManualInput = Vector3.up; + customVector3Configs[1].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[2].source = CustomVector3Source.manualInput; + customVector3Configs[2].clipboardForManualInput = Vector3.zero; + customVector3Configs[2].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[3].source = CustomVector3Source.manualInput; + customVector3Configs[3].clipboardForManualInput = Vector3.forward; + customVector3Configs[3].vectorInterpretation = VectorInterpretation.globalSpace; + + endPlates_size = 0.1f; //Despite this value: End plates display is initially disabled due to "endPlatesConfig" + } + + public override void DrawVisualizedObject() + { + float used_enlargeSmallTextToThisMinTextSize_value = enlargeSmallTextToThisMinTextSize ? enlargeSmallTextToThisMinTextSize_value : 0.0f; + float used_endPlates_size = Set_endPlatesConfig_reversible(); + Vector3 used_customAmplitudeAndTextDir = Set_amplitudeAndTextDirConfig_reversible(); + UtilitiesDXXL_DrawBasics.Set_shiftTextPosOnLines_toNonIntersecting_reversible(shiftTextPosOnLines_toNonIntersecting); + UtilitiesDXXL_DrawBasics.Set_relSizeOfTextOnLines_reversible(relSizeOfTextOnLines); + GetLineStartPosAndDirection(out Vector3 lineStartPosition, out Vector3 vector_fromLineStart_toLineEnd); + + switch (lineType) + { + case LineType.standardLine: + if (useDifferentEndColor) + { + precedingLineAnimationProgress = LineFrom_fadeableAnimSpeed.InternalDraw_withColorFade(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, endColor, lineWidth, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, used_customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, used_endPlates_size, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + precedingLineAnimationProgress = LineFrom_fadeableAnimSpeed.InternalDraw(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, lineWidth, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, used_customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, used_endPlates_size, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + break; + case LineType.vector: + switch (conesConfig) + { + case ConesConfig.bothSides: + DrawBasics.VectorFrom(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, lineWidth, text_inclGlobalMarkupTags, coneLength_forStraightVectors, true, flattenThickRoundLineIntoAmplitudePlane, used_customAmplitudeAndTextDir, addNormalizedMarkingText, used_enlargeSmallTextToThisMinTextSize_value, writeComponentValuesAsText, used_endPlates_size, 0.0f, hiddenByNearerObjects); + break; + case ConesConfig.onlyAtStart: + DrawBasics.VectorTo(-vector_fromLineStart_toLineEnd, lineStartPosition, startColor, lineWidth, text_inclGlobalMarkupTags, coneLength_forStraightVectors, false, flattenThickRoundLineIntoAmplitudePlane, used_customAmplitudeAndTextDir, addNormalizedMarkingText, used_enlargeSmallTextToThisMinTextSize_value, writeComponentValuesAsText, used_endPlates_size, 0.0f, hiddenByNearerObjects); + break; + case ConesConfig.onlyAtEnd: + DrawBasics.VectorFrom(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, lineWidth, text_inclGlobalMarkupTags, coneLength_forStraightVectors, false, flattenThickRoundLineIntoAmplitudePlane, used_customAmplitudeAndTextDir, addNormalizedMarkingText, used_enlargeSmallTextToThisMinTextSize_value, writeComponentValuesAsText, used_endPlates_size, 0.0f, hiddenByNearerObjects); + break; + default: + break; + } + break; + case LineType.vectorWithExtention: + float used_forceFixedConeLength_value = forceFixedConeLength ? forceFixedConeLength_value : 0.0f; + DrawEngineBasics.RayLineExtended(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, lineWidth, text_inclGlobalMarkupTags, used_forceFixedConeLength_value, addNormalizedMarkingText, used_enlargeSmallTextToThisMinTextSize_value, extentionLength, 0.0f, hiddenByNearerObjects); + break; + case LineType.blinkingLine: + float used_blinkDurationInSec = ((Application.isPlaying == false) && (animationDuringEditMode == false)) ? float.MaxValue : blinkDurationInSec; //-> this prevents a problem in the situation where "animationDuringEditMode" has been disabled in a blink phase where the line is not possible. Otherwise in such cases the line would permanently invisible. + DrawBasics.BlinkingRay(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, used_blinkDurationInSec, lineWidth, text_inclGlobalMarkupTags, lineStyle, blinkColor, stylePatternScaleFactor, used_customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, used_endPlates_size, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + break; + case LineType.lineUnderTension: + DrawBasics.RayUnderTension(lineStartPosition, vector_fromLineStart_toLineEnd, relaxedLength, relaxedColor, lineStyle_underTension, stretchFactor_forStretchedTensionColor, color_forStretchedTension, stretchFactor_forSqueezedTensionColor, color_forSqueezedTension, lineWidth, text_inclGlobalMarkupTags, alphaOfReferenceLengthDisplay, stylePatternScaleFactor, used_customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, used_endPlates_size, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + break; + case LineType.movingArrowsLine: + precedingLineAnimationProgress = MovingArrowsRay_fadeableAnimSpeed.InternalDraw(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, lineWidth_ofMovingArrowsLine, distanceBetweenArrows, lengthOfArrows, text_inclGlobalMarkupTags, animationSpeed_ofMovingArrowsLine, precedingLineAnimationProgress, backwardAnimationFlipsArrowDirection, flattenThickRoundLineIntoAmplitudePlane_ofMovingArrowsLine, used_customAmplitudeAndTextDir, used_endPlates_size, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects); + break; + case LineType.lineWithAlternatingColors: + precedingLineAnimationProgress = RayWithAlternatingColors_fadeableAnimSpeed.InternalDraw(lineStartPosition, vector_fromLineStart_toLineEnd, startColor, alternatingColor, lineWidth, lengthOfStripes, text_inclGlobalMarkupTags, animationSpeed, precedingLineAnimationProgress, used_customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, used_endPlates_size, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinTextSize_value, 0.0f, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + break; + default: + break; + } + + UtilitiesDXXL_DrawBasics.Reverse_shiftTextPosOnLines_toNonIntersecting(); + UtilitiesDXXL_DrawBasics.Reverse_relSizeOfTextOnLines(); + Reverse_amplitudeAndTextDirConfig(); + Reverse_endPlatesConfig(); + + TrySheduleRepaintSceneViewForAnimationOutsidePlaymode(); + } + + void GetLineStartPosAndDirection(out Vector3 lineStartPosition, out Vector3 vector_fromLineStart_toLineEnd) + { + Vector3 lineEndPosition; + switch (lineDefinitionMode) + { + case LineDefinitionMode.startPositionAndEndPosition: + lineStartPosition = GetLineStartPosition_fromDefineStartPosSection(); + lineEndPosition = GetLineEndPosition_fromDefineEndPosSection(); + vector_fromLineStart_toLineEnd = lineEndPosition - lineStartPosition; + break; + case LineDefinitionMode.startPositionAndDirectionVectorToEndPosition: + lineStartPosition = GetLineStartPosition_fromDefineStartPosSection(); + vector_fromLineStart_toLineEnd = Get_customVector3_1_inGlobalSpaceUnits(); + break; + case LineDefinitionMode.endPositionAndDirectionVectorToIt: + lineEndPosition = GetLineEndPosition_fromDefineEndPosSection(); + vector_fromLineStart_toLineEnd = Get_customVector3_1_inGlobalSpaceUnits(); + lineStartPosition = lineEndPosition - vector_fromLineStart_toLineEnd; + break; + default: + lineStartPosition = Vector3.zero; + vector_fromLineStart_toLineEnd = Vector3.forward; + break; + } + } + + Vector3 GetLineStartPosition_fromDefineStartPosSection() + { + switch (positionDefinitionOption_ofStartPos) + { + case PositionDefinitionOption.positionOfThisGameobjectPlusOffset: + return GetDrawPos3D_global(); + case PositionDefinitionOption.positionOfOtherGameobjectPlusOffset: + bool theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject = (coordinateSpaceForLocalOffsetOnOtherGameobject_forStartPos == CoordinateSpaceForLocalOffset.useLocalSpaceDefinedByTransformOnOtherGameobject); + return GetDrawPos3D_ofPartnerGameobject_global(theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject); + case PositionDefinitionOption.chooseFree: + return Get_customVector3_3_inGlobalSpaceUnits(); + default: + return Vector3.zero; + } + } + + Vector3 GetLineEndPosition_fromDefineEndPosSection() + { + switch (positionDefinitionOption_ofEndPos) + { + case PositionDefinitionOption.positionOfThisGameobjectPlusOffset: + return GetDrawPos3D_global_independentAlternativeValue(); + case PositionDefinitionOption.positionOfOtherGameobjectPlusOffset: + bool theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject = (coordinateSpaceForLocalOffsetOnOtherGameobject_forEndPos == CoordinateSpaceForLocalOffset.useLocalSpaceDefinedByTransformOnOtherGameobject); + return GetDrawPos3D_ofPartnerGameobject_global_independentAlternativeValue(theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject); + case PositionDefinitionOption.chooseFree: + return Get_customVector3_4_inGlobalSpaceUnits(); + default: + return Vector3.forward; + } + } + + Vector3 Set_amplitudeAndTextDirConfig_reversible() + { + switch (amplitudeAndTextAlignment) + { + case AmplitudeAndTextAlignment.verticalInGlobalSpace: + UtilitiesDXXL_DrawBasics.Set_automaticAmplitudeAndTextAlignment_reversible(DrawBasics.AutomaticAmplitudeAndTextAlignment.vertical); + return Vector3.zero; + case AmplitudeAndTextAlignment.perpendicularToSceneViewCamera: + UtilitiesDXXL_DrawBasics.Set_automaticAmplitudeAndTextAlignment_reversible(DrawBasics.AutomaticAmplitudeAndTextAlignment.perpendicularToCamera); + UtilitiesDXXL_DrawBasics.Set_cameraForAutomaticOrientation_reversible(DrawBasics.CameraForAutomaticOrientation.sceneViewCamera); + return Vector3.zero; + case AmplitudeAndTextAlignment.perpendicularToGameViewCamera: + UtilitiesDXXL_DrawBasics.Set_automaticAmplitudeAndTextAlignment_reversible(DrawBasics.AutomaticAmplitudeAndTextAlignment.perpendicularToCamera); + UtilitiesDXXL_DrawBasics.Set_cameraForAutomaticOrientation_reversible(DrawBasics.CameraForAutomaticOrientation.gameViewCamera); + return Vector3.zero; + case AmplitudeAndTextAlignment.customAmplitudeDirection: + return Get_customVector3_2_inGlobalSpaceUnits(); + default: + return Vector3.zero; + } + } + + void Reverse_amplitudeAndTextDirConfig() + { + switch (amplitudeAndTextAlignment) + { + case AmplitudeAndTextAlignment.verticalInGlobalSpace: + UtilitiesDXXL_DrawBasics.Reverse_automaticAmplitudeAndTextAlignment(); + break; + case AmplitudeAndTextAlignment.perpendicularToSceneViewCamera: + UtilitiesDXXL_DrawBasics.Reverse_automaticAmplitudeAndTextAlignment(); + UtilitiesDXXL_DrawBasics.Reverse_cameraForAutomaticOrientation(); + break; + case AmplitudeAndTextAlignment.perpendicularToGameViewCamera: + UtilitiesDXXL_DrawBasics.Reverse_automaticAmplitudeAndTextAlignment(); + UtilitiesDXXL_DrawBasics.Reverse_cameraForAutomaticOrientation(); + break; + case AmplitudeAndTextAlignment.customAmplitudeDirection: + break; + default: + break; + } + } + + public float Set_endPlatesConfig_reversible() + { + if (endPlatesConfig == EndPlatesConfig.disabled) + { + return 0.0f; + } + else + { + UtilitiesDXXL_DrawBasics.Set_endPlates_sizeInterpretation_reversible(endPlates_sizeInterpretation); + switch (endPlatesConfig) + { + case EndPlatesConfig.bothSides: + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineStart_reversible(false); + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineEnd_reversible(false); + break; + case EndPlatesConfig.onlyAtStart: + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineStart_reversible(false); + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineEnd_reversible(true); + break; + case EndPlatesConfig.onlyAtEnd: + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineStart_reversible(true); + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineEnd_reversible(false); + break; + default: + break; + } + return endPlates_size; + } + } + + public void Reverse_endPlatesConfig() + { + if (endPlatesConfig != EndPlatesConfig.disabled) + { + UtilitiesDXXL_DrawBasics.Reverse_endPlates_sizeInterpretation(); + UtilitiesDXXL_DrawBasics.Reverse_disableEndPlates_atLineStart(); + UtilitiesDXXL_DrawBasics.Reverse_disableEndPlates_atLineEnd(); + } + } + + public void TrySheduleRepaintSceneViewForAnimationOutsidePlaymode() + { + if (animationDuringEditMode) + { + if (Application.isPlaying == false) + { + if (DrawnLineUsesAnimation(true)) + { + UtilitiesDXXL_Components.currentVirtualOnDrawGizmoCycle_shouldRepaintAllViews = true; + } + } + } + } + + public bool DrawnLineUsesAnimation(bool returnFalseForAnimationSpeedOfZero) + { + if (lineType == LineType.standardLine) + { + if (UtilitiesDXXL_LineStyles.CheckIfLineStyleIsAnimatable(lineStyle)) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(animationSpeed)) + { + return (!returnFalseForAnimationSpeedOfZero); + } + else + { + return true; + } + } + } + + if (lineType == LineType.lineWithAlternatingColors) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(animationSpeed)) + { + return (!returnFalseForAnimationSpeedOfZero); + } + else + { + return true; + } + } + + if (lineType == LineType.movingArrowsLine) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(animationSpeed_ofMovingArrowsLine)) + { + return (!returnFalseForAnimationSpeedOfZero); + } + else + { + return true; + } + } + + if (lineType == LineType.blinkingLine) + { + return true; + } + + return false; + } + + public bool CheckIf_lineCanBeAffectedByFlattenBool() + { + if (lineType == LineType.vectorWithExtention) + { + return false; //never affected: doesn't have the flatten-option + } + else + { + if (lineType == LineType.vector) + { + return true; //always affected due to "cones". + } + else + { + if ((lineStyle == DrawBasics.LineStyle.arrows) && ((lineType == LineType.standardLine) || (lineType == LineType.blinkingLine))) + { + return true; //always affected due to "cones". + } + else + { + if ((lineStyle_underTension == DrawBasics.LineStyle.arrows) && (lineType == LineType.lineUnderTension)) + { + return true; //always affected due to "cones". + } + else + { + if (lineType == LineType.movingArrowsLine) + { + return ((UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_ofMovingArrowsLine) == false) || EndPlatesAreActive()); + } + else + { + return ((UtilitiesDXXL_Math.ApproximatelyZero(lineWidth) == false) || EndPlatesAreActive()); + } + } + } + } + } + } + + bool EndPlatesAreActive() + { + return ((endPlatesConfig != EndPlatesConfig.disabled) && (UtilitiesDXXL_Math.ApproximatelyZero(endPlates_size) == false)); + } + + public virtual float GetLineLength() + { + GetLineStartPosAndDirection(out Vector3 lineStartPosition, out Vector3 vector_fromLineStart_toLineEnd); + return vector_fromLineStart_toLineEnd.magnitude; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/LineDrawer.cs.meta b/Runtime/DrawDebugLibrary/components/LineDrawer.cs.meta new file mode 100644 index 0000000..e25e38f --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/LineDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 50cd64f06e2254244817c9592b836558 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/MeasurementVisualizer.cs b/Runtime/DrawDebugLibrary/components/MeasurementVisualizer.cs new file mode 100644 index 0000000..373ffa1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/MeasurementVisualizer.cs @@ -0,0 +1,205 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Measurement Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class MeasurementVisualizer : VisualizerParent + { + public enum MeasurementType { distanceBetweenPoints, distanceThresholdBetweenPoints, distanceFromPointToLine, distanceFromLineToLine, distanceFromPointToPlane, distanceAlongOrthographicViewDir, distancePerpendicularToOrthographicViewDir, angleBetweenVectors, angleFromLineToPlane, angleFromPlaneToPlane }; + [SerializeField] MeasurementType measurementType = MeasurementType.distanceBetweenPoints; + + public enum AngleUnit { degree, radians }; + [SerializeField] AngleUnit angleUnitToDisplay = AngleUnit.degree; + + [SerializeField] Color color1 = DrawMeasurements.defaultColor1; + [SerializeField] Color color2 = DrawMeasurements.defaultColor2; + [SerializeField] public bool appearanceBlock_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public float measuredResultValue; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] float linesWidth = 0.0f; + [SerializeField] Color color = DrawBasics.defaultColor; + [SerializeField] float enlargeSmallTextToThisMinTextSize = 0.005f; + [SerializeField] bool addTextForAlternativeAngleUnit = true; + [SerializeField] float forceRadius_value = 1.0f; + [SerializeField] bool useReflexAngleOver180deg = false; + [SerializeField] bool drawBoundaryLines = true; + [SerializeField] bool returnObtuseAngleOver90deg = false; + [SerializeField] string name_ofGeoObject1 = null; + [SerializeField] string name_ofGeoObject2 = null; + [SerializeField] float minimumLineLength_forDistancePointToLine = DrawMeasurements.minimumLineLength_forDistancePointToLine; + [SerializeField] float minimumLineLength_forDistanceLineToLine = DrawMeasurements.minimumLineLength_forDistanceLineToLine; + [SerializeField] float minimumLineLength_forAngleLineToPlane = DrawMeasurements.minimumLineLength_forAngleLineToPlane; + + public enum PointerConfigOfAngleBetweenVectors { atBothEnds, onlyAtStart, onlyAtEnd }; + [SerializeField] PointerConfigOfAngleBetweenVectors pointerConfigOfAngleBetweenVectors = PointerConfigOfAngleBetweenVectors.atBothEnds; + + //only for distanceThreshold: + public enum DistanceThresholdType { one, two }; + [SerializeField] DistanceThresholdType distanceThresholdType = DistanceThresholdType.one; + + [SerializeField] float smallerThresholdDistance = 1.0f; + [SerializeField] float biggerThresholdDistance = 2.0f; + [SerializeField] bool displayDistanceAlsoAsText = false; + + public enum ExactlyOnThresholdBehaviour { countAsShorterThanThreshold, countAsLongerThanThreshold }; + [SerializeField] ExactlyOnThresholdBehaviour exactlyOnThresholdBehaviour = ExactlyOnThresholdBehaviour.countAsShorterThanThreshold; + + [SerializeField] DrawBasics.LineStyle overwriteStyle_forNear = DrawBasics.LineStyle.electricNoise; + [SerializeField] DrawBasics.LineStyle overwriteStyle_forMiddle = DrawBasics.LineStyle.electricImpulses; + [SerializeField] DrawBasics.LineStyle overwriteStyle_forFar = DrawBasics.LineStyle.solid; + + [SerializeField] Color overwriteColor_forNear_oneThresholdVersion = UtilitiesDXXL_Colors.red_boolFalse; + [SerializeField] Color overwriteColor_forFar_oneThresholdVersion = UtilitiesDXXL_Colors.green_boolTrue; + + [SerializeField] Color overwriteColor_forNear_twoThresholdsVersion = UtilitiesDXXL_Colors.red_lineThresholdFarDistance; + [SerializeField] Color overwriteColor_forMiddle_twoThresholdsVersion = UtilitiesDXXL_Colors.orange_lineThresholdMiddleDistance; + [SerializeField] Color overwriteColor_forFar_twoThresholdsVersion = UtilitiesDXXL_Colors.green_lineThresholdNearDistance; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + endPlates_size = 0.0f; + coneLength_forStraightVectors = 0.10f; + coneLength_forCircledVectors = 0.13f; + drawPosOffset3DSection_isOutfolded = true; + drawPosOffset3DSection_ofPartnerGameobject_isOutfolded = true; + + customVector3Configs[0].picker_isOutfolded = true; + customVector3Configs[0].source = CustomVector3Source.transformsForward; + customVector3Configs[0].clipboardForManualInput = Vector3.one; + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[1].picker_isOutfolded = true; + customVector3Configs[1].source = CustomVector3Source.transformsForward; + customVector3Configs[1].clipboardForManualInput = Vector3.forward; + customVector3Configs[1].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[2].picker_isOutfolded = true; + customVector3Configs[2].source = CustomVector3Source.manualInput; + customVector3Configs[2].clipboardForManualInput = Vector3.one; + customVector3Configs[2].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[3].picker_isOutfolded = true; + customVector3Configs[3].source = CustomVector3Source.transformsForward; + customVector3Configs[3].clipboardForManualInput = Vector3.one; + customVector3Configs[3].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3ofPartnerGameobject_picker_isOutfolded = true; + source_ofCustomVector3ofPartnerGameobject = CustomVector3Source.transformsForward; + customVector3ofPartnerGameobject_clipboardForManualInput = Vector3.one; + vectorInterpretation_ofCustomVector3ofPartnerGameobject = VectorInterpretation.globalSpace; + } + + public override void DrawVisualizedObject() + { + UtilitiesDXXL_Measurements.Set_defaultColor1_reversible(color1); + UtilitiesDXXL_Measurements.Set_defaultColor2_reversible(color2); + switch (measurementType) + { + case MeasurementType.distanceBetweenPoints: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(coneLength_interpretation_forStraightVectors); + measuredResultValue = DrawMeasurements.Distance(GetDrawPos3D_global(), GetDrawPos3D_ofPartnerGameobject_global(), color, linesWidth, text_inclGlobalMarkupTags, coneLength_forStraightVectors, enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + break; + case MeasurementType.distanceThresholdBetweenPoints: + switch (distanceThresholdType) + { + case DistanceThresholdType.one: + UtilitiesDXXL_DrawBasics.Set_endPlates_sizeInterpretation_reversible(endPlates_sizeInterpretation); + DrawMeasurements.DistanceThreshold(GetDrawPos3D_global(), GetDrawPos3D_ofPartnerGameobject_global(), smallerThresholdDistance, text_inclGlobalMarkupTags, displayDistanceAlsoAsText, linesWidth, ExactlyThresholdLength_countsAsShorter(), endPlates_size, overwriteStyle_forNear, overwriteStyle_forFar, overwriteColor_forNear_oneThresholdVersion, overwriteColor_forFar_oneThresholdVersion, default(Vector3), enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_endPlates_sizeInterpretation(); + break; + case DistanceThresholdType.two: + UtilitiesDXXL_DrawBasics.Set_endPlates_sizeInterpretation_reversible(endPlates_sizeInterpretation); + DrawMeasurements.DistanceThresholds(GetDrawPos3D_global(), GetDrawPos3D_ofPartnerGameobject_global(), smallerThresholdDistance, biggerThresholdDistance, text_inclGlobalMarkupTags, displayDistanceAlsoAsText, linesWidth, ExactlyThresholdLength_countsAsShorter(), endPlates_size, overwriteStyle_forNear, overwriteStyle_forMiddle, overwriteStyle_forFar, overwriteColor_forNear_twoThresholdsVersion, overwriteColor_forMiddle_twoThresholdsVersion, overwriteColor_forFar_twoThresholdsVersion, default(Vector3), enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_endPlates_sizeInterpretation(); + break; + default: + break; + } + break; + case MeasurementType.distanceFromPointToLine: + UtilitiesDXXL_Measurements.Set_minimumLineLength_forDistancePointToLine_reversible(minimumLineLength_forDistancePointToLine); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(coneLength_interpretation_forStraightVectors); + measuredResultValue = DrawMeasurements.DistancePointToLine(GetDrawPos3D_global(), GetDrawPos3D_ofPartnerGameobject_global(), Get_customVector3ofPartnerGameobject_inGlobalSpaceUnits(), color, linesWidth, text_inclGlobalMarkupTags, name_ofGeoObject2, coneLength_forStraightVectors, enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + UtilitiesDXXL_Measurements.Reverse_minimumLineLength_forDistancePointToLine(); + break; + case MeasurementType.distanceFromLineToLine: + UtilitiesDXXL_Measurements.Set_minimumLineLength_forDistanceLineToLine_reversible(minimumLineLength_forDistanceLineToLine); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(coneLength_interpretation_forStraightVectors); + measuredResultValue = DrawMeasurements.DistanceLineToLine(GetDrawPos3D_global(), Get_customVector3_4_inGlobalSpaceUnits(), GetDrawPos3D_ofPartnerGameobject_global(), Get_customVector3ofPartnerGameobject_inGlobalSpaceUnits(), color, linesWidth, text_inclGlobalMarkupTags, name_ofGeoObject1, name_ofGeoObject2, coneLength_forStraightVectors, enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + UtilitiesDXXL_Measurements.Reverse_minimumLineLength_forDistanceLineToLine(); + break; + case MeasurementType.distanceFromPointToPlane: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(coneLength_interpretation_forStraightVectors); + measuredResultValue = DrawMeasurements.DistancePointToPlane(GetDrawPos3D_global(), GetDrawPos3D_ofPartnerGameobject_global(), Get_customVector3ofPartnerGameobject_inGlobalSpaceUnits(), color, linesWidth, text_inclGlobalMarkupTags, name_ofGeoObject2, coneLength_forStraightVectors, enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + break; + case MeasurementType.distanceAlongOrthographicViewDir: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(coneLength_interpretation_forStraightVectors); + measuredResultValue = DrawMeasurements.DistanceAlongOrthoViewDir(GetDrawPos3D_global(), GetDrawPos3D_ofPartnerGameobject_global(), Get_customVector3_1_inGlobalSpaceUnits(), color, linesWidth, text_inclGlobalMarkupTags, coneLength_forStraightVectors, enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + break; + case MeasurementType.distancePerpendicularToOrthographicViewDir: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(coneLength_interpretation_forStraightVectors); + measuredResultValue = DrawMeasurements.DistancePerpToOrthoViewDir(GetDrawPos3D_global(), GetDrawPos3D_ofPartnerGameobject_global(), Get_customVector3_1_inGlobalSpaceUnits(), color, linesWidth, text_inclGlobalMarkupTags, coneLength_forStraightVectors, enlargeSmallTextToThisMinTextSize, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + break; + case MeasurementType.angleBetweenVectors: + switch (pointerConfigOfAngleBetweenVectors) + { + case PointerConfigOfAngleBetweenVectors.atBothEnds: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(coneLength_interpretation_forCircledVectors); + measuredResultValue = DrawMeasurements.AngleSpan(Get_customVector3_2_inGlobalSpaceUnits(), Get_customVector3_3_inGlobalSpaceUnits(), GetDrawPos3D_global_independentAlternativeValue(), color, forceRadius_value, linesWidth, text_inclGlobalMarkupTags, useReflexAngleOver180deg, DisplayAndReturn_radInsteadOfDeg(), coneLength_forCircledVectors, drawBoundaryLines, addTextForAlternativeAngleUnit, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + break; + case PointerConfigOfAngleBetweenVectors.onlyAtStart: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(coneLength_interpretation_forCircledVectors); + measuredResultValue = DrawMeasurements.Angle(Get_customVector3_3_inGlobalSpaceUnits(), Get_customVector3_2_inGlobalSpaceUnits(), GetDrawPos3D_global_independentAlternativeValue(), color, forceRadius_value, linesWidth, text_inclGlobalMarkupTags, useReflexAngleOver180deg, DisplayAndReturn_radInsteadOfDeg(), coneLength_forCircledVectors, drawBoundaryLines, addTextForAlternativeAngleUnit, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + break; + case PointerConfigOfAngleBetweenVectors.onlyAtEnd: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(coneLength_interpretation_forCircledVectors); + measuredResultValue = DrawMeasurements.Angle(Get_customVector3_2_inGlobalSpaceUnits(), Get_customVector3_3_inGlobalSpaceUnits(), GetDrawPos3D_global_independentAlternativeValue(), color, forceRadius_value, linesWidth, text_inclGlobalMarkupTags, useReflexAngleOver180deg, DisplayAndReturn_radInsteadOfDeg(), coneLength_forCircledVectors, drawBoundaryLines, addTextForAlternativeAngleUnit, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + break; + default: + break; + } + break; + case MeasurementType.angleFromLineToPlane: + UtilitiesDXXL_Measurements.Set_minimumLineLength_forAngleLineToPlane_reversible(minimumLineLength_forAngleLineToPlane); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(coneLength_interpretation_forCircledVectors); + measuredResultValue = DrawMeasurements.AngleLineToPlane(GetDrawPos3D_global(), Get_customVector3_4_inGlobalSpaceUnits(), GetDrawPos3D_ofPartnerGameobject_global(), Get_customVector3ofPartnerGameobject_inGlobalSpaceUnits(), color, linesWidth, text_inclGlobalMarkupTags, name_ofGeoObject1, name_ofGeoObject2, returnObtuseAngleOver90deg, DisplayAndReturn_radInsteadOfDeg(), coneLength_forCircledVectors, addTextForAlternativeAngleUnit, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + UtilitiesDXXL_Measurements.Reverse_minimumLineLength_forAngleLineToPlane(); + break; + case MeasurementType.angleFromPlaneToPlane: + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(coneLength_interpretation_forCircledVectors); + measuredResultValue = DrawMeasurements.AnglePlaneToPlane(GetDrawPos3D_global(), Get_customVector3_4_inGlobalSpaceUnits(), GetDrawPos3D_ofPartnerGameobject_global(), Get_customVector3ofPartnerGameobject_inGlobalSpaceUnits(), color, linesWidth, text_inclGlobalMarkupTags, name_ofGeoObject1, name_ofGeoObject2, returnObtuseAngleOver90deg, DisplayAndReturn_radInsteadOfDeg(), coneLength_forCircledVectors, addTextForAlternativeAngleUnit, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + break; + default: + break; + } + + UtilitiesDXXL_Measurements.Reverse_defaultColor1(); + UtilitiesDXXL_Measurements.Reverse_defaultColor2(); + } + + bool DisplayAndReturn_radInsteadOfDeg() + { + return (angleUnitToDisplay == AngleUnit.radians); + } + + bool ExactlyThresholdLength_countsAsShorter() + { + return (exactlyOnThresholdBehaviour == ExactlyOnThresholdBehaviour.countAsShorterThanThreshold); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/MeasurementVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/MeasurementVisualizer.cs.meta new file mode 100644 index 0000000..0e1a546 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/MeasurementVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 27ffb8439c7c24b459e6fde4196c3e1c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/PhysicsVisualizer.cs b/Runtime/DrawDebugLibrary/components/PhysicsVisualizer.cs new file mode 100644 index 0000000..79d91cb --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/PhysicsVisualizer.cs @@ -0,0 +1,923 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Physics Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class PhysicsVisualizer : VisualizerParent + { + public enum Shape { collidersOnThisGameobject, box, sphere, capsule, ray }; + [SerializeField] Shape shape = Shape.collidersOnThisGameobject; + + [SerializeField] CollisionType collisionType = CollisionType.cast; + + [SerializeField] WantedHits wantedHits = WantedHits.all; + + [SerializeField] bool distanceIsInfinityRespToOtherGO = true; + [SerializeField] float adjustedDistance = 20.0f; + float used_distance; + + [SerializeField] float radiusScaleFactor_ofCastRespCheckedShape = 0.5f; + [SerializeField] Vector3 sizeScaleFactors_ofCastRespCheckedBox = Vector3.one; + [SerializeField] float heightScaleFactor_ofCastRespCheckedCapsule = 2.0f; + public enum CapsuleAlignment { alongLocalX, alongLocalY, alongLocalZ }; + [SerializeField] CapsuleAlignment capsuleAlignment = CapsuleAlignment.alongLocalY; + + public enum ShapeOrientationType { transformsRotationPlusOptionalAdditionalLocalRotation, transformsRotationPlusOptionalAdditionalGlobalRotation, customRotationIndependentFromTransform }; + [SerializeField] public ShapeOrientationType shapeOrientationType = ShapeOrientationType.transformsRotationPlusOptionalAdditionalLocalRotation; + [SerializeField] public Vector3 optionalAdditionalRotation_asEulersInV3 = Vector3.zero; + [SerializeField] public Vector3 customRotation_asEulersInV3 = Vector3.zero; + [SerializeField] public bool showTransformIndependentRotationHandle = false; + + BoxCollider[] boxColliders_onThisGameobject; + SphereCollider[] sphereColliders_onThisGameobject; + CapsuleCollider[] capsuleColliders_onThisGameobject; + [SerializeField] public bool theGameobjectHasACompatibleAndEnabledCollider; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + [SerializeField] public bool otherSettings_isFoldedOut = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + [SerializeField] bool excludeCollidersOnThisGO = true; + [SerializeField] bool excludeCollidersOnParentGOs = true; + [SerializeField] bool excludeCollidersOnChildrenGOs = true; + + Collider[] allCollidersOnThisGameobject; + List enabledState_ofAllCollidersOnThisGO_beforeCurrentDrawOperation = new List(); + + Collider[] allCollidersOnThisGameobjectAndOnParents; + List enabledState_ofAllCollidersOnThisGOPlusParents_beforeCurrentDrawOperation = new List(); + List isOnThisGO_forAllCollidersOnThisGOPlusParents_beforeCurrentDrawOperation = new List(); + + Collider[] allCollidersOnThisGameobjectAndOnChildren; + List enabledState_ofAllCollidersOnThisGOPlusChildren_beforeCurrentDrawOperation = new List(); + List isOnThisGO_forAllCollidersOnThisGOPlusChildren_beforeCurrentDrawOperation = new List(); + + [SerializeField] LayerMask layerMask = Physics.DefaultRaycastLayers; //The "Physics.DefaultRaycastLayers" already inludes the layer slots that are not yet defined by the users. That means this doesn't have to updated in cases where a user adds a custom defined layer AFTER the creation of this component + [SerializeField] QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal; + [SerializeField] int numberOfFoundHits = 0; + + //DrawPhysics' class global settings: + [SerializeField] Color colorForNonHittingCasts = DrawPhysics.colorForNonHittingCasts; + [SerializeField] Color colorForHittingCasts = DrawPhysics.colorForHittingCasts; + [SerializeField] Color colorForCastLineBeyondHit = DrawPhysics.colorForCastLineBeyondHit; + [SerializeField] Color colorForCastsHitText = DrawPhysics.colorForCastsHitText; + [SerializeField] bool doOverwriteColorForCastsHitNormals = false; + [SerializeField] Color overwriteColorForCastsHitNormals = UtilitiesDXXL_Physics.Get_defaultColor_ofNormal(); //-> not using "DrawPhysics.overwriteColorForCastsHitNormals", since this would be the default color that doesn't represent what the user sees as normal color in the Scene + [SerializeField] float scaleFactor_forCastHitTextSize = DrawPhysics.scaleFactor_forCastHitTextSize; + [SerializeField] float castSilhouetteVisualizerDensity = DrawPhysics.castSilhouetteVisualizerDensity; + [SerializeField] bool drawCastNameTag_atCastOrigin = DrawPhysics.drawCastNameTag_atCastOrigin; + [SerializeField] bool drawCastNameTag_atHitPositions = DrawPhysics.drawCastNameTag_atHitPositions; + [SerializeField] int maxListedColliders_inOverlapVolumesTextList = DrawPhysics.MaxListedColliders_inOverlapVolumesTextList; + [SerializeField] int maxOverlapingCollidersWithUntruncatedText = DrawPhysics.maxOverlapingCollidersWithUntruncatedText; + [SerializeField] [Range(0.001f, 0.2f)] float forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = 0.01f; + [SerializeField] float forcedConstantWorldspaceTextSize_forOverlapResultTexts = 0.1f; + [SerializeField] bool useCustomDirectionForHitResultText = false; + [SerializeField] Vector2 customDirectionForHitResultText = GetInitialValueFor_customDirectionForHitResultText(); + + public enum SaveDrawnLinesType { no_useFullDetails, useAMidwayTradeoff, yes_displayWithLowDetails }; + [SerializeField] SaveDrawnLinesType saveDrawnLinesType = Map_visualizationQuality_to_saveDrawnLinesType(DrawPhysics.visualizationQuality); + + public enum OverlapResultTextSizeInterpretation { relativeToTheSizeOfTheOverlapingPhysicsShape, fixedWorldSpaceSize, relativeToTheSceneViewWindowSize, relativeToTheGameViewWindowSize }; + [SerializeField] OverlapResultTextSizeInterpretation overlapResultTextSizeInterpretation = OverlapResultTextSizeInterpretation.relativeToTheSizeOfTheOverlapingPhysicsShape; + + Color colorForNonHittingCasts_before; + Color colorForHittingCasts_before; + Color colorForCastLineBeyondHit_before; + Color colorForCastsHitText_before; + Color overwriteColorForCastsHitNormals_before; + float scaleFactor_forCastHitTextSize_before; + float castSilhouetteVisualizerDensity_before; + DrawPhysics.VisualizationQuality visualizationQuality_before; + bool drawCastNameTag_atCastOrigin_before; + bool drawCastNameTag_atHitPositions_before; + int maxListedColliders_inOverlapVolumesTextList_before; + int maxOverlapingCollidersWithUntruncatedText_before; + float forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before; + float forcedConstantWorldspaceTextSize_forOverlapResultTexts_before; + DrawBasics.CameraForAutomaticOrientation cameraForAutomaticOrientation_before; + Vector2 directionOfHitResultText_before; + + public override void InitializeValues_onceInComponentLifetime() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = "Collisions from " + this.gameObject.name; + text_inclGlobalMarkupTags = "Collisions from " + this.gameObject.name; + } + + customVector3Configs[0].picker_isOutfolded = true; + customVector3Configs[0].source = CustomVector3Source.transformsForward; + customVector3Configs[0].clipboardForManualInput = Vector3.one; + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy() + { + if (shape == Shape.collidersOnThisGameobject) + { + if (CheckIfGameobjectHasASupportedCollider() == false) + { + shape = Shape.box; + } + } + } + + public override void DrawVisualizedObject() + { + TryFetchCurrentEnabledStateOfCollidersOnThisGameobjectsHierarchy(); + Save_globalDrawPhysicsOptions_beforeThisDrawOperation(); + try + { + Set_globalDrawPhysicsOptions_toValuesFromInpsector(); + TryDisableEnabledStateOfCollidersOnThisGameobjectsHierarchy(); + CastRespCheckTheColliders_andDrawThem(); + } + catch { } + TryRestoreEnabledStateOfCollidersOnThisGameobjectsHierarchy(); + Restore_globalDrawPhysicsOptions_toValuesFromBefore(); + } + + bool CheckIfGameobjectHasASupportedCollider() + { + if ((this.gameObject.GetComponent() == null) && (this.gameObject.GetComponent() == null) && (this.gameObject.GetComponent() == null)) + { + return false; + } + else + { + return true; + } + } + + void TryFetchCurrentEnabledStateOfCollidersOnThisGameobjectsHierarchy() + { + if (excludeCollidersOnThisGO || excludeCollidersOnParentGOs || excludeCollidersOnChildrenGOs) //The other flag's threads need "allCollidersOnThisGameobject" + { + allCollidersOnThisGameobject = this.gameObject.GetComponents(); + if (allCollidersOnThisGameobject != null) + { + for (int i = 0; i < allCollidersOnThisGameobject.Length; i++) + { + if (allCollidersOnThisGameobject[i] != null) + { + UtilitiesDXXL_List.AddToABoolList(ref enabledState_ofAllCollidersOnThisGO_beforeCurrentDrawOperation, allCollidersOnThisGameobject[i].enabled, i); + } + } + } + } + + if (excludeCollidersOnParentGOs) + { + allCollidersOnThisGameobjectAndOnParents = this.gameObject.GetComponentsInParent(); + if (allCollidersOnThisGameobjectAndOnParents != null) + { + for (int i = 0; i < allCollidersOnThisGameobjectAndOnParents.Length; i++) + { + if (allCollidersOnThisGameobjectAndOnParents[i] != null) + { + UtilitiesDXXL_List.AddToABoolList(ref enabledState_ofAllCollidersOnThisGOPlusParents_beforeCurrentDrawOperation, allCollidersOnThisGameobjectAndOnParents[i].enabled, i); + UtilitiesDXXL_List.AddToABoolList(ref isOnThisGO_forAllCollidersOnThisGOPlusParents_beforeCurrentDrawOperation, CheckIfColliderIsOnThisGameobject(allCollidersOnThisGameobjectAndOnParents[i]), i); + } + } + } + } + + if (excludeCollidersOnChildrenGOs) + { + allCollidersOnThisGameobjectAndOnChildren = this.gameObject.GetComponentsInChildren(); + + if (allCollidersOnThisGameobjectAndOnChildren != null) + { + for (int i = 0; i < allCollidersOnThisGameobjectAndOnChildren.Length; i++) + { + if (allCollidersOnThisGameobjectAndOnChildren[i] != null) + { + UtilitiesDXXL_List.AddToABoolList(ref enabledState_ofAllCollidersOnThisGOPlusChildren_beforeCurrentDrawOperation, allCollidersOnThisGameobjectAndOnChildren[i].enabled, i); + UtilitiesDXXL_List.AddToABoolList(ref isOnThisGO_forAllCollidersOnThisGOPlusChildren_beforeCurrentDrawOperation, CheckIfColliderIsOnThisGameobject(allCollidersOnThisGameobjectAndOnChildren[i]), i); + } + } + } + } + } + + bool CheckIfColliderIsOnThisGameobject(Collider collider_toCheckIfItIsOnThisGameobject) + { + if (collider_toCheckIfItIsOnThisGameobject != null) + { + if (allCollidersOnThisGameobject != null) + { + for (int i = 0; i < allCollidersOnThisGameobject.Length; i++) + { + if (allCollidersOnThisGameobject[i] != null) + { + if (allCollidersOnThisGameobject[i] == collider_toCheckIfItIsOnThisGameobject) + { + return true; + } + } + } + } + } + return false; + } + + bool GetEnabledStateBeforeCurrentDrawOperation_ofColliderComponentOnThisGameobject(Collider collider_toRetrieveEnabledStateFor) + { + if (collider_toRetrieveEnabledStateFor != null) + { + if (allCollidersOnThisGameobject != null) + { + for (int i = 0; i < allCollidersOnThisGameobject.Length; i++) + { + if (allCollidersOnThisGameobject[i] != null) + { + if (allCollidersOnThisGameobject[i] == collider_toRetrieveEnabledStateFor) + { + return enabledState_ofAllCollidersOnThisGO_beforeCurrentDrawOperation[i]; + } + } + } + } + } + return false; + } + + void TryDisableEnabledStateOfCollidersOnThisGameobjectsHierarchy() + { + if (excludeCollidersOnThisGO) + { + if (allCollidersOnThisGameobject != null) + { + for (int i = 0; i < allCollidersOnThisGameobject.Length; i++) + { + if (allCollidersOnThisGameobject[i] != null) + { + allCollidersOnThisGameobject[i].enabled = false; + } + } + } + } + + if (excludeCollidersOnParentGOs) + { + if (allCollidersOnThisGameobjectAndOnParents != null) + { + for (int i = 0; i < allCollidersOnThisGameobjectAndOnParents.Length; i++) + { + if (allCollidersOnThisGameobjectAndOnParents[i] != null) + { + if (isOnThisGO_forAllCollidersOnThisGOPlusParents_beforeCurrentDrawOperation[i] == false) + { + allCollidersOnThisGameobjectAndOnParents[i].enabled = false; + } + } + } + } + } + + if (excludeCollidersOnChildrenGOs) + { + if (allCollidersOnThisGameobjectAndOnChildren != null) + { + for (int i = 0; i < allCollidersOnThisGameobjectAndOnChildren.Length; i++) + { + if (allCollidersOnThisGameobjectAndOnChildren[i] != null) + { + if (isOnThisGO_forAllCollidersOnThisGOPlusChildren_beforeCurrentDrawOperation[i] == false) + { + allCollidersOnThisGameobjectAndOnChildren[i].enabled = false; + } + } + } + } + } + } + + void TryRestoreEnabledStateOfCollidersOnThisGameobjectsHierarchy() + { + if (excludeCollidersOnThisGO) + { + if (allCollidersOnThisGameobject != null) + { + for (int i = 0; i < allCollidersOnThisGameobject.Length; i++) + { + if (allCollidersOnThisGameobject[i] != null) + { + allCollidersOnThisGameobject[i].enabled = enabledState_ofAllCollidersOnThisGO_beforeCurrentDrawOperation[i]; + } + } + } + } + + if (excludeCollidersOnParentGOs) + { + if (allCollidersOnThisGameobjectAndOnParents != null) + { + for (int i = 0; i < allCollidersOnThisGameobjectAndOnParents.Length; i++) + { + if (allCollidersOnThisGameobjectAndOnParents[i] != null) + { + if (isOnThisGO_forAllCollidersOnThisGOPlusParents_beforeCurrentDrawOperation[i] == false) + { + allCollidersOnThisGameobjectAndOnParents[i].enabled = enabledState_ofAllCollidersOnThisGOPlusParents_beforeCurrentDrawOperation[i]; + } + } + } + } + } + + if (excludeCollidersOnChildrenGOs) + { + if (allCollidersOnThisGameobjectAndOnChildren != null) + { + for (int i = 0; i < allCollidersOnThisGameobjectAndOnChildren.Length; i++) + { + if (allCollidersOnThisGameobjectAndOnChildren[i] != null) + { + if (isOnThisGO_forAllCollidersOnThisGOPlusChildren_beforeCurrentDrawOperation[i] == false) + { + allCollidersOnThisGameobjectAndOnChildren[i].enabled = enabledState_ofAllCollidersOnThisGOPlusChildren_beforeCurrentDrawOperation[i]; + } + } + } + } + } + } + + void Save_globalDrawPhysicsOptions_beforeThisDrawOperation() + { + colorForNonHittingCasts_before = DrawPhysics.colorForNonHittingCasts; + colorForHittingCasts_before = DrawPhysics.colorForHittingCasts; + colorForCastLineBeyondHit_before = DrawPhysics.colorForCastLineBeyondHit; + colorForCastsHitText_before = DrawPhysics.colorForCastsHitText; + scaleFactor_forCastHitTextSize_before = DrawPhysics.scaleFactor_forCastHitTextSize; + castSilhouetteVisualizerDensity_before = DrawPhysics.castSilhouetteVisualizerDensity; + visualizationQuality_before = DrawPhysics.visualizationQuality; + drawCastNameTag_atCastOrigin_before = DrawPhysics.drawCastNameTag_atCastOrigin; + drawCastNameTag_atHitPositions_before = DrawPhysics.drawCastNameTag_atHitPositions; + maxListedColliders_inOverlapVolumesTextList_before = DrawPhysics.MaxListedColliders_inOverlapVolumesTextList; + maxOverlapingCollidersWithUntruncatedText_before = DrawPhysics.maxOverlapingCollidersWithUntruncatedText; + forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before = DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts; + forcedConstantWorldspaceTextSize_forOverlapResultTexts_before = DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts; + cameraForAutomaticOrientation_before = DrawBasics.cameraForAutomaticOrientation; + + if (doOverwriteColorForCastsHitNormals) + { + overwriteColorForCastsHitNormals_before = DrawPhysics.overwriteColorForCastsHitNormals; + } + + if (useCustomDirectionForHitResultText) + { + directionOfHitResultText_before = DrawPhysics.directionOfHitResultText; + } + } + + void Set_globalDrawPhysicsOptions_toValuesFromInpsector() + { + DrawPhysics.colorForNonHittingCasts = colorForNonHittingCasts; + DrawPhysics.colorForHittingCasts = colorForHittingCasts; + DrawPhysics.colorForCastLineBeyondHit = colorForCastLineBeyondHit; + DrawPhysics.colorForCastsHitText = colorForCastsHitText; + DrawPhysics.scaleFactor_forCastHitTextSize = scaleFactor_forCastHitTextSize; + DrawPhysics.castSilhouetteVisualizerDensity = castSilhouetteVisualizerDensity; + DrawPhysics.visualizationQuality = Map_saveDrawnLinesType_to_visualizationQuality(saveDrawnLinesType); + DrawPhysics.drawCastNameTag_atCastOrigin = drawCastNameTag_atCastOrigin; + DrawPhysics.drawCastNameTag_atHitPositions = drawCastNameTag_atHitPositions; + DrawPhysics.MaxListedColliders_inOverlapVolumesTextList = maxListedColliders_inOverlapVolumesTextList; + DrawPhysics.maxOverlapingCollidersWithUntruncatedText = maxOverlapingCollidersWithUntruncatedText; + + switch (overlapResultTextSizeInterpretation) + { + case OverlapResultTextSizeInterpretation.relativeToTheSizeOfTheOverlapingPhysicsShape: + DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = 0.0f; + DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts = 0.0f; + break; + case OverlapResultTextSizeInterpretation.fixedWorldSpaceSize: + DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = 0.0f; + DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts = forcedConstantWorldspaceTextSize_forOverlapResultTexts; + break; + case OverlapResultTextSizeInterpretation.relativeToTheSceneViewWindowSize: + DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts; + DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + break; + case OverlapResultTextSizeInterpretation.relativeToTheGameViewWindowSize: + DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts; + DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + break; + default: + break; + } + + if (doOverwriteColorForCastsHitNormals) + { + DrawPhysics.overwriteColorForCastsHitNormals = overwriteColorForCastsHitNormals; + } + + if (useCustomDirectionForHitResultText) + { + DrawPhysics.directionOfHitResultText = customDirectionForHitResultText; + } + } + + void Restore_globalDrawPhysicsOptions_toValuesFromBefore() + { + DrawPhysics.colorForNonHittingCasts = colorForNonHittingCasts_before; + DrawPhysics.colorForHittingCasts = colorForHittingCasts_before; + DrawPhysics.colorForCastLineBeyondHit = colorForCastLineBeyondHit_before; + DrawPhysics.colorForCastsHitText = colorForCastsHitText_before; + DrawPhysics.scaleFactor_forCastHitTextSize = scaleFactor_forCastHitTextSize_before; + DrawPhysics.castSilhouetteVisualizerDensity = castSilhouetteVisualizerDensity_before; + DrawPhysics.visualizationQuality = visualizationQuality_before; + DrawPhysics.drawCastNameTag_atCastOrigin = drawCastNameTag_atCastOrigin_before; + DrawPhysics.drawCastNameTag_atHitPositions = drawCastNameTag_atHitPositions_before; + DrawPhysics.MaxListedColliders_inOverlapVolumesTextList = maxListedColliders_inOverlapVolumesTextList_before; + DrawPhysics.maxOverlapingCollidersWithUntruncatedText = maxOverlapingCollidersWithUntruncatedText_before; + DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before; + DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts = forcedConstantWorldspaceTextSize_forOverlapResultTexts_before; + DrawBasics.cameraForAutomaticOrientation = cameraForAutomaticOrientation_before; + + if (doOverwriteColorForCastsHitNormals) + { + DrawPhysics.overwriteColorForCastsHitNormals = overwriteColorForCastsHitNormals_before; + } + + if (useCustomDirectionForHitResultText) + { + DrawPhysics.directionOfHitResultText = directionOfHitResultText_before; + } + } + + void CastRespCheckTheColliders_andDrawThem() + { + used_distance = Get_used_distance(); + switch (shape) + { + case Shape.collidersOnThisGameobject: + theGameobjectHasACompatibleAndEnabledCollider = false; + CastRespOverlap_boxCollidersOnThisGameobject(); + CastRespOverlap_sphereCollidersOnThisGameobject(); + CastRespOverlap_capsuleCollidersOnThisGameobject(); + break; + case Shape.box: + switch (collisionType) + { + case CollisionType.cast: + BoxCast(GetDrawPos3D_global(), Get_halfExtentsOfFinalBoxShape(sizeScaleFactors_ofCastRespCheckedBox), GetUsedBoxRotation()); + break; + case CollisionType.overlap: + Box_checkRespOverlap(GetDrawPos3D_global(), Get_halfExtentsOfFinalBoxShape(sizeScaleFactors_ofCastRespCheckedBox), GetUsedBoxRotation()); + break; + default: + break; + } + break; + case Shape.sphere: + switch (collisionType) + { + case CollisionType.cast: + SphereCast(GetDrawPos3D_global(), GetRadiusOfFinalSphereShape(radiusScaleFactor_ofCastRespCheckedShape)); + break; + case CollisionType.overlap: + Sphere_checkRespOverlap(GetDrawPos3D_global(), GetRadiusOfFinalSphereShape(radiusScaleFactor_ofCastRespCheckedShape)); + break; + default: + break; + } + break; + case Shape.capsule: + Get_shapeParameters_ofFinalCapsuleShape(out Vector3 point1, out Vector3 point2, out float radius, capsuleAlignment, radiusScaleFactor_ofCastRespCheckedShape, heightScaleFactor_ofCastRespCheckedCapsule, GetDrawPos3D_global()); + switch (collisionType) + { + case CollisionType.cast: + CapsuleCast(point1, point2, radius); + break; + case CollisionType.overlap: + Capsule_checkRespOverlap(point1, point2, radius); + break; + default: + break; + } + break; + case Shape.ray: + RayCast(); + break; + default: + break; + } + } + + float Get_used_distance() + { + if (distanceIsInfinityRespToOtherGO) + { + if (customVector3Configs[0].source == VisualizerParent.CustomVector3Source.toOtherGameobject) + { + if (customVector3Configs[0].targetGameObject != null) + { + return (transform.position - customVector3Configs[0].targetGameObject.transform.position).magnitude; + } + else + { + return Mathf.Infinity; + } + } + else + { + return Mathf.Infinity; + } + } + else + { + return adjustedDistance; + } + } + + void CastRespOverlap_boxCollidersOnThisGameobject() + { + boxColliders_onThisGameobject = this.gameObject.GetComponents(); + if (boxColliders_onThisGameobject != null) + { + for (int i = 0; i < boxColliders_onThisGameobject.Length; i++) + { + if (boxColliders_onThisGameobject[i] != null) + { + if (boxColliders_onThisGameobject[i].enabled || GetEnabledStateBeforeCurrentDrawOperation_ofColliderComponentOnThisGameobject(boxColliders_onThisGameobject[i])) + { + theGameobjectHasACompatibleAndEnabledCollider = true; + Vector3 center = GetCenterPosGlobalOfCollider(boxColliders_onThisGameobject[i].center); + Vector3 halfExtents = Get_halfExtentsOfFinalBoxShape(boxColliders_onThisGameobject[i].size); + Quaternion orientation = transform.rotation; + switch (collisionType) + { + case CollisionType.cast: + BoxCast(center, halfExtents, orientation); + break; + case CollisionType.overlap: + Box_checkRespOverlap(center, halfExtents, orientation); + break; + default: + break; + } + } + } + } + } + } + + void CastRespOverlap_sphereCollidersOnThisGameobject() + { + sphereColliders_onThisGameobject = this.gameObject.GetComponents(); + if (sphereColliders_onThisGameobject != null) + { + for (int i = 0; i < sphereColliders_onThisGameobject.Length; i++) + { + if (sphereColliders_onThisGameobject[i] != null) + { + if (sphereColliders_onThisGameobject[i].enabled || GetEnabledStateBeforeCurrentDrawOperation_ofColliderComponentOnThisGameobject(sphereColliders_onThisGameobject[i])) + { + theGameobjectHasACompatibleAndEnabledCollider = true; + Vector3 origin = GetCenterPosGlobalOfCollider(sphereColliders_onThisGameobject[i].center); + float radius = GetRadiusOfFinalSphereShape(sphereColliders_onThisGameobject[i].radius); + switch (collisionType) + { + case CollisionType.cast: + SphereCast(origin, radius); + break; + case CollisionType.overlap: + Sphere_checkRespOverlap(origin, radius); + break; + default: + break; + } + } + } + } + } + } + + void CastRespOverlap_capsuleCollidersOnThisGameobject() + { + capsuleColliders_onThisGameobject = this.gameObject.GetComponents(); + if (capsuleColliders_onThisGameobject != null) + { + for (int i = 0; i < capsuleColliders_onThisGameobject.Length; i++) + { + if (capsuleColliders_onThisGameobject[i] != null) + { + if (capsuleColliders_onThisGameobject[i].enabled || GetEnabledStateBeforeCurrentDrawOperation_ofColliderComponentOnThisGameobject(capsuleColliders_onThisGameobject[i])) + { + theGameobjectHasACompatibleAndEnabledCollider = true; + Vector3 colliderCenter_global = GetCenterPosGlobalOfCollider(capsuleColliders_onThisGameobject[i].center); + Get_shapeParameters_ofFinalCapsuleShape(out Vector3 point1, out Vector3 point2, out float radius, GetCapsuleAlignmentFromCollider(capsuleColliders_onThisGameobject[i].direction), capsuleColliders_onThisGameobject[i].radius, capsuleColliders_onThisGameobject[i].height, colliderCenter_global); + switch (collisionType) + { + case CollisionType.cast: + CapsuleCast(point1, point2, radius); + break; + case CollisionType.overlap: + Capsule_checkRespOverlap(point1, point2, radius); + break; + default: + break; + } + } + } + } + } + } + + float GetRadiusOfFinalSphereShape(float radiusScaleFactor_fromComponentProperty) + { + return (radiusScaleFactor_fromComponentProperty * UtilitiesDXXL_Math.GetBiggestAbsComponent_butReassignTheSign(transform.lossyScale)); + } + + Vector3 Get_halfExtentsOfFinalBoxShape(Vector3 sizeScaleFactors_fromComponentProperty) + { + return (0.5f * Vector3.Scale(transform.lossyScale, sizeScaleFactors_fromComponentProperty)); + } + + void Get_shapeParameters_ofFinalCapsuleShape(out Vector3 point1, out Vector3 point2, out float radius, CapsuleAlignment capsuleAlignment, float radiusScaleFactor_fromComponentProperty, float heightScaleFactor_fromComponentProperty, Vector3 finalCapsuleCenterPos_global) + { + UtilitiesDXXL_Math.Dimension directionOfCapsule = Convert_capsuleAlignment_to_cartesianDimension(capsuleAlignment); + radius = radiusScaleFactor_fromComponentProperty * UtilitiesDXXL_Math.GetBiggestAbsComponent_butReassignTheSign(transform.lossyScale, directionOfCapsule); + float absRadius = Mathf.Abs(radius); + float capsuleHeight = heightScaleFactor_fromComponentProperty * UtilitiesDXXL_Math.GetComponentByDimension(transform.lossyScale, directionOfCapsule); //"height" includes the whole capsule shape, and is not just from sphereCenter to sphereCenter + float halfCapsuleHeight = 0.5f * capsuleHeight; + float absHalfCapsuleHeight = Mathf.Abs(halfCapsuleHeight); + Vector3 finalUpwardDirectionOfCapsuleToCastRespCheck_asNormalizedVector = Get_finalUpwardDirectionOfCapsuleToCastRespCheck_asNormalizedVector(directionOfCapsule); + float point1s_offsetDistanceFromCenter = Mathf.Max(0.0f, absHalfCapsuleHeight - absRadius); + Vector3 point1s_offsetFromCenter = finalUpwardDirectionOfCapsuleToCastRespCheck_asNormalizedVector * point1s_offsetDistanceFromCenter; + point1 = finalCapsuleCenterPos_global + point1s_offsetFromCenter; + point2 = finalCapsuleCenterPos_global - point1s_offsetFromCenter; + } + + static UtilitiesDXXL_Math.Dimension Convert_capsuleAlignment_to_cartesianDimension(CapsuleAlignment capsuleAlignment_toConvert) + { + switch (capsuleAlignment_toConvert) + { + case CapsuleAlignment.alongLocalX: + return UtilitiesDXXL_Math.Dimension.x; + case CapsuleAlignment.alongLocalY: + return UtilitiesDXXL_Math.Dimension.y; + case CapsuleAlignment.alongLocalZ: + return UtilitiesDXXL_Math.Dimension.z; + default: + return UtilitiesDXXL_Math.Dimension.x; + } + } + + Vector3 GetCenterPosGlobalOfCollider(Vector3 collidersLocalCenter) + { + Vector3 xOffset = transform.right * transform.lossyScale.x * collidersLocalCenter.x; + Vector3 yOffset = transform.up * transform.lossyScale.y * collidersLocalCenter.y; + Vector3 zOffset = transform.forward * transform.lossyScale.z * collidersLocalCenter.z; + return (transform.position + xOffset + yOffset + zOffset); + } + + CapsuleAlignment GetCapsuleAlignmentFromCollider(int capsulesDirection_asInt) + { + switch (capsulesDirection_asInt) + { + case 0: + return CapsuleAlignment.alongLocalX; + case 1: + return CapsuleAlignment.alongLocalY; + case 2: + return CapsuleAlignment.alongLocalZ; + default: + return CapsuleAlignment.alongLocalX; + } + } + + Vector3 Get_finalUpwardDirectionOfCapsuleToCastRespCheck_asNormalizedVector(UtilitiesDXXL_Math.Dimension directionOfCapsule) + { + Quaternion additionalRotation; + Quaternion customRotation; + switch (shapeOrientationType) + { + case ShapeOrientationType.transformsRotationPlusOptionalAdditionalLocalRotation: + additionalRotation = UtilitiesDXXL_Math.ApproximatelyZero(optionalAdditionalRotation_asEulersInV3) ? Quaternion.identity : Quaternion.Euler(optionalAdditionalRotation_asEulersInV3); + switch (directionOfCapsule) + { + case UtilitiesDXXL_Math.Dimension.x: + return (transform.rotation * additionalRotation * Vector3.right); + case UtilitiesDXXL_Math.Dimension.y: + return (transform.rotation * additionalRotation * Vector3.up); + case UtilitiesDXXL_Math.Dimension.z: + return (transform.rotation * additionalRotation * Vector3.forward); + default: + return Vector3.forward; + } + case ShapeOrientationType.transformsRotationPlusOptionalAdditionalGlobalRotation: + additionalRotation = UtilitiesDXXL_Math.ApproximatelyZero(optionalAdditionalRotation_asEulersInV3) ? Quaternion.identity : Quaternion.Euler(optionalAdditionalRotation_asEulersInV3); + switch (directionOfCapsule) + { + case UtilitiesDXXL_Math.Dimension.x: + return (additionalRotation * transform.right); + case UtilitiesDXXL_Math.Dimension.y: + return (additionalRotation * transform.up); + case UtilitiesDXXL_Math.Dimension.z: + return (additionalRotation * transform.forward); + default: + return Vector3.forward; + } + case ShapeOrientationType.customRotationIndependentFromTransform: + customRotation = UtilitiesDXXL_Math.ApproximatelyZero(customRotation_asEulersInV3) ? Quaternion.identity : Quaternion.Euler(customRotation_asEulersInV3); + switch (directionOfCapsule) + { + case UtilitiesDXXL_Math.Dimension.x: + return (customRotation * Vector3.right); + case UtilitiesDXXL_Math.Dimension.y: + return (customRotation * Vector3.up); + case UtilitiesDXXL_Math.Dimension.z: + return (customRotation * Vector3.forward); + default: + return Vector3.forward; + } + default: + return Vector3.forward; + } + } + + Quaternion GetUsedBoxRotation() + { + switch (shapeOrientationType) + { + case ShapeOrientationType.transformsRotationPlusOptionalAdditionalLocalRotation: + if (UtilitiesDXXL_Math.ApproximatelyZero(optionalAdditionalRotation_asEulersInV3)) + { + return transform.rotation; + } + else + { + return (transform.rotation * Quaternion.Euler(optionalAdditionalRotation_asEulersInV3)); + } + case ShapeOrientationType.transformsRotationPlusOptionalAdditionalGlobalRotation: + if (UtilitiesDXXL_Math.ApproximatelyZero(optionalAdditionalRotation_asEulersInV3)) + { + return transform.rotation; + } + else + { + return (Quaternion.Euler(optionalAdditionalRotation_asEulersInV3) * transform.rotation); + } + case ShapeOrientationType.customRotationIndependentFromTransform: + if (UtilitiesDXXL_Math.ApproximatelyZero(customRotation_asEulersInV3)) + { + return Quaternion.identity; + } + else + { + return Quaternion.Euler(customRotation_asEulersInV3); + } + default: + return Quaternion.identity; + } + } + + void BoxCast(Vector3 center, Vector3 halfExtents, Quaternion orientation) + { + if (wantedHits == WantedHits.all) + { + RaycastHit[] hitInfos = DrawPhysics.BoxCastAll(center, halfExtents, Get_customVector3_1_inGlobalSpaceUnits(), orientation, used_distance, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (hitInfos != null) ? hitInfos.Length : 0; + } + else + { + bool hasHit = DrawPhysics.BoxCast(center, halfExtents, Get_customVector3_1_inGlobalSpaceUnits(), orientation, used_distance, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = hasHit ? 1 : 0; + } + } + + void SphereCast(Vector3 origin, float radius) + { + if (wantedHits == WantedHits.all) + { + RaycastHit[] hitInfos = DrawPhysics.SphereCastAll(origin, radius, Get_customVector3_1_inGlobalSpaceUnits(), used_distance, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (hitInfos != null) ? hitInfos.Length : 0; + } + else + { + bool hasHit = DrawPhysics.SphereCast(origin, radius, Get_customVector3_1_inGlobalSpaceUnits(), used_distance, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = hasHit ? 1 : 0; + } + } + + void CapsuleCast(Vector3 point1, Vector3 point2, float radius) + { + if (wantedHits == WantedHits.all) + { + RaycastHit[] hitInfos = DrawPhysics.CapsuleCastAll(point1, point2, radius, Get_customVector3_1_inGlobalSpaceUnits(), used_distance, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (hitInfos != null) ? hitInfos.Length : 0; + } + else + { + bool hasHit = DrawPhysics.CapsuleCast(point1, point2, radius, Get_customVector3_1_inGlobalSpaceUnits(), used_distance, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = hasHit ? 1 : 0; + } + } + + void RayCast() + { + if (wantedHits == WantedHits.all) + { + RaycastHit[] hitInfos = DrawPhysics.RaycastAll(GetDrawPos3D_global(), Get_customVector3_1_inGlobalSpaceUnits(), used_distance, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (hitInfos != null) ? hitInfos.Length : 0; + } + else + { + bool hasHit = DrawPhysics.Raycast(GetDrawPos3D_global(), Get_customVector3_1_inGlobalSpaceUnits(), used_distance, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = hasHit ? 1 : 0; + } + } + + void Box_checkRespOverlap(Vector3 center, Vector3 halfExtents, Quaternion orientation) + { + if (wantedHits == WantedHits.all) + { + Collider[] overlappingColliders = DrawPhysics.OverlapBox(center, halfExtents, orientation, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (overlappingColliders != null) ? overlappingColliders.Length : 0; + } + else + { + bool doesOverlap = DrawPhysics.CheckBox(center, halfExtents, orientation, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = doesOverlap ? 1 : 0; + } + } + + void Sphere_checkRespOverlap(Vector3 position, float radius) + { + if (wantedHits == WantedHits.all) + { + Collider[] overlappingColliders = DrawPhysics.OverlapSphere(position, radius, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (overlappingColliders != null) ? overlappingColliders.Length : 0; + } + else + { + bool doesOverlap = DrawPhysics.CheckSphere(position, radius, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = doesOverlap ? 1 : 0; + } + } + + void Capsule_checkRespOverlap(Vector3 point0, Vector3 point1, float radius) + { + if (wantedHits == WantedHits.all) + { + Collider[] overlappingColliders = DrawPhysics.OverlapCapsule(point0, point1, radius, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = (overlappingColliders != null) ? overlappingColliders.Length : 0; + } + else + { + bool doesOverlap = DrawPhysics.CheckCapsule(point0, point1, radius, layerMask, queryTriggerInteraction, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + numberOfFoundHits = doesOverlap ? 1 : 0; + } + } + + public static DrawPhysics.VisualizationQuality Map_saveDrawnLinesType_to_visualizationQuality(SaveDrawnLinesType saveDrawnLinesType_toMap) + { + switch (saveDrawnLinesType_toMap) + { + case SaveDrawnLinesType.no_useFullDetails: + return DrawPhysics.VisualizationQuality.high_withFullDetails; + case SaveDrawnLinesType.useAMidwayTradeoff: + return DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes; + case SaveDrawnLinesType.yes_displayWithLowDetails: + return DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes; + default: + return DrawPhysics.VisualizationQuality.high_withFullDetails; + } + } + + public static SaveDrawnLinesType Map_visualizationQuality_to_saveDrawnLinesType(DrawPhysics.VisualizationQuality visualizationQuality_toMap) + { + switch (visualizationQuality_toMap) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + return SaveDrawnLinesType.no_useFullDetails; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + return SaveDrawnLinesType.useAMidwayTradeoff; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + return SaveDrawnLinesType.yes_displayWithLowDetails; + default: + return SaveDrawnLinesType.no_useFullDetails; + } + } + + static Vector2 GetInitialValueFor_customDirectionForHitResultText() + { + if (UtilitiesDXXL_Math.IsDefaultVector(DrawPhysics.directionOfHitResultText)) + { + return DrawBasics.Default_textOffsetDirection_forPointTags; + } + else + { + return DrawPhysics.directionOfHitResultText; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/PhysicsVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/PhysicsVisualizer.cs.meta new file mode 100644 index 0000000..00f277b --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/PhysicsVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d4a6e766633d01647bdc6ccf6b70f0d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/PositionVisualizer.cs b/Runtime/DrawDebugLibrary/components/PositionVisualizer.cs new file mode 100644 index 0000000..f328bf6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/PositionVisualizer.cs @@ -0,0 +1,80 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Position Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class PositionVisualizer : VisualizerParent + { + + [SerializeField] bool global = false; + [SerializeField] bool local = true; + [SerializeField] bool allParents = false; + + [SerializeField] Color color = DrawBasics.defaultColor; + [SerializeField] [Range(0.0f, 2.0f)] float lineWidth = 0.0f; + + public override void InitializeValues_onceInComponentLifetime() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = "to position of
" + this.gameObject.name; + text_inclGlobalMarkupTags = "to position of
" + this.gameObject.name; + } + hiddenByNearerObjects = false; + } + + public override void InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy() + { + if (transform.parent == null) + { + global = true; + local = false; + } + } + + public override void DrawVisualizedObject() + { + if (global) + { + DrawEngineBasics.Position(transform.position, color, lineWidth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + + if (local) + { + if (transform.parent != null) + { + DrawEngineBasics.Position_local(transform.parent, transform.localPosition, color, lineWidth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + } + + if (allParents) + { + if (transform.parent != null) + { + Transform[] transformsOfParents = transform.parent.GetComponentsInParent(true); + if (transformsOfParents != null) + { + for (int i = 0; i < transformsOfParents.Length; i++) + { + if (transformsOfParents[i] != null) + { + if (transformsOfParents[i].parent == null) + { + DrawEngineBasics.Position(transformsOfParents[i].position, color, lineWidth, null, 0.0f, hiddenByNearerObjects); + } + else + { + DrawEngineBasics.Position_local(transformsOfParents[i].parent, transformsOfParents[i].localPosition, color, lineWidth, null, 0.0f, hiddenByNearerObjects); + } + } + } + } + } + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/PositionVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/PositionVisualizer.cs.meta new file mode 100644 index 0000000..7427d82 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/PositionVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 152263bde55ed984a9c426c6bd27fc46 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/RotationVisualizer.cs b/Runtime/DrawDebugLibrary/components/RotationVisualizer.cs new file mode 100644 index 0000000..44cb1c8 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/RotationVisualizer.cs @@ -0,0 +1,160 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Rotation Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class RotationVisualizer : VisualizerParent + { + public enum RotationType { quaternionGlobal, quaternionLocal, eulerAnglesGlobal, eulerAnglesLocal }; + [SerializeField] RotationType rotationType = RotationType.quaternionGlobal; + RotationType rotationType_before = RotationType.quaternionGlobal; + + [SerializeField] Color color_ofTurnAxis = DrawBasics.defaultColor; + [SerializeField] [Range(0.008f, 0.3f)] float lineWidth = 0.008f; + + [SerializeField] float length_ofUpAndForwardVectors_caseQuaternion = 1.0f; + [SerializeField] float length_ofUpAndForwardVectors_caseEuler = 0.0f; + + //custom rotated vector + [SerializeField] bool drawCustomRotatedVector_caseQuaternion = false; + [SerializeField] bool drawCustomRotatedVector_caseEuler = true; + + [SerializeField] [Range(0.0f, 1.0f)] float alpha_ofSquareSpannedByForwardAndUp = 0.45f; + [SerializeField] public bool useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay = false; + [SerializeField] [Range(0.0f, 1.0f)] float alpha_ofUnrotatedGimbalAxes = 0.06f; + [SerializeField] public float gimbalSize = 1.0f; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToGameobjectName(); + hiddenByNearerObjects = false; + + customVector3Configs[0].source = CustomVector3Source.manualInput; + customVector3Configs[0].clipboardForManualInput = Vector3.one; + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void DrawVisualizedObject() + { + TryChangeCustomVectorInterpretation(); + switch (rotationType) + { + case RotationType.quaternionGlobal: + DrawQuaternion(); + break; + case RotationType.quaternionLocal: + DrawQuaternionLocal(); + break; + case RotationType.eulerAnglesGlobal: + DrawEuler(); + break; + case RotationType.eulerAnglesLocal: + DrawEulerLocal(); + break; + default: + break; + } + } + + void DrawQuaternion() + { + if (drawCustomRotatedVector_caseQuaternion) + { + DrawEngineBasics.QuaternionRotation(this.gameObject.transform.rotation, GetDrawPos3D_global(), Get_customVector3_1_inGlobalSpaceUnits(), length_ofUpAndForwardVectors_caseQuaternion, color_ofTurnAxis, lineWidth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + DrawEngineBasics.QuaternionRotation(this.gameObject.transform.rotation, GetDrawPos3D_global(), default(Vector3), length_ofUpAndForwardVectors_caseQuaternion, color_ofTurnAxis, lineWidth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + } + + void DrawQuaternionLocal() + { + if (drawCustomRotatedVector_caseQuaternion) + { + DrawEngineBasics.QuaternionRotation_local(this.transform.parent, this.gameObject.transform.localRotation, GetDrawPos3D_global(), Get_customVector3_1_inLocalSpaceDefinedByParentUnits(), length_ofUpAndForwardVectors_caseQuaternion, color_ofTurnAxis, lineWidth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + else + { + DrawEngineBasics.QuaternionRotation_local(this.transform.parent, this.gameObject.transform.localRotation, GetDrawPos3D_global(), default(Vector3), length_ofUpAndForwardVectors_caseQuaternion, color_ofTurnAxis, lineWidth, text_inclGlobalMarkupTags, 0.0f, hiddenByNearerObjects); + } + } + + void DrawEuler() + { + string text_inclGlobalMarkupTags_extended; + bool used_useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay; + if (useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay == false) + { + if (transform.parent != null) + { + text_inclGlobalMarkupTags_extended = "[ The transform has a parent, but the angle values from the inspector show the local rotation
-> fallback to values from transform.eulerAngles
-> for further infos see documentation of 'useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay']
" + text_inclGlobalMarkupTags; + used_useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay = true; + } + else + { + text_inclGlobalMarkupTags_extended = text_inclGlobalMarkupTags; + used_useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay = useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay; + } + } + else + { + text_inclGlobalMarkupTags_extended = text_inclGlobalMarkupTags; + used_useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay = useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay; + } + + Vector3 eulerAnglesToDraw = UtilitiesDXXL_Euler.GetEulerAnglesFromNonNullTransform(this.transform, used_useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay, false); + if (drawCustomRotatedVector_caseEuler) + { + DrawEngineBasics.EulerRotation(eulerAnglesToDraw, GetDrawPos3D_global(), Get_customVector3_1_inGlobalSpaceUnits(), length_ofUpAndForwardVectors_caseEuler, alpha_ofSquareSpannedByForwardAndUp, text_inclGlobalMarkupTags_extended, alpha_ofUnrotatedGimbalAxes, gimbalSize, 0.0f, hiddenByNearerObjects); + } + else + { + DrawEngineBasics.EulerRotation(eulerAnglesToDraw, GetDrawPos3D_global(), default(Vector3), length_ofUpAndForwardVectors_caseEuler, alpha_ofSquareSpannedByForwardAndUp, text_inclGlobalMarkupTags_extended, alpha_ofUnrotatedGimbalAxes, gimbalSize, 0.0f, hiddenByNearerObjects); + } + } + + void DrawEulerLocal() + { + Vector3 eulerAnglesToDraw_local = UtilitiesDXXL_Euler.GetEulerAnglesFromNonNullTransform(this.transform, useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay, true); + if (drawCustomRotatedVector_caseEuler) + { + DrawEngineBasics.EulerRotation_local(this.transform.parent, eulerAnglesToDraw_local, GetDrawPos3D_global(), Get_customVector3_1_inLocalSpaceDefinedByParentUnits(), length_ofUpAndForwardVectors_caseEuler, alpha_ofSquareSpannedByForwardAndUp, text_inclGlobalMarkupTags, alpha_ofUnrotatedGimbalAxes, gimbalSize, 0.0f, hiddenByNearerObjects); + } + else + { + DrawEngineBasics.EulerRotation_local(this.transform.parent, eulerAnglesToDraw_local, GetDrawPos3D_global(), default(Vector3), length_ofUpAndForwardVectors_caseEuler, alpha_ofSquareSpannedByForwardAndUp, text_inclGlobalMarkupTags, alpha_ofUnrotatedGimbalAxes, gimbalSize, 0.0f, hiddenByNearerObjects); + } + } + + void TryChangeCustomVectorInterpretation() + { + //-> this implementation is not fit for Unitys build-in undo-functionality + if (rotationType_before != rotationType) + { + switch (rotationType) + { + case RotationType.quaternionGlobal: + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + break; + case RotationType.quaternionLocal: + customVector3Configs[0].vectorInterpretation = VectorInterpretation.localSpaceDefinedByParent; + break; + case RotationType.eulerAnglesGlobal: + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + break; + case RotationType.eulerAnglesLocal: + customVector3Configs[0].vectorInterpretation = VectorInterpretation.localSpaceDefinedByParent; + break; + default: + break; + } + } + rotationType_before = rotationType; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/RotationVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/RotationVisualizer.cs.meta new file mode 100644 index 0000000..4254d88 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/RotationVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e6e564a9e212f1b418c58b7fd155220c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/ScaleVisualizer.cs b/Runtime/DrawDebugLibrary/components/ScaleVisualizer.cs new file mode 100644 index 0000000..ae3b4d1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/ScaleVisualizer.cs @@ -0,0 +1,57 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Scale Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class ScaleVisualizer : VisualizerParent + { + public enum ScaleType { local, global }; + [SerializeField] ScaleType scaleType; + [SerializeField] [Range(0.0f, 0.5f)] float lineWidth = 0.0035f; + [SerializeField] bool drawXDim = true; + [SerializeField] bool drawYDim = true; + [SerializeField] bool drawZDim = true; + [SerializeField] [Range(0.0f, 1.0f)] float relSizeOfPlanes = 0.5f; + [SerializeField] bool force_overwriteColor = false; + [SerializeField] Color overwriteColor = DrawBasics.defaultColor; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToGameobjectName(); + hiddenByNearerObjects = false; + } + + public override void DrawVisualizedObject() + { + SetScaleType(); + Color used_color = force_overwriteColor ? overwriteColor : default(Color); + switch (scaleType) + { + case ScaleType.local: + DrawEngineBasics.LocalScale(GetDrawPos3D_inLocalSpaceAsDefinedByParent(), transform.localScale, transform.parent, transform.localRotation, lineWidth, text_inclGlobalMarkupTags, drawXDim, drawYDim, drawZDim, relSizeOfPlanes, used_color, 0.0f, hiddenByNearerObjects); + break; + case ScaleType.global: + DrawEngineBasics.Scale(GetDrawPos3D_global(), transform.lossyScale, lineWidth, text_inclGlobalMarkupTags, transform.rotation, drawXDim, drawYDim, drawZDim, relSizeOfPlanes, used_color, 0.0f, hiddenByNearerObjects); + break; + default: + break; + } + } + + void SetScaleType() + { + if (transform.parent == null) + { + scaleType = ScaleType.global; + } + else + { + scaleType = ScaleType.local; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/ScaleVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/ScaleVisualizer.cs.meta new file mode 100644 index 0000000..bccbcef --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/ScaleVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 884254c896376a949b4b66db4d8d671f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/ShapeDrawer.cs b/Runtime/DrawDebugLibrary/components/ShapeDrawer.cs new file mode 100644 index 0000000..dbaaafe --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/ShapeDrawer.cs @@ -0,0 +1,1073 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Shape Drawer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class ShapeDrawer : VisualizerParent + { + public enum ShapeCategory { _3D, flat }; + [SerializeField] ShapeCategory shapeCategory = ShapeCategory._3D; + + public enum ShapeType_3D { cube, sphere, capsule, cylinder, extrusion, ellipsoid, pyramid, bipyramid, cone, frustum }; + [SerializeField] ShapeType_3D shapeType_3D = ShapeType_3D.cube; + + public enum ShapeType_flat { circle, ellipse, star, capsule, icon, triangle, square, pentagon, hexagon, septagon, octagon, decagon, regularPolygon, plane, rhombus, dot }; + [SerializeField] ShapeType_flat shapeType_flat = ShapeType_flat.circle; + + public enum ShapeSizeDefinition { relativeToTheGlobalScaleOfTheTransformRespectivelyItsBiggestAbsoluteComponent, absoluteUnits, relativeToTheSceneViewWindowSize, relativeToTheGameViewWindowSize }; + [SerializeField] ShapeSizeDefinition sizeDefinition = ShapeSizeDefinition.relativeToTheGlobalScaleOfTheTransformRespectivelyItsBiggestAbsoluteComponent; + float lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + float biggestAbsGlobalSizeComponentOfTransform = 1.0f; + [SerializeField] bool cameraForSizeDefinitionIsAvailable = false; + Camera gameviewCameraForDrawing; + public enum ShapeAttachedTextsizeReferenceContext { sizeOfShape, globalSpace, sceneViewWindowSize, gameViewWindowSize }; + [SerializeField] ShapeAttachedTextsizeReferenceContext shapeAttachedTextsizeReferenceContext = ShapeAttachedTextsizeReferenceContext.sceneViewWindowSize; + [SerializeField] float textSize_value = 0.1f; + [SerializeField] [Range(0.001f, 0.2f)] float textSize_value_relToScreen = 0.02f; + + public enum PyramidDefinitionVariant { fromCenterOfBasePlane, fromApex, fromCenterOfHullVolume }; + [SerializeField] PyramidDefinitionVariant pyramidDefinitionVariant = PyramidDefinitionVariant.fromCenterOfBasePlane; + + public enum FrustumDefinitionVariant { centerOfBigClipPlanePlusDistanceAndScaleFactorOfSmallPlane, centerOfBigClipPlanePlusDistancesToSmallPlaneAndApex, centersOfBigAndSmallClipPlanes, fromApex, fromCenterOfHullVolume }; + [SerializeField] FrustumDefinitionVariant frustumDefinitionVariant = FrustumDefinitionVariant.centerOfBigClipPlanePlusDistanceAndScaleFactorOfSmallPlane; + + public enum CornerOptionsForIrregularStar { _3, _4, _5, _6, _8, _10, _16, _32, _64 }; + [SerializeField] CornerOptionsForIrregularStar cornerOptionsForIrregularStar = CornerOptionsForIrregularStar._5; + + [SerializeField] public string labelOfPosition = ""; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public string labelOfForwardVector = ""; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public string labelOfUpVector = ""; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool forwardVector_hasHigherPrioThan_upVector; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + //general settings: + [SerializeField] Color color = DrawBasics.defaultColor; + [SerializeField] DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid; + [SerializeField] DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible; + [SerializeField] float shapeFillDensity = 1.0f; + [SerializeField] bool textBlockAboveLine = false; + + //shape specific settings: + [SerializeField] bool force2DShapeTo_facingToSceneViewCam = false; + [SerializeField] bool force2DShapeTo_facingToGameViewCam = false; + [SerializeField] bool coneIsFilled = true; + [SerializeField] bool rhombusPositionDescribesCenterNotCorner = false; + [SerializeField] bool cubeIsFilled = false; + [SerializeField] int segmentsPerSide = 6; + [SerializeField] Color colorOfSidePlanes = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawBasics.defaultColor, 0.5f); + [SerializeField] bool useEdgesColorAsTextColor_ifAvailable = true; + [SerializeField] bool ellipsoidIsNonUniform = false; + [SerializeField] bool flatShapeIsNonUniform = false; + [SerializeField] int struts = 2; + [SerializeField] bool onlyUpperHalf = false; + [SerializeField] bool drawEquator = true; + [SerializeField] DrawShapes.Shape2DType baseShape_withInitialValueOf_circle4struts = DrawShapes.Shape2DType.circle4struts; + [SerializeField] DrawShapes.Shape2DType baseShape_withInitialValueOf_square = DrawShapes.Shape2DType.square; + [SerializeField] [Range(0.0f, 179.99f)] float angleDegVert_initialValueOf90 = 90.0f; + [SerializeField] [Range(0.0f, 179.99f)] float angleDegHoriz_initialValueOf90 = 90.0f; + [SerializeField] [Range(0.0f, 179.99f)] float angleDeg_initialValueOf60 = 60.0f; + [SerializeField] float aspectRatio = (16.0f / 9.0f); + [SerializeField] float scalingFactor_forSmallClipPlane = 0.5f; + [SerializeField] bool flattenRoundLines_intoShapePlane = true; + [SerializeField] bool filledWithSpokes = false; + [SerializeField] float innerRadiusFactor = 0.5f; + [SerializeField] int corners = 5; + [SerializeField] CapsuleDirection2D capusleDirection2D = CapsuleDirection2D.Vertical; + [SerializeField] DrawBasics.IconType iconType = DrawBasics.IconType.car; + [SerializeField] bool iconIsMirroredHorizontally = false; + [SerializeField] bool showAtlasOfAllAvailableIcons = false; + [SerializeField] int subSegments = 10; + [SerializeField] float fixedPlaneStrutDistance = 1.0f; + [SerializeField] float planeAnchorVisualizationSize = 0.0f; + [SerializeField] bool pointer_as_textAttachStyle_forPlanes = false; + [SerializeField] float dotDensity = 1.0f; + public enum PlaneStrutDefinitionType { fixedNumber, fixedWorldSpaceDistance }; + [SerializeField] PlaneStrutDefinitionType planeStrutDefinitionType = PlaneStrutDefinitionType.fixedNumber; + [SerializeField] GameObject extendPlaneToOtherGO; + [SerializeField] bool drawPlumbLine_fromExtentionPosition = true; + public enum SphereQuality { _64_linesPerSphereCircle, _32_linesPerSphereCircle, _16_linesPerSphereCircle, _8_linesPerSphereCircle }; + [SerializeField] SphereQuality sphereQuality = Map_linesPerSphereCircle_to_sphereQuality(DrawShapes.LinesPerSphereCircle); + + //general - scale type dependent: + [SerializeField] ScreenRelativeValue linesWidth = new ScreenRelativeValue(0.0f, 0.0f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue stylePatternScaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + + //shape specific - scale type dependent: + [SerializeField] Vector3 scaleFactors_ofHullVolume = Vector3.one; + [SerializeField] Vector3 scaleFactors_ofHullVolume_relToScreen = 0.1f * Vector3.one; + [SerializeField] ScreenRelativeValue linesWidthOfCubeFillLines = new ScreenRelativeValue(0.0f, 0.0f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue radiusScaleFactor = new ScreenRelativeValue(0.5f, 0.05f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue radiusUpScaleFactor_ellipsoid = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); //-> only difference to "radiusScaleFactor" is the higher initial value, so that the deformation of the sphere shape is visible at first sight. + [SerializeField] ScreenRelativeValue radiusDownScaleFactor_ellipsoid = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); //-> is inconsistent to "heightToDown_scaleFactor" because the inverted direction doesn't need the "minus" here. + [SerializeField] ScreenRelativeValue heightScaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue widthScaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue uniformSizeScaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue width_ofBase_scaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue length_ofBase_scaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue heightToUp_scaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue heightToDown_scaleFactor = new ScreenRelativeValue(-1.0f, -0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue heightOfCapsule3D_scaleFactor = new ScreenRelativeValue(2.0f, 0.2f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue widthOfCapsule2D_scaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue heightOfCapsule2D_scaleFactor = new ScreenRelativeValue(2.0f, 0.2f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue width_ofBigClipPlane_scaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue height_ofBigClipPlane_scaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue width_ofSmallClipPlane_scaleFactor = new ScreenRelativeValue(0.5f, 0.05f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue height_ofSmallClipPlane_scaleFactor = new ScreenRelativeValue(0.5f, 0.05f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue radiusSideward_ofEllipse_scaleFactor = new ScreenRelativeValue(0.25f, 0.025f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue radiusUpward_ofEllipse_scaleFactor = new ScreenRelativeValue(0.5f, 0.05f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue outerRadiusOfStars_scaleFactor = new ScreenRelativeValue(0.5f, 0.05f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue widthOfPlane_scaleFactor = new ScreenRelativeValue(10.0f, 0.25f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue lengthOfPlane_scaleFactor = new ScreenRelativeValue(10.0f, 0.25f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue distanceBetweenClipPlanes_scaleFactor = new ScreenRelativeValue(0.5f, 0.05f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue distance_bigClipPlaneToApex_scaleFactor = new ScreenRelativeValue(1.0f, 0.1f, ScreenRelativeValue.ScaleMode.absolute); + [SerializeField] ScreenRelativeValue distanceApexToNearPlane_scaleFactor = new ScreenRelativeValue(0.5f, 0.05f, ScreenRelativeValue.ScaleMode.absolute); + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + + customVector3Configs[0].picker_isOutfolded = false; + customVector3Configs[0].source = CustomVector3Source.transformsForward; + customVector3Configs[0].clipboardForManualInput = Vector3.forward; + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[1].picker_isOutfolded = false; + customVector3Configs[1].source = CustomVector3Source.transformsUp; + customVector3Configs[1].clipboardForManualInput = Vector3.up; + customVector3Configs[1].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[2].picker_isOutfolded = false; + customVector3Configs[2].source = CustomVector3Source.transformsForward; + customVector3Configs[2].clipboardForManualInput = Vector3.forward; + customVector3Configs[2].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[3].picker_isOutfolded = false; + customVector3Configs[3].source = CustomVector3Source.transformsUp; + customVector3Configs[3].clipboardForManualInput = Vector3.up; + customVector3Configs[3].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void DrawVisualizedObject() + { + ForceNonRhombusOrientationVectorsToLenghtOf1(); + corners = Mathf.Max(3, corners); + struts = Mathf.Max(1, struts); + CacheSizeScaleFactors(); + + switch (shapeCategory) + { + case ShapeCategory._3D: + DrawAThreeDimensionalShape(); + break; + case ShapeCategory.flat: + DrawAFlatShape(); + break; + default: + break; + } + } + + void ForceNonRhombusOrientationVectorsToLenghtOf1() + { + bool isRhombus = ((shapeCategory == ShapeCategory.flat) && (shapeType_flat == ShapeType_flat.rhombus)); + if (isRhombus == false) + { + customVector3Configs[0].hasForcedAbsLength = false; + customVector3Configs[0].lengthRelScaleFactor = 1.0f; + customVector3Configs[1].hasForcedAbsLength = false; + customVector3Configs[1].lengthRelScaleFactor = 1.0f; + } + } + + void CacheSizeScaleFactors() + { + biggestAbsGlobalSizeComponentOfTransform = UtilitiesDXXL_Math.GetBiggestAbsComponent(transform.lossyScale); + cameraForSizeDefinitionIsAvailable = false; + switch (sizeDefinition) + { + case ShapeSizeDefinition.relativeToTheGlobalScaleOfTheTransformRespectivelyItsBiggestAbsoluteComponent: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + case ShapeSizeDefinition.absoluteUnits: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + case ShapeSizeDefinition.relativeToTheSceneViewWindowSize: +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + cameraForSizeDefinitionIsAvailable = true; + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_global() - UnityEditor.SceneView.lastActiveSceneView.camera.transform.position).magnitude; + lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(UnityEditor.SceneView.lastActiveSceneView.camera, distance_ofDrawnObject_toCamera); + } + else + { + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + } +#else + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; +#endif + break; + case ShapeSizeDefinition.relativeToTheGameViewWindowSize: + cameraForSizeDefinitionIsAvailable = UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out gameviewCameraForDrawing, "Shape Drawer Component", false); + if (cameraForSizeDefinitionIsAvailable) + { + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_global() - gameviewCameraForDrawing.transform.position).magnitude; + lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(gameviewCameraForDrawing, distance_ofDrawnObject_toCamera); + } + else + { + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + } + break; + default: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + } + } + + void DrawAThreeDimensionalShape() + { + Set_globalTextSizeSpecs_reversible(); + switch (shapeType_3D) + { + case ShapeType_3D.cube: + labelOfPosition = "Position of cube center"; + labelOfForwardVector = "Forward orientation of cube"; + labelOfUpVector = "Upward orientation of cube"; + forwardVector_hasHigherPrioThan_upVector = true; + if (cubeIsFilled) + { + DrawShapes.CubeFilled(GetDrawPos3D_global(), GetScaledHullSize(), colorOfSidePlanes, GetUpwardVector(), GetForwardVector(), Get_linesWidthOfCubeFillLines(), segmentsPerSide, text_inclGlobalMarkupTags, lineStyle, color, Get_linesWidth(), Get_stylePatternScaleFactor(), useEdgesColorAsTextColor_ifAvailable, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + DrawShapes.Cube(GetDrawPos3D_global(), GetScaledHullSize(), color, GetUpwardVector(), GetForwardVector(), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + break; + case ShapeType_3D.sphere: + labelOfPosition = "Position of sphere center"; + labelOfForwardVector = "Forward orientation of sphere"; + labelOfUpVector = "Upward orientation of sphere"; + forwardVector_hasHigherPrioThan_upVector = false; + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(Map_sphereQuality_to_linesPerSphereCircle(sphereQuality)); + DrawShapes.Sphere(GetDrawPos3D_global(), GetRadius(), color, GetUpwardVector(), GetForwardVector(), Get_linesWidth(), text_inclGlobalMarkupTags, struts, onlyUpperHalf, lineStyle, Get_stylePatternScaleFactor(), !drawEquator, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case ShapeType_3D.capsule: + labelOfPosition = "Position of capsule center"; + labelOfForwardVector = "Forward orientation of capsule"; + labelOfUpVector = "Upward orientation of capsule"; + forwardVector_hasHigherPrioThan_upVector = false; + //-> radius cannot be restricted to be based on only 2 components (e.g. x and z for capsules along z) (as Collider.Capsule does), because the capsuleUpwardVector can be freely chosen and is not restricted to the transform directions + //-> same for "height" + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(Map_sphereQuality_to_linesPerSphereCircle(sphereQuality)); + DrawShapes.Capsule(GetDrawPos3D_global(), GetRadius(), Get_heightOfCapsule3D(), color, GetUpwardVector(), GetForwardVector(), Get_linesWidth(), text_inclGlobalMarkupTags, struts, onlyUpperHalf, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case ShapeType_3D.cylinder: + labelOfPosition = "Position of cylinder center"; + labelOfForwardVector = "Up orientation inside cross section plane"; + labelOfUpVector = "Extrusion direction"; + forwardVector_hasHigherPrioThan_upVector = false; + DrawShapes.Cylinder(GetDrawPos3D_global(), Get_height(), Get_width_ofBase(), Get_length_ofBase(), color, GetUpwardVector(), GetForwardVector(), baseShape_withInitialValueOf_circle4struts, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case ShapeType_3D.extrusion: + labelOfPosition = "Position of extrusion base"; + labelOfForwardVector = "Up orientation inside cross section plane"; + labelOfUpVector = "Extrusion direction"; + forwardVector_hasHigherPrioThan_upVector = false; + DrawShapes.Extrusion(GetDrawPos3D_global(), Get_heightToUp(), Get_heightToDown(), Get_width_ofBase(), Get_length_ofBase(), color, GetUpwardVector(), GetForwardVector(), baseShape_withInitialValueOf_square, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case ShapeType_3D.ellipsoid: + labelOfPosition = "Position of ellipsoid center"; + labelOfForwardVector = "Forward orientation of ellipsoid"; + labelOfUpVector = "Upward orientation of ellipsoid"; + forwardVector_hasHigherPrioThan_upVector = false; + + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(Map_sphereQuality_to_linesPerSphereCircle(sphereQuality)); + if (ellipsoidIsNonUniform) + { + DrawShapes.EllipsoidNonUniform(GetDrawPos3D_global(), 0.5f * Get_width_ofBase(), GetRadiusUp_ellipsoid(), GetRadiusDown_ellipsoid(), 0.5f * Get_length_ofBase(), color, GetUpwardVector(), GetForwardVector(), Get_linesWidth(), text_inclGlobalMarkupTags, struts, lineStyle, Get_stylePatternScaleFactor(), !drawEquator, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + Vector3 radius_forEachDim = new Vector3(0.5f * Get_width_ofBase(), GetRadiusUp_ellipsoid(), 0.5f * Get_length_ofBase()); + DrawShapes.Ellipsoid(GetDrawPos3D_global(), radius_forEachDim, color, GetUpwardVector(), GetForwardVector(), Get_linesWidth(), text_inclGlobalMarkupTags, struts, onlyUpperHalf, lineStyle, Get_stylePatternScaleFactor(), !drawEquator, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case ShapeType_3D.pyramid: + switch (pyramidDefinitionVariant) + { + case PyramidDefinitionVariant.fromCenterOfBasePlane: + labelOfPosition = "Position of center of base plane"; + labelOfForwardVector = "Up orientation inside base plane"; + labelOfUpVector = "Normal of base towards apex"; + forwardVector_hasHigherPrioThan_upVector = false; + DrawShapes.Pyramid(GetDrawPos3D_global(), Get_height(), Get_width_ofBase(), Get_length_ofBase(), color, GetUpwardVector(), GetForwardVector(), baseShape_withInitialValueOf_square, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case PyramidDefinitionVariant.fromApex: + labelOfPosition = "Position of apex"; + labelOfForwardVector = "Forward direction from apex towards base plane"; + labelOfUpVector = "Up orientation inside base plane"; + forwardVector_hasHigherPrioThan_upVector = true; + DrawShapes.Pyramid(GetDrawPos3D_global(), Get_height(), GetForwardVector(), GetUpwardVector(), angleDegVert_initialValueOf90, angleDegHoriz_initialValueOf90, color, baseShape_withInitialValueOf_square, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case PyramidDefinitionVariant.fromCenterOfHullVolume: + labelOfPosition = "Position of center of pyramid hull volume"; + labelOfForwardVector = "Up orientation inside base plane"; + labelOfUpVector = "Normal of base towards apex"; + forwardVector_hasHigherPrioThan_upVector = false; + Quaternion rotation = Quaternion.LookRotation(GetForwardVector(), GetUpwardVector()); + DrawShapes.Pyramid(GetDrawPos3D_global(), GetScaledHullSize(), rotation, color, baseShape_withInitialValueOf_square, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + default: + break; + } + break; + case ShapeType_3D.bipyramid: + labelOfPosition = "Position of center of base plane"; + labelOfForwardVector = "Up orientation inside base plane"; + labelOfUpVector = "Normal of base towards upper apex"; + forwardVector_hasHigherPrioThan_upVector = false; + DrawShapes.Bipyramid(GetDrawPos3D_global(), Get_heightToUp(), Get_heightToDown(), Get_width_ofBase(), Get_length_ofBase(), color, GetUpwardVector(), GetForwardVector(), baseShape_withInitialValueOf_square, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case ShapeType_3D.cone: + if (coneIsFilled) + { + switch (pyramidDefinitionVariant) + { + case PyramidDefinitionVariant.fromCenterOfBasePlane: + labelOfPosition = "Position of center of base circle"; + labelOfForwardVector = "Up orientation inside base circle"; + labelOfUpVector = "Normal of base circle towards apex"; + forwardVector_hasHigherPrioThan_upVector = false; + DrawShapes.ConeFilled(GetDrawPos3D_global(), Get_height(), Get_width_ofBase(), Get_length_ofBase(), color, GetUpwardVector(), GetForwardVector(), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case PyramidDefinitionVariant.fromApex: + labelOfPosition = "Position of apex"; + labelOfForwardVector = "Forward direction from apex towards base circle"; + labelOfUpVector = "Up orientation inside base circle"; + forwardVector_hasHigherPrioThan_upVector = true; + DrawShapes.ConeFilled(GetDrawPos3D_global(), Get_height(), GetForwardVector(), GetUpwardVector(), angleDegVert_initialValueOf90, angleDegHoriz_initialValueOf90, color, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case PyramidDefinitionVariant.fromCenterOfHullVolume: + labelOfPosition = "Position of center of cone hull volume"; + labelOfForwardVector = "Up orientation inside base circle"; + labelOfUpVector = "Normal of base circle towards apex"; + forwardVector_hasHigherPrioThan_upVector = false; + Quaternion rotation = Quaternion.LookRotation(GetForwardVector(), GetUpwardVector()); + DrawShapes.ConeFilled(GetDrawPos3D_global(), GetScaledHullSize(), rotation, color, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + default: + break; + } + } + else + { + switch (pyramidDefinitionVariant) + { + case PyramidDefinitionVariant.fromCenterOfBasePlane: + labelOfPosition = "Position of center of base circle"; + labelOfForwardVector = "Up orientation inside base circle"; + labelOfUpVector = "Normal of base circle towards apex"; + forwardVector_hasHigherPrioThan_upVector = false; + DrawShapes.Cone(GetDrawPos3D_global(), Get_height(), Get_width_ofBase(), Get_length_ofBase(), color, GetUpwardVector(), GetForwardVector(), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case PyramidDefinitionVariant.fromApex: + labelOfPosition = "Position of apex"; + labelOfForwardVector = "Forward direction from apex towards base circle"; + labelOfUpVector = "Up orientation inside base circle"; + forwardVector_hasHigherPrioThan_upVector = true; + DrawShapes.Cone(GetDrawPos3D_global(), Get_height(), GetForwardVector(), GetUpwardVector(), angleDegVert_initialValueOf90, angleDegHoriz_initialValueOf90, color, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case PyramidDefinitionVariant.fromCenterOfHullVolume: + labelOfPosition = "Position of center of cone hull volume"; + labelOfForwardVector = "Up orientation inside base circle"; + labelOfUpVector = "Normal of base circle towards apex"; + forwardVector_hasHigherPrioThan_upVector = false; + Quaternion rotation = Quaternion.LookRotation(GetForwardVector(), GetUpwardVector()); + DrawShapes.Cone(GetDrawPos3D_global(), GetScaledHullSize(), rotation, color, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + default: + break; + } + } + break; + case ShapeType_3D.frustum: + switch (frustumDefinitionVariant) + { + case FrustumDefinitionVariant.centerOfBigClipPlanePlusDistanceAndScaleFactorOfSmallPlane: + labelOfPosition = "Position of center of big clip plane"; + labelOfForwardVector = "Up orientation inside clip plane"; + labelOfUpVector = "Normal of clip plane towards apex"; + forwardVector_hasHigherPrioThan_upVector = false; + DrawShapes.Frustum(GetDrawPos3D_global(), Get_distanceBetweenClipPlanes(), scalingFactor_forSmallClipPlane, GetUpwardVector(), GetForwardVector(), Get_width_ofBigClipPlane(), Get_height_ofBigClipPlane(), color, baseShape_withInitialValueOf_square, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case FrustumDefinitionVariant.centerOfBigClipPlanePlusDistancesToSmallPlaneAndApex: + labelOfPosition = "Position of center of big clip plane"; + labelOfForwardVector = "Up orientation inside clip plane"; + labelOfUpVector = "Normal of clip plane towards apex"; + forwardVector_hasHigherPrioThan_upVector = false; + DrawShapes.Frustum(Get_distance_bigClipPlaneToApex(), Get_distanceBetweenClipPlanes(), GetDrawPos3D_global(), GetUpwardVector(), GetForwardVector(), Get_width_ofBigClipPlane(), Get_height_ofBigClipPlane(), color, baseShape_withInitialValueOf_square, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case FrustumDefinitionVariant.centersOfBigAndSmallClipPlanes: + labelOfPosition = "Position of center of big clip plane"; + labelOfForwardVector = "Up orientation inside clip planes"; + labelOfUpVector = "Fallback for normal of clip planes towards apex"; + forwardVector_hasHigherPrioThan_upVector = true; + DrawShapes.Frustum(GetDrawPos3D_global(), GetDrawPos3D_ofPartnerGameobject_global(), Get_width_ofBigClipPlane(), Get_height_ofBigClipPlane(), Get_width_ofSmallClipPlane(), Get_height_ofSmallClipPlane(), color, GetForwardVector(), GetUpwardVector(), baseShape_withInitialValueOf_square, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case FrustumDefinitionVariant.fromApex: + labelOfPosition = "Position of apex"; + labelOfForwardVector = "Forward direction from apex towards clip planes"; + labelOfUpVector = "Up orientation inside clip planes"; + forwardVector_hasHigherPrioThan_upVector = true; + DrawShapes.Frustum(GetDrawPos3D_global(), GetForwardVector(), GetUpwardVector(), angleDeg_initialValueOf60, aspectRatio, Get_distanceApexToNearPlane(), Get_distance_bigClipPlaneToApex(), color, baseShape_withInitialValueOf_square, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + case FrustumDefinitionVariant.fromCenterOfHullVolume: + labelOfPosition = "Position of center of frustums hull volume"; + labelOfForwardVector = "Up orientation inside clip planes"; + labelOfUpVector = "Normal of clip planes towards apex"; + forwardVector_hasHigherPrioThan_upVector = false; + Quaternion rotation = Quaternion.LookRotation(GetForwardVector(), GetUpwardVector()); + DrawShapes.Frustum(GetDrawPos3D_global(), GetScaledHullSize(), rotation, scalingFactor_forSmallClipPlane, color, baseShape_withInitialValueOf_square, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + break; + default: + break; + } + break; + default: + break; + } + Reverse_globalTextSizeSpecs(); + } + + void DrawAFlatShape() + { + switch (shapeType_flat) + { + case ShapeType_flat.circle: + labelOfPosition = "Position of circle center"; + labelOfForwardVector = "Normal of circle plane"; + labelOfUpVector = "Upward orientation inside circle plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + if (flatShapeIsNonUniform) + { + DrawShapes.FlatShape(GetDrawPos3D_global(), DrawShapes.Shape2DType.circle, Get_width(), Get_height(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + DrawShapes.Circle(GetDrawPos3D_global(), GetRadius(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.ellipse: + labelOfPosition = "Position of ellipse center"; + labelOfForwardVector = "Normal of ellipse plane"; + labelOfUpVector = "Upward orientation inside ellipse plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawShapes.Ellipse(GetDrawPos3D_global(), Get_radiusSideward_ofEllipse(), Get_radiusUpward_ofEllipse(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.star: + labelOfPosition = "Position of star center"; + labelOfForwardVector = "Normal of star plane"; + labelOfUpVector = "Upward orientation inside star plane"; + forwardVector_hasHigherPrioThan_upVector = true; + Set_globalTextSizeSpecs_reversible(); + if (flatShapeIsNonUniform) + { + DrawShapes.FlatShape(GetDrawPos3D_global(), Get_shape2DType_forIrregularStar(cornerOptionsForIrregularStar), Get_width(), Get_height(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), flattenRoundLines_intoShapePlane, DrawBasics.LineStyle.invisible, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + DrawShapes.Star(GetDrawPos3D_global(), Get_outerRadiusOfStars(), color, corners, innerRadiusFactor, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.capsule: + labelOfPosition = "Position of capsule center"; + labelOfForwardVector = "Normal of capsule plane"; + labelOfUpVector = "Upward orientation inside capsule plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawShapes.FlatCapsule(GetDrawPos3D_global(), Get_widthOfCapsule2D(), Get_heightOfCapsule2D(), color, GetForwardVector(true), GetUpwardVector(true), capusleDirection2D, Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.icon: + labelOfPosition = "Position of icon center"; + labelOfForwardVector = "Normal of icon plane"; + labelOfUpVector = "Upward orientation inside icon plane"; + forwardVector_hasHigherPrioThan_upVector = true; + float uniformSize = Get_uniformSize(); + int strokeWidth_asPPMofSize = 0; + if ((UtilitiesDXXL_Math.ApproximatelyZero(uniformSize) == false) && (UtilitiesDXXL_Math.ApproximatelyZero(Get_linesWidth()) == false)) + { + strokeWidth_asPPMofSize = (int)(1000000.0f * (Get_linesWidth() / uniformSize)); + } + DrawBasics.Icon(GetDrawPos3D_global(), iconType, color, uniformSize, text_inclGlobalMarkupTags, GetForwardVector(true), GetUpwardVector(true), strokeWidth_asPPMofSize, iconIsMirroredHorizontally, 0.0f, hiddenByNearerObjects); + + if (showAtlasOfAllAvailableIcons) + { + DrawBasics.DrawAtlasOfAllIconsWithTheirNames(GetDrawPos3D_global(), default(Color), default(Color), true, biggestAbsGlobalSizeComponentOfTransform); + } + break; + case ShapeType_flat.triangle: + labelOfPosition = "Position of triangle center"; + labelOfForwardVector = "Normal of triangle plane"; + labelOfUpVector = "Upward orientation inside triangle plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + if (flatShapeIsNonUniform) + { + DrawShapes.FlatShape(GetDrawPos3D_global(), DrawShapes.Shape2DType.triangle, Get_width(), Get_height(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + DrawShapes.Triangle(GetDrawPos3D_global(), GetRadius(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.square: + labelOfPosition = "Position of square center"; + labelOfForwardVector = "Normal of square plane"; + labelOfUpVector = "Upward orientation inside square plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + if (flatShapeIsNonUniform) + { + DrawShapes.FlatShape(GetDrawPos3D_global(), DrawShapes.Shape2DType.square, Get_width(), Get_height(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + DrawShapes.Square(GetDrawPos3D_global(), Get_uniformSize(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.pentagon: + labelOfPosition = "Position of pentagon center"; + labelOfForwardVector = "Normal of pentagon plane"; + labelOfUpVector = "Upward orientation inside pentagon plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + if (flatShapeIsNonUniform) + { + DrawShapes.FlatShape(GetDrawPos3D_global(), DrawShapes.Shape2DType.pentagon, Get_width(), Get_height(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + DrawShapes.Pentagon(GetDrawPos3D_global(), GetRadius(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.hexagon: + labelOfPosition = "Position of hexagon center"; + labelOfForwardVector = "Normal of hexagon plane"; + labelOfUpVector = "Upward orientation inside hexagon plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + if (flatShapeIsNonUniform) + { + DrawShapes.FlatShape(GetDrawPos3D_global(), DrawShapes.Shape2DType.hexagon, Get_width(), Get_height(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + DrawShapes.Hexagon(GetDrawPos3D_global(), GetRadius(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.septagon: + labelOfPosition = "Position of septagon center"; + labelOfForwardVector = "Normal of septagon plane"; + labelOfUpVector = "Upward orientation inside septagon plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + if (flatShapeIsNonUniform) + { + DrawShapes.FlatShape(GetDrawPos3D_global(), DrawShapes.Shape2DType.septagon, Get_width(), Get_height(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + DrawShapes.Septagon(GetDrawPos3D_global(), GetRadius(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.octagon: + labelOfPosition = "Position of octagon center"; + labelOfForwardVector = "Normal of octagon plane"; + labelOfUpVector = "Upward orientation inside octagon plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + if (flatShapeIsNonUniform) + { + DrawShapes.FlatShape(GetDrawPos3D_global(), DrawShapes.Shape2DType.octagon, Get_width(), Get_height(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + DrawShapes.Octagon(GetDrawPos3D_global(), GetRadius(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.decagon: + labelOfPosition = "Position of decagon center"; + labelOfForwardVector = "Normal of decagon plane"; + labelOfUpVector = "Upward orientation inside decagon plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + if (flatShapeIsNonUniform) + { + DrawShapes.FlatShape(GetDrawPos3D_global(), DrawShapes.Shape2DType.decagon, Get_width(), Get_height(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), flattenRoundLines_intoShapePlane, fillStyle, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + else + { + DrawShapes.Decagon(GetDrawPos3D_global(), GetRadius(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + } + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.regularPolygon: + labelOfPosition = "Position of polygon center"; + labelOfForwardVector = "Normal of polygon plane"; + labelOfUpVector = "Upward orientation inside polygon plane"; + forwardVector_hasHigherPrioThan_upVector = true; + + Set_globalTextSizeSpecs_reversible(); + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + DrawShapes.RegularPolygon(corners, GetDrawPos3D_global(), GetRadius(), color, GetForwardVector(true), GetUpwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, lineStyle, Get_stylePatternScaleFactor(), fillStyle, filledWithSpokes, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.plane: + //-> meaning of "up" and "forward" is inconsistent to the polygon shapes above to fit the default orientation of a plane mesh on transforms + labelOfPosition = "Position of plane center"; + labelOfForwardVector = "Forward orientation inside plane"; + labelOfUpVector = "Normal of plane"; + forwardVector_hasHigherPrioThan_upVector = false; + + float subSegments_signFlipsInterpretation = (planeStrutDefinitionType == PlaneStrutDefinitionType.fixedWorldSpaceDistance) ? (-fixedPlaneStrutDistance) : subSegments; + Vector3 planeAreaExtentionPosition = (extendPlaneToOtherGO == null) ? default(Vector3) : extendPlaneToOtherGO.transform.position; + + Set_globalTextSizeSpecs_reversible(); //is only used by planes if "pointer_as_textAttachStyle_forPlanes == true", but does not harm in other cases + DrawShapes.Plane(GetDrawPos3D_global(), GetUpwardVector(true), planeAreaExtentionPosition, color, Get_widthOfPlane(), Get_lengthOfPlane(), GetForwardVector(true), Get_linesWidth(), text_inclGlobalMarkupTags, subSegments_signFlipsInterpretation, pointer_as_textAttachStyle_forPlanes, planeAnchorVisualizationSize, drawPlumbLine_fromExtentionPosition, lineStyle, Get_stylePatternScaleFactor(), textBlockAboveLine, 0.0f, hiddenByNearerObjects); + Reverse_globalTextSizeSpecs(); + break; + case ShapeType_flat.rhombus: + if (rhombusPositionDescribesCenterNotCorner) + { + labelOfPosition = "Position of rhombus center"; + labelOfForwardVector = "Rhombus edge 1"; + labelOfUpVector = "Rhombus edge 2"; + forwardVector_hasHigherPrioThan_upVector = true; + DrawShapes.RhombusAroundCenter(GetDrawPos3D_global(), Get_customVector3_1_inGlobalSpaceUnits(), Get_customVector3_2_inGlobalSpaceUnits(), color, Get_linesWidth(), text_inclGlobalMarkupTags, subSegments, lineStyle, Get_stylePatternScaleFactor(), 0.0f, hiddenByNearerObjects); + } + else + { + labelOfPosition = "Position of start corner"; + labelOfForwardVector = "Rhombus edge 1"; + labelOfUpVector = "Rhombus edge 2"; + forwardVector_hasHigherPrioThan_upVector = true; + DrawShapes.Rhombus(GetDrawPos3D_global(), Get_customVector3_1_inGlobalSpaceUnits(), Get_customVector3_2_inGlobalSpaceUnits(), color, Get_linesWidth(), text_inclGlobalMarkupTags, subSegments, lineStyle, Get_stylePatternScaleFactor(), 0.0f, hiddenByNearerObjects); + } + break; + case ShapeType_flat.dot: + labelOfPosition = "Position of dot center"; + labelOfForwardVector = "Normal of Dot"; + labelOfUpVector = "Upward orientation inside dot plane"; //not used + forwardVector_hasHigherPrioThan_upVector = true; + DrawBasics.Dot(GetDrawPos3D_global(), 0.5f * Get_uniformSize(), GetForwardVector(true), color, text_inclGlobalMarkupTags, dotDensity, 0.0f, hiddenByNearerObjects); + break; + default: + break; + } + } + + Vector3 GetForwardVector(bool tryUseFallbacksForForcingToObserverCam = false) + { + if (tryUseFallbacksForForcingToObserverCam) + { + if (force2DShapeTo_facingToSceneViewCam || force2DShapeTo_facingToGameViewCam) + { + return Get_customVector3_3_inGlobalSpaceUnits(); + } + else + { + return Get_customVector3_1_inGlobalSpaceUnits(); + } + } + else + { + return Get_customVector3_1_inGlobalSpaceUnits(); + } + } + + Vector3 GetUpwardVector(bool tryUseFallbacksForForcingToObserverCam = false) + { + if (tryUseFallbacksForForcingToObserverCam) + { + if (force2DShapeTo_facingToSceneViewCam || force2DShapeTo_facingToGameViewCam) + { + return Get_customVector3_4_inGlobalSpaceUnits(); + } + else + { + return Get_customVector3_2_inGlobalSpaceUnits(); + } + } + else + { + return Get_customVector3_2_inGlobalSpaceUnits(); + } + } + + Vector3 GetScaledHullSize() + { + if (sizeDefinition == ShapeSizeDefinition.relativeToTheGlobalScaleOfTheTransformRespectivelyItsBiggestAbsoluteComponent) + { + return Vector3.Scale(transform.lossyScale, scaleFactors_ofHullVolume); + } + else + { + float scaled_x = ScaleInputFloat_accordingToSizeDefinition(scaleFactors_ofHullVolume_relToScreen.x, scaleFactors_ofHullVolume.x); + float scaled_y = ScaleInputFloat_accordingToSizeDefinition(scaleFactors_ofHullVolume_relToScreen.y, scaleFactors_ofHullVolume.y); + float scaled_z = ScaleInputFloat_accordingToSizeDefinition(scaleFactors_ofHullVolume_relToScreen.z, scaleFactors_ofHullVolume.z); + return new Vector3(scaled_x, scaled_y, scaled_z); + } + } + + float GetRadius() + { + return ScaleInputFloat_accordingToSizeDefinition(radiusScaleFactor); + } + + float GetRadiusUp_ellipsoid() + { + return ScaleInputFloat_accordingToSizeDefinition(radiusUpScaleFactor_ellipsoid); + } + + float GetRadiusDown_ellipsoid() + { + return ScaleInputFloat_accordingToSizeDefinition(radiusDownScaleFactor_ellipsoid); + } + + float Get_height() + { + return ScaleInputFloat_accordingToSizeDefinition(heightScaleFactor); + } + + float Get_width() + { + return ScaleInputFloat_accordingToSizeDefinition(widthScaleFactor); + } + + float Get_uniformSize() + { + return ScaleInputFloat_accordingToSizeDefinition(uniformSizeScaleFactor); + } + + float Get_width_ofBase() + { + return ScaleInputFloat_accordingToSizeDefinition(width_ofBase_scaleFactor); + } + + float Get_length_ofBase() + { + return ScaleInputFloat_accordingToSizeDefinition(length_ofBase_scaleFactor); + } + + float Get_heightToUp() + { + return ScaleInputFloat_accordingToSizeDefinition(heightToUp_scaleFactor); + } + + float Get_heightToDown() + { + return ScaleInputFloat_accordingToSizeDefinition(heightToDown_scaleFactor); + } + + float Get_width_ofBigClipPlane() + { + return ScaleInputFloat_accordingToSizeDefinition(width_ofBigClipPlane_scaleFactor); + } + + float Get_height_ofBigClipPlane() + { + return ScaleInputFloat_accordingToSizeDefinition(height_ofBigClipPlane_scaleFactor); + } + + float Get_width_ofSmallClipPlane() + { + return ScaleInputFloat_accordingToSizeDefinition(width_ofSmallClipPlane_scaleFactor); + } + + float Get_height_ofSmallClipPlane() + { + return ScaleInputFloat_accordingToSizeDefinition(height_ofSmallClipPlane_scaleFactor); + } + + float Get_distanceBetweenClipPlanes() + { + return ScaleInputFloat_accordingToSizeDefinition(distanceBetweenClipPlanes_scaleFactor); + } + + float Get_distance_bigClipPlaneToApex() + { + return ScaleInputFloat_accordingToSizeDefinition(distance_bigClipPlaneToApex_scaleFactor); + } + + float Get_distanceApexToNearPlane() + { + return ScaleInputFloat_accordingToSizeDefinition(distanceApexToNearPlane_scaleFactor); + } + + float Get_radiusSideward_ofEllipse() + { + return ScaleInputFloat_accordingToSizeDefinition(radiusSideward_ofEllipse_scaleFactor); + } + + float Get_radiusUpward_ofEllipse() + { + return ScaleInputFloat_accordingToSizeDefinition(radiusUpward_ofEllipse_scaleFactor); + } + + float Get_outerRadiusOfStars() + { + return ScaleInputFloat_accordingToSizeDefinition(outerRadiusOfStars_scaleFactor); + } + + float Get_widthOfPlane() + { + return ScaleInputFloat_accordingToSizeDefinition(widthOfPlane_scaleFactor); + } + + float Get_lengthOfPlane() + { + return ScaleInputFloat_accordingToSizeDefinition(lengthOfPlane_scaleFactor); + } + + float Get_linesWidth() + { + return ScaleInputFloat_accordingToSizeDefinition(linesWidth); + } + + float Get_linesWidthOfCubeFillLines() + { + return ScaleInputFloat_accordingToSizeDefinition(linesWidthOfCubeFillLines); + } + + float Get_stylePatternScaleFactor() + { + float stylePatternScaleFactor_unclamped = ScaleInputFloat_accordingToSizeDefinition(stylePatternScaleFactor); + return Mathf.Max(stylePatternScaleFactor_unclamped, UtilitiesDXXL_LineStyles.minStylePatternScaleFactor); + } + + float Get_heightOfCapsule3D() + { + return ScaleInputFloat_accordingToSizeDefinition(heightOfCapsule3D_scaleFactor); + } + + float Get_widthOfCapsule2D() + { + return ScaleInputFloat_accordingToSizeDefinition(widthOfCapsule2D_scaleFactor); + } + + float Get_heightOfCapsule2D() + { + return ScaleInputFloat_accordingToSizeDefinition(heightOfCapsule2D_scaleFactor); + } + + float ScaleInputFloat_accordingToSizeDefinition(float inputFloatToScale_versionThatIsRelToScreen, float inputFloatToScale) + { + switch (sizeDefinition) + { + case ShapeSizeDefinition.relativeToTheGlobalScaleOfTheTransformRespectivelyItsBiggestAbsoluteComponent: + return biggestAbsGlobalSizeComponentOfTransform * inputFloatToScale; + case ShapeSizeDefinition.absoluteUnits: + return inputFloatToScale; + case ShapeSizeDefinition.relativeToTheSceneViewWindowSize: + if (cameraForSizeDefinitionIsAvailable) + { + return lengthOfScreenDiagonal_atDrawnObjectsPosition * inputFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputFloatToScale; + } + case ShapeSizeDefinition.relativeToTheGameViewWindowSize: + if (cameraForSizeDefinitionIsAvailable) + { + return lengthOfScreenDiagonal_atDrawnObjectsPosition * inputFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputFloatToScale; + } + default: + return inputFloatToScale; + } + } + + float ScaleInputFloat_accordingToSizeDefinition(ScreenRelativeValue value) + { + return ScaleInputFloat_accordingToSizeDefinition(value.relativeToScreen, value.absolute); + } + + float forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before; + float forcedConstantWorldspaceTextSize_forTextAtShapes_before; + DrawBasics.CameraForAutomaticOrientation cameraForAutomaticOrientation_before; + DrawText.AutomaticTextOrientation automaticTextOrientation_before; + void Set_globalTextSizeSpecs_reversible() + { + forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before = DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes; + forcedConstantWorldspaceTextSize_forTextAtShapes_before = DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes; + cameraForAutomaticOrientation_before = DrawBasics.cameraForAutomaticOrientation; + automaticTextOrientation_before = DrawText.automaticTextOrientation; + + if (sizeDefinition == ShapeSizeDefinition.relativeToTheSceneViewWindowSize) + { + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + DrawText.automaticTextOrientation = DrawText.AutomaticTextOrientation.screen; + } + else + { + if (sizeDefinition == ShapeSizeDefinition.relativeToTheGameViewWindowSize) + { + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + DrawText.automaticTextOrientation = DrawText.AutomaticTextOrientation.screen; + } + else + { + switch (shapeAttachedTextsizeReferenceContext) + { + case ShapeAttachedTextsizeReferenceContext.sizeOfShape: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = 0.0f; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + break; + case ShapeAttachedTextsizeReferenceContext.globalSpace: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = 0.0f; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = textSize_value; + break; + case ShapeAttachedTextsizeReferenceContext.sceneViewWindowSize: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = textSize_value_relToScreen; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + DrawText.automaticTextOrientation = DrawText.AutomaticTextOrientation.screen; + break; + case ShapeAttachedTextsizeReferenceContext.gameViewWindowSize: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = textSize_value_relToScreen; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + DrawText.automaticTextOrientation = DrawText.AutomaticTextOrientation.screen; + break; + default: + break; + } + } + } + } + + void Reverse_globalTextSizeSpecs() + { + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = forcedConstantWorldspaceTextSize_forTextAtShapes_before; + DrawBasics.cameraForAutomaticOrientation = cameraForAutomaticOrientation_before; + DrawText.automaticTextOrientation = automaticTextOrientation_before; + } + + public static DrawShapes.Shape2DType Get_shape2DType_forIrregularStar(CornerOptionsForIrregularStar cornerOptionsForIrregularStar) + { + switch (cornerOptionsForIrregularStar) + { + case CornerOptionsForIrregularStar._3: + return DrawShapes.Shape2DType.star3; + case CornerOptionsForIrregularStar._4: + return DrawShapes.Shape2DType.star4; + case CornerOptionsForIrregularStar._5: + return DrawShapes.Shape2DType.star5; + case CornerOptionsForIrregularStar._6: + return DrawShapes.Shape2DType.star6; + case CornerOptionsForIrregularStar._8: + return DrawShapes.Shape2DType.star8; + case CornerOptionsForIrregularStar._10: + return DrawShapes.Shape2DType.star10; + case CornerOptionsForIrregularStar._16: + return DrawShapes.Shape2DType.star16; + case CornerOptionsForIrregularStar._32: + return DrawShapes.Shape2DType.star32; + case CornerOptionsForIrregularStar._64: + return DrawShapes.Shape2DType.star64; + default: + return DrawShapes.Shape2DType.star5; + } + } + + public static int Map_sphereQuality_to_linesPerSphereCircle(SphereQuality sphereQuality_toMap) + { + switch (sphereQuality_toMap) + { + case SphereQuality._64_linesPerSphereCircle: + return 64; + case SphereQuality._32_linesPerSphereCircle: + return 32; + case SphereQuality._16_linesPerSphereCircle: + return 16; + case SphereQuality._8_linesPerSphereCircle: + return 8; + default: + return 64; + } + } + + public static SphereQuality Map_linesPerSphereCircle_to_sphereQuality(int linesPerSphereCircle_toMap) + { + switch (linesPerSphereCircle_toMap) + { + case 64: + return SphereQuality._64_linesPerSphereCircle; + case 32: + return SphereQuality._32_linesPerSphereCircle; + case 16: + return SphereQuality._16_linesPerSphereCircle; + case 8: + return SphereQuality._8_linesPerSphereCircle; + default: + Debug.LogError("'linesPerSphereCircle' has to be 64, 32, 16, or 8."); + return SphereQuality._64_linesPerSphereCircle; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/ShapeDrawer.cs.meta b/Runtime/DrawDebugLibrary/components/ShapeDrawer.cs.meta new file mode 100644 index 0000000..53479a7 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/ShapeDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 137430c027a94114d824e41341e8d161 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/TagDrawer.cs b/Runtime/DrawDebugLibrary/components/TagDrawer.cs new file mode 100644 index 0000000..395599a --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/TagDrawer.cs @@ -0,0 +1,355 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Tag Drawer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class TagDrawer : VisualizerParent + { + public enum TagStyle { pointer, boxed }; + [SerializeField] TagStyle tagStyle = TagStyle.pointer; + + public enum PointerSizeInterpretation { absoluteUnits, relativeToGameobjectSize, relativeToTheSceneViewWindowSize, relativeToTheGameViewWindowSize }; + [SerializeField] PointerSizeInterpretation pointerSizeInterpretation = PointerSizeInterpretation.absoluteUnits; + float lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + float biggestAbsGlobalSizeComponentOfTransform = 1.0f; + [SerializeField] bool cameraForSizeDefinitionIsAvailable = false; + Camera gameviewCameraForDrawing; + + public enum AttachedTextsizeReferenceContext { extentOfTag, globalSpace, sceneViewWindowSize, gameViewWindowSize }; + [SerializeField] AttachedTextsizeReferenceContext attachedTextsizeReferenceContext = AttachedTextsizeReferenceContext.sceneViewWindowSize; + + //both styles: + [SerializeField] float linesWidth = 0.0f; + [SerializeField] [Range(0.0f, 0.02f)] float linesWidth_relToScreen = 0.0f; + [SerializeField] Color colorForText = DrawBasics.defaultColor; + + //pointer style: + [SerializeField] public bool textOffsetDistance_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] float textOffsetDistance = 1.0f; + [SerializeField] [Range(0.0025f, 0.3f)] float textOffsetDistance_relToScreen = 0.1f; + [SerializeField] float textSize_value = 0.1f; + [SerializeField] [Range(0.001f, 0.2f)] float textSize_value_relToScreen = 0.01f; + [SerializeField] bool forcePointerDirection = false; + [SerializeField] bool skipConeDrawing = false; + + //pointer style (coordinates): + [SerializeField] bool drawGlobalCoordinates = false; + [SerializeField] bool drawLocalCoordinates = false; + [SerializeField] float sizeOfMarkingCross = 1.0f; + [SerializeField] [Range(0.0f, 1.0f)] float strokeWidth_forCoordinateTexts_onPointVisualiation_in0to1 = 0.0f; + [SerializeField] [Range(0.005f, 1.0f)] float sizeOfMarkingCross_relToScreen = 0.15f; + + //boxed style + [SerializeField] bool encapsulateChildren = true; + [SerializeField] bool textBlockAboveLine = false; + [SerializeField] bool differentBoxColor = false; + [SerializeField] Color differentBoxColor_value = UtilitiesDXXL_Colors.violet; + + public override void InitializeValues_onceInComponentLifetime() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = "tag text of " + this.gameObject.name; + text_inclGlobalMarkupTags = "tag text of " + this.gameObject.name; + } + textSection_isOutfolded = true; + + customVector3Configs[0].source = CustomVector3Source.manualInput; + customVector3Configs[0].clipboardForManualInput = (-DrawBasics.Default_textOffsetDirection_forPointTags); + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void DrawVisualizedObject() + { + UtilitiesDXXL_Text.Set_automaticTextOrientation_reversible(DrawText.AutomaticTextOrientation.screen); + UtilitiesDXXL_DrawBasics.Set_cameraForAutomaticOrientation_reversible(Get_cameraForAutomaticOrientation()); + try + { + DrawTag(); + } + catch { } + UtilitiesDXXL_Text.Reverse_automaticTextOrientation(); + UtilitiesDXXL_DrawBasics.Reverse_cameraForAutomaticOrientation(); + } + + void DrawTag() + { + switch (tagStyle) + { + case TagStyle.pointer: + CacheSizeScaleFactors(); + Vector3 drawPos3D_global = GetDrawPos3D_global(); + TryDrawCoordinates(drawPos3D_global); + Vector3 used_textOffsetDir = forcePointerDirection ? (-Get_customVector3_1_inGlobalSpaceUnits()) : Vector3.zero; + float used_linesWidth = ScaleInputFloat_accordingToSizeDefinition(linesWidth_relToScreen, linesWidth); + float used_textOffsetDistance_unclamped = ScaleInputFloat_accordingToSizeDefinition(textOffsetDistance_relToScreen, textOffsetDistance); + float used_textOffsetDistance = UtilitiesDXXL_DrawBasics.GetClamped_pointTagSize_asTextOffsetDistance(used_textOffsetDistance_unclamped, used_linesWidth); + float used_relTextSizeScaling = Get_used_relTextSizeScaling(used_textOffsetDistance); + DrawBasics.PointTag(drawPos3D_global, text_inclGlobalMarkupTags, colorForText, used_linesWidth, used_textOffsetDistance, used_textOffsetDir, used_relTextSizeScaling, skipConeDrawing, 0.0f, hiddenByNearerObjects); + break; + case TagStyle.boxed: + Color used_colorForBox = differentBoxColor ? differentBoxColor_value : colorForText; + float used_textSize = Set_globalTextSizeSpecs_reversible(); + DrawEngineBasics.TagGameObject(this.gameObject, text_inclGlobalMarkupTags, colorForText, used_colorForBox, used_textSize, linesWidth, encapsulateChildren, textBlockAboveLine, 0.0f, hiddenByNearerObjects); + Reverse_globalTextSizeSpecs(); + break; + default: + break; + } + } + + void CacheSizeScaleFactors() + { + biggestAbsGlobalSizeComponentOfTransform = UtilitiesDXXL_Math.GetBiggestAbsComponent(transform.lossyScale); + cameraForSizeDefinitionIsAvailable = false; + switch (pointerSizeInterpretation) + { + case PointerSizeInterpretation.absoluteUnits: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + case PointerSizeInterpretation.relativeToGameobjectSize: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + case PointerSizeInterpretation.relativeToTheSceneViewWindowSize: +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + cameraForSizeDefinitionIsAvailable = true; + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_global() - UnityEditor.SceneView.lastActiveSceneView.camera.transform.position).magnitude; + lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(UnityEditor.SceneView.lastActiveSceneView.camera, distance_ofDrawnObject_toCamera); + } + else + { + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + } +#else + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; +#endif + break; + case PointerSizeInterpretation.relativeToTheGameViewWindowSize: + cameraForSizeDefinitionIsAvailable = UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out gameviewCameraForDrawing, "Tag Drawer Component", false); + if (cameraForSizeDefinitionIsAvailable) + { + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_global() - gameviewCameraForDrawing.transform.position).magnitude; + lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(gameviewCameraForDrawing, distance_ofDrawnObject_toCamera); + } + else + { + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + } + break; + default: + lengthOfScreenDiagonal_atDrawnObjectsPosition = 1.0f; + break; + } + } + + void TryDrawCoordinates(Vector3 drawPos3D_global) + { + UtilitiesDXXL_DrawBasics.Set_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_reversible(Convert_strokeWidthForCoordinateTexts_toPPM()); + if (this.transform.parent == null) + { + if (drawGlobalCoordinates || drawLocalCoordinates) + { + DrawBasics.Point(drawPos3D_global, null, default(Color), ScaleInputFloat_accordingToSizeDefinition(sizeOfMarkingCross_relToScreen, sizeOfMarkingCross), 0.0f, default(Color), default(Quaternion), false, true, false, 0.0f, hiddenByNearerObjects); + } + } + else + { + if (drawLocalCoordinates) + { + //-> "PointLocal()" already includes a potentially drawn "Point(global)()" + DrawBasics.PointLocal(GetDrawPos3D_inLocalSpaceAsDefinedByParent(), this.transform.parent, null, default(Color), ScaleInputFloat_accordingToSizeDefinition(sizeOfMarkingCross_relToScreen, sizeOfMarkingCross), 0.0f, default(Color), default(Quaternion), false, true, drawGlobalCoordinates, false, false, 0.0f, hiddenByNearerObjects); + } + else + { + if (drawGlobalCoordinates) + { + DrawBasics.Point(drawPos3D_global, null, default(Color), ScaleInputFloat_accordingToSizeDefinition(sizeOfMarkingCross_relToScreen, sizeOfMarkingCross), 0.0f, default(Color), default(Quaternion), false, true, false, 0.0f, hiddenByNearerObjects); + } + } + } + UtilitiesDXXL_DrawBasics.Reverse_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM(); + } + + int Convert_strokeWidthForCoordinateTexts_toPPM() + { + if (strokeWidth_forCoordinateTexts_onPointVisualiation_in0to1 <= 0.0f) + { + return 0; + } + else + { + return Mathf.CeilToInt(strokeWidth_forCoordinateTexts_onPointVisualiation_in0to1 * UtilitiesDXXL_Text.maxRelStrokeWidth_inPPMofSize); + } + } + + float Get_used_relTextSizeScaling(float used_textOffsetDistance) + { + if (CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace() == false) + { + switch (attachedTextsizeReferenceContext) + { + case AttachedTextsizeReferenceContext.extentOfTag: + return 1.0f; + case AttachedTextsizeReferenceContext.globalSpace: + return Get_used_relTextSizeScaling_toReachAFixedWorldSpaceTextSize(textSize_value, used_textOffsetDistance); + case AttachedTextsizeReferenceContext.sceneViewWindowSize: + //cannot reuse "cameraForSizeDefinitionIsAvailable" here, since "pointerAttachedTextsizeReferenceContext" is another setting than "pointerSizeInterpretation" +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_global() - UnityEditor.SceneView.lastActiveSceneView.camera.transform.position).magnitude; + float lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(UnityEditor.SceneView.lastActiveSceneView.camera, distance_ofDrawnObject_toCamera); + float worldSpaceTextSize_toReachWantedScreenspaceTextSize = lengthOfScreenDiagonal_atDrawnObjectsPosition * textSize_value_relToScreen; + return Get_used_relTextSizeScaling_toReachAFixedWorldSpaceTextSize(worldSpaceTextSize_toReachWantedScreenspaceTextSize, used_textOffsetDistance); + } + else + { + return 1.0f; + } +#else + return 1.0f; +#endif + case AttachedTextsizeReferenceContext.gameViewWindowSize: + //cannot reuse "cameraForSizeDefinitionIsAvailable" here, since "pointerAttachedTextsizeReferenceContext" is another setting than "pointerSizeInterpretation" + bool cameraForTextSizeDefinitionIsAvailable = UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out gameviewCameraForDrawing, "Tag Drawer Component", false); + if (cameraForTextSizeDefinitionIsAvailable) + { + float distance_ofDrawnObject_toCamera = (GetDrawPos3D_global() - gameviewCameraForDrawing.transform.position).magnitude; + float lengthOfScreenDiagonal_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_diagonalExtentOfViewport_at_distanceFromCam(gameviewCameraForDrawing, distance_ofDrawnObject_toCamera); + float worldSpaceTextSize_toReachWantedScreenspaceTextSize = lengthOfScreenDiagonal_atDrawnObjectsPosition * textSize_value_relToScreen; + return Get_used_relTextSizeScaling_toReachAFixedWorldSpaceTextSize(worldSpaceTextSize_toReachWantedScreenspaceTextSize, used_textOffsetDistance); + } + else + { + return 1.0f; + } + default: + return 1.0f; + } + } + else + { + return 1.0f; + } + } + + float Get_used_relTextSizeScaling_toReachAFixedWorldSpaceTextSize(float fixedWorldSpaceTextSize_toReach, float used_textOffsetDistance) + { + //"used_textOffsetDistance" is guaranteed bigger than 0 here -> no "division by 0" check necessary + return (fixedWorldSpaceTextSize_toReach / (used_textOffsetDistance * UtilitiesDXXL_DrawBasics.pointTagsTextSize_relToOffset)); + } + + bool CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace() + { + return ((pointerSizeInterpretation == PointerSizeInterpretation.relativeToTheSceneViewWindowSize) || (pointerSizeInterpretation == PointerSizeInterpretation.relativeToTheGameViewWindowSize)); + } + + DrawBasics.CameraForAutomaticOrientation Get_cameraForAutomaticOrientation() + { + if (tagStyle == TagStyle.pointer && CheckIf_pointerSizeInterpretaion_isDependentOn_screenspace()) + { + if (pointerSizeInterpretation == PointerSizeInterpretation.relativeToTheSceneViewWindowSize) + { + return DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + } + if (pointerSizeInterpretation == PointerSizeInterpretation.relativeToTheGameViewWindowSize) + { + return DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + } + UtilitiesDXXL_Log.PrintErrorCode("81-" + pointerSizeInterpretation); + return DrawBasics.cameraForAutomaticOrientation; + } + else + { + switch (attachedTextsizeReferenceContext) + { + case AttachedTextsizeReferenceContext.extentOfTag: + return DrawBasics.cameraForAutomaticOrientation; + case AttachedTextsizeReferenceContext.globalSpace: + return DrawBasics.cameraForAutomaticOrientation; + case AttachedTextsizeReferenceContext.sceneViewWindowSize: + return DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + case AttachedTextsizeReferenceContext.gameViewWindowSize: + return DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + default: + return DrawBasics.cameraForAutomaticOrientation; + } + } + } + + float forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before; + float forcedConstantWorldspaceTextSize_forTextAtShapes_before; + DrawBasics.CameraForAutomaticOrientation cameraForAutomaticOrientation_before; + float Set_globalTextSizeSpecs_reversible() + { + forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before = DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes; + forcedConstantWorldspaceTextSize_forTextAtShapes_before = DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes; + cameraForAutomaticOrientation_before = DrawBasics.cameraForAutomaticOrientation; + + switch (attachedTextsizeReferenceContext) + { + case AttachedTextsizeReferenceContext.extentOfTag: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = 0.0f; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + return 0.0f; + case AttachedTextsizeReferenceContext.globalSpace: + return textSize_value; + case AttachedTextsizeReferenceContext.sceneViewWindowSize: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = textSize_value_relToScreen; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + return 0.0f; + case AttachedTextsizeReferenceContext.gameViewWindowSize: + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = textSize_value_relToScreen; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = 0.0f; + DrawBasics.cameraForAutomaticOrientation = DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + return 0.0f; + default: + return textSize_value; + } + } + + void Reverse_globalTextSizeSpecs() + { + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = forcedConstantWorldspaceTextSize_forTextAtShapes_before; + DrawBasics.cameraForAutomaticOrientation = cameraForAutomaticOrientation_before; + } + + float ScaleInputFloat_accordingToSizeDefinition(float inputFloatToScale_versionThatIsRelToScreen, float inputFloatToScale) + { + switch (pointerSizeInterpretation) + { + case PointerSizeInterpretation.absoluteUnits: + return inputFloatToScale; + case PointerSizeInterpretation.relativeToGameobjectSize: + return biggestAbsGlobalSizeComponentOfTransform * inputFloatToScale; + case PointerSizeInterpretation.relativeToTheSceneViewWindowSize: + if (cameraForSizeDefinitionIsAvailable) + { + return lengthOfScreenDiagonal_atDrawnObjectsPosition * inputFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputFloatToScale; + } + case PointerSizeInterpretation.relativeToTheGameViewWindowSize: + if (cameraForSizeDefinitionIsAvailable) + { + return lengthOfScreenDiagonal_atDrawnObjectsPosition * inputFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputFloatToScale; + } + default: + return inputFloatToScale; + } + } + } + +} diff --git a/Runtime/DrawDebugLibrary/components/TagDrawer.cs.meta b/Runtime/DrawDebugLibrary/components/TagDrawer.cs.meta new file mode 100644 index 0000000..944870f --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/TagDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 74eec45e52affae44a67e6f5f3606e66 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/TextDrawer.cs b/Runtime/DrawDebugLibrary/components/TextDrawer.cs new file mode 100644 index 0000000..5b981b6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/TextDrawer.cs @@ -0,0 +1,309 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Text Drawer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class TextDrawer : VisualizerParent + { + public enum SizeInterpretation { globalSpace, sizeOfGameobject, sceneViewWindowWidth, gameViewWindowWidth }; + [SerializeField] SizeInterpretation sizeInterpretation = SizeInterpretation.globalSpace; + float lengthOfSceneviewScreenWidth_atDrawnObjectsPosition = 1.0f; + float lengthOfGameviewScreenWidth_atDrawnObjectsPosition = 1.0f; + float biggestAbsGlobalSizeComponentOfTransform = 1.0f; + [SerializeField] bool sceneViewCameraForSizeDefinitionIsAvailable = false; + [SerializeField] bool gameViewCameraForSizeDefinitionIsAvailable = false; + Camera gameviewCameraForDrawing; + public enum SizeInterpretationInclFallback { relativeToTheSameAsTextSize, absoluteUnits, relativeToGameobjectSize, relativeToTheSceneViewWindowWidth, relativeToTheGameViewWindowWidth }; + + [SerializeField] public Color color = DrawBasics.defaultColor; + [SerializeField] float size = 0.1f; + [SerializeField] [Range(0.001f, 0.25f)] float size_relToScreen = 0.01f; + [SerializeField] public bool size_isOutfolded = true; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public DrawText.TextAnchorDXXL textAnchor = DrawText.TextAnchorDXXL.LowerLeft; + [SerializeField] public bool enclosingBox_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.invisible; + [SerializeField] public float enclosingBox_lineWidth_relToTextSize = 0.0f; + [SerializeField] public float enclosingBox_paddingSize_relToTextSize = 0.0f; + + [SerializeField] public bool forceTextEnlargementToThisMinWidth_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] bool forceTextEnlargementToThisMinWidth = false; + [SerializeField] float forceTextEnlargementToThisMinWidth_value = 0.05f; + [SerializeField] [Range(0.003f, 2.0f)] float forceTextEnlargementToThisMinWidth_value_relToScreen = 0.005f; //upper range end is for vertical text in portrait mode screens + [SerializeField] SizeInterpretationInclFallback forceTextEnlargementToThisMinWidth_interpretation = SizeInterpretationInclFallback.relativeToTheSameAsTextSize; + + [SerializeField] public bool forceRestrictTextSizeToThisMaxTextWidth_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] bool forceRestrictTextSizeToThisMaxTextWidth = false; + [SerializeField] float forceRestrictTextSizeToThisMaxTextWidth_value = 1.0f; + [SerializeField] [Range(0.003f, 2.0f)] float forceRestrictTextSizeToThisMaxTextWidth_value_relToScreen = 0.1f; //upper range end is for vertical text in portrait mode screens + [SerializeField] SizeInterpretationInclFallback forceRestrictTextSizeToThisMaxTextWidth_interpretation = SizeInterpretationInclFallback.relativeToTheSameAsTextSize; + + [SerializeField] public bool autoLineBreakWidth_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] bool autoLineBreakWidth = false; + [SerializeField] float autoLineBreakWidth_value = 5.0f; + [SerializeField] [Range(0.003f, 2.0f)] float autoLineBreakWidth_value_relToScreen = 0.5f; //upper range end is for vertical text in portrait mode screens + [SerializeField] SizeInterpretationInclFallback autoLineBreakWidth_interpretation = SizeInterpretationInclFallback.relativeToTheSameAsTextSize; + + [SerializeField] public bool autoFlipToPreventMirrorInverted = true; + [SerializeField] bool forceTextTo_facingToSceneViewCam = true; + [SerializeField] bool forceTextTo_facingToGameViewCam = false; + + public override void InitializeValues_onceInComponentLifetime() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = "text to draw"; + text_inclGlobalMarkupTags = "text to draw"; + } + textSection_isOutfolded = true; + + customVector3Configs[0].picker_isOutfolded = false; + customVector3Configs[0].source = CustomVector3Source.transformsRight; + customVector3Configs[0].clipboardForManualInput = Vector3.right; + customVector3Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[1].picker_isOutfolded = false; + customVector3Configs[1].source = CustomVector3Source.transformsUp; + customVector3Configs[1].clipboardForManualInput = Vector3.up; + customVector3Configs[1].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[2].picker_isOutfolded = false; + customVector3Configs[2].source = CustomVector3Source.transformsRight; + customVector3Configs[2].clipboardForManualInput = Vector3.right; + customVector3Configs[2].vectorInterpretation = VectorInterpretation.globalSpace; + + customVector3Configs[3].picker_isOutfolded = false; + customVector3Configs[3].source = CustomVector3Source.transformsUp; + customVector3Configs[3].clipboardForManualInput = Vector3.up; + customVector3Configs[3].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void DrawVisualizedObject() + { + CacheSizeScaleFactors("Text Drawer Component"); + float used_size = Get_used_size(); + if (text_inclGlobalMarkupTags != null && text_inclGlobalMarkupTags != "") + { + if (UtilitiesDXXL_Math.ApproximatelyZero(used_size) == false) + { + GetScaledTextBlockConstraintValues(out float used_forceTextEnlargementToThisMinWidth_value, out float used_forceRestrictTextSizeToThisMaxTextWidth_value, out float used_autoLineBreakWidth_value); + + UtilitiesDXXL_DrawBasics.Set_cameraForAutomaticOrientation_reversible(Get_cameraForAutomaticOrientation()); + UtilitiesDXXL_Text.WriteFramed(text_inclGlobalMarkupTags, GetDrawPos3D_global(), color, used_size, GetTextDirVector(), GetTextUpVector(), textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, used_forceTextEnlargementToThisMinWidth_value, used_forceRestrictTextSizeToThisMaxTextWidth_value, used_autoLineBreakWidth_value, autoFlipToPreventMirrorInverted, 0.0f, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_cameraForAutomaticOrientation(); + } + } + } + + public void CacheSizeScaleFactors(string componentNameForErrorLog) + { + biggestAbsGlobalSizeComponentOfTransform = Get_biggestAbsGlobalSizeComponentOfTransform(); + + if (CheckIf_sceneViewCameraIsRequired()) + { +#if UNITY_EDITOR + sceneViewCameraForSizeDefinitionIsAvailable = (UnityEditor.SceneView.lastActiveSceneView != null); + if (sceneViewCameraForSizeDefinitionIsAvailable) + { + float distance_ofDrawnObject_toCamera = (Get_used_drawPos3D_global() - UnityEditor.SceneView.lastActiveSceneView.camera.transform.position).magnitude; + lengthOfSceneviewScreenWidth_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_horizExtentOfViewport_at_distanceFromCam(UnityEditor.SceneView.lastActiveSceneView.camera, distance_ofDrawnObject_toCamera); + } +#else + sceneViewCameraForSizeDefinitionIsAvailable = false; +#endif + } + + if (CheckIf_gameViewCameraIsRequired()) + { + gameViewCameraForSizeDefinitionIsAvailable = UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out gameviewCameraForDrawing, componentNameForErrorLog, false); + if (gameViewCameraForSizeDefinitionIsAvailable) + { + float distance_ofDrawnObject_toCamera = (Get_used_drawPos3D_global() - gameviewCameraForDrawing.transform.position).magnitude; + lengthOfGameviewScreenWidth_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_horizExtentOfViewport_at_distanceFromCam(gameviewCameraForDrawing, distance_ofDrawnObject_toCamera); + } + } + } + + bool CheckIf_sceneViewCameraIsRequired() + { + return ((sizeInterpretation == SizeInterpretation.sceneViewWindowWidth) || (forceTextEnlargementToThisMinWidth_interpretation == SizeInterpretationInclFallback.relativeToTheSceneViewWindowWidth) || (forceRestrictTextSizeToThisMaxTextWidth_interpretation == SizeInterpretationInclFallback.relativeToTheSceneViewWindowWidth) || (autoLineBreakWidth_interpretation == SizeInterpretationInclFallback.relativeToTheSceneViewWindowWidth)); + } + + bool CheckIf_gameViewCameraIsRequired() + { + return ((sizeInterpretation == SizeInterpretation.gameViewWindowWidth) || (forceTextEnlargementToThisMinWidth_interpretation == SizeInterpretationInclFallback.relativeToTheGameViewWindowWidth) || (forceRestrictTextSizeToThisMaxTextWidth_interpretation == SizeInterpretationInclFallback.relativeToTheGameViewWindowWidth) || (autoLineBreakWidth_interpretation == SizeInterpretationInclFallback.relativeToTheGameViewWindowWidth)); + } + + Vector3 GetTextDirVector() + { + if (forceTextTo_facingToSceneViewCam || forceTextTo_facingToGameViewCam) + { + return Get_customVector3_3_inGlobalSpaceUnits(); + } + else + { + return Get_customVector3_1_inGlobalSpaceUnits(); + } + } + + Vector3 GetTextUpVector() + { + if (forceTextTo_facingToSceneViewCam || forceTextTo_facingToGameViewCam) + { + return Get_customVector3_4_inGlobalSpaceUnits(); + } + else + { + return Get_customVector3_2_inGlobalSpaceUnits(); + } + } + + public float Get_used_size() + { + return ScaleInputFloat_accordingToSizeDefinition(size_relToScreen, size); + } + + float ScaleInputFloat_accordingToSizeDefinition(float inputFloatToScale_versionThatIsRelToScreen, float inputFloatToScale) + { + switch (sizeInterpretation) + { + case SizeInterpretation.globalSpace: + return inputFloatToScale; + case SizeInterpretation.sizeOfGameobject: + return biggestAbsGlobalSizeComponentOfTransform * inputFloatToScale; + case SizeInterpretation.sceneViewWindowWidth: + if (sceneViewCameraForSizeDefinitionIsAvailable) + { + return lengthOfSceneviewScreenWidth_atDrawnObjectsPosition * inputFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputFloatToScale; + } + case SizeInterpretation.gameViewWindowWidth: + if (gameViewCameraForSizeDefinitionIsAvailable) + { + return lengthOfGameviewScreenWidth_atDrawnObjectsPosition * inputFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputFloatToScale; + } + default: + return inputFloatToScale; + } + } + + public void GetScaledTextBlockConstraintValues(out float used_forceTextEnlargementToThisMinWidth_value, out float used_forceRestrictTextSizeToThisMaxTextWidth_value, out float used_autoLineBreakWidth_value) + { + used_forceTextEnlargementToThisMinWidth_value = ScaleTextBlockConstraintFloat_accordingToSizeDefinition(forceTextEnlargementToThisMinWidth, forceTextEnlargementToThisMinWidth_interpretation, forceTextEnlargementToThisMinWidth_value_relToScreen, forceTextEnlargementToThisMinWidth_value); + used_forceRestrictTextSizeToThisMaxTextWidth_value = ScaleTextBlockConstraintFloat_accordingToSizeDefinition(forceRestrictTextSizeToThisMaxTextWidth, forceRestrictTextSizeToThisMaxTextWidth_interpretation, forceRestrictTextSizeToThisMaxTextWidth_value_relToScreen, forceRestrictTextSizeToThisMaxTextWidth_value); + used_autoLineBreakWidth_value = ScaleTextBlockConstraintFloat_accordingToSizeDefinition(autoLineBreakWidth, autoLineBreakWidth_interpretation, autoLineBreakWidth_value_relToScreen, autoLineBreakWidth_value); + } + + public float ScaleTextBlockConstraintFloat_accordingToSizeDefinition(bool constraintIsActive, SizeInterpretationInclFallback interpretationOfConstraintValue, float inputConstraintFloatToScale_versionThatIsRelToScreen, float inputConstraintFloatToScale) + { + if (constraintIsActive) + { + switch (interpretationOfConstraintValue) + { + case SizeInterpretationInclFallback.relativeToTheSameAsTextSize: + return ScaleInputFloat_accordingToSizeDefinition(inputConstraintFloatToScale_versionThatIsRelToScreen, inputConstraintFloatToScale); + case SizeInterpretationInclFallback.absoluteUnits: + return inputConstraintFloatToScale; + case SizeInterpretationInclFallback.relativeToGameobjectSize: + return biggestAbsGlobalSizeComponentOfTransform * inputConstraintFloatToScale; + case SizeInterpretationInclFallback.relativeToTheSceneViewWindowWidth: + if (sceneViewCameraForSizeDefinitionIsAvailable) + { + return lengthOfSceneviewScreenWidth_atDrawnObjectsPosition * inputConstraintFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputConstraintFloatToScale; + } + case SizeInterpretationInclFallback.relativeToTheGameViewWindowWidth: + if (gameViewCameraForSizeDefinitionIsAvailable) + { + return lengthOfGameviewScreenWidth_atDrawnObjectsPosition * inputConstraintFloatToScale_versionThatIsRelToScreen; + } + else + { + return inputConstraintFloatToScale; + } + default: + return inputConstraintFloatToScale; + } + } + else + { + return 0.0f; + } + } + + public virtual float Get_biggestAbsGlobalSizeComponentOfTransform() + { + return UtilitiesDXXL_Math.GetBiggestAbsComponent(transform.lossyScale); + } + + public virtual Vector3 Get_used_drawPos3D_global() + { + return GetDrawPos3D_global(); + } + + DrawBasics.CameraForAutomaticOrientation Get_cameraForAutomaticOrientation() + { + if (autoFlipToPreventMirrorInverted) + { + if (forceTextTo_facingToSceneViewCam) + { + return DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + } + else + { + if (forceTextTo_facingToGameViewCam) + { + return DrawBasics.CameraForAutomaticOrientation.gameViewCamera; + } + else + { + if (CheckIf_textDirVectorSource_isOrientedAtObserverCam()) + { + return customVector3Configs[0].observerCamera; + } + else + { + if (CheckIf_textUpVectorSource_isOrientedAtObserverCam()) + { + return customVector3Configs[1].observerCamera; + } + else + { + //= no change + return DrawBasics.cameraForAutomaticOrientation; + } + } + } + } + } + else + { + //= no change + return DrawBasics.cameraForAutomaticOrientation; + } + } + + bool CheckIf_textDirVectorSource_isOrientedAtObserverCam() + { + return ((customVector3Configs[0].source == CustomVector3Source.observerCameraForward) || (customVector3Configs[0].source == CustomVector3Source.observerCameraUp) || (customVector3Configs[0].source == CustomVector3Source.observerCameraRight) || (customVector3Configs[0].source == CustomVector3Source.observerCameraBack) || (customVector3Configs[0].source == CustomVector3Source.observerCameraDown) || (customVector3Configs[0].source == CustomVector3Source.observerCameraLeft) || (customVector3Configs[0].source == CustomVector3Source.observerCameraToThisGameobject)); + } + + bool CheckIf_textUpVectorSource_isOrientedAtObserverCam() + { + return ((customVector3Configs[1].source == CustomVector3Source.observerCameraForward) || (customVector3Configs[1].source == CustomVector3Source.observerCameraUp) || (customVector3Configs[1].source == CustomVector3Source.observerCameraRight) || (customVector3Configs[1].source == CustomVector3Source.observerCameraBack) || (customVector3Configs[1].source == CustomVector3Source.observerCameraDown) || (customVector3Configs[1].source == CustomVector3Source.observerCameraLeft) || (customVector3Configs[1].source == CustomVector3Source.observerCameraToThisGameobject)); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/TextDrawer.cs.meta b/Runtime/DrawDebugLibrary/components/TextDrawer.cs.meta new file mode 100644 index 0000000..6724591 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/TextDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 47fc512398f06fb40a9a419593032596 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities.meta b/Runtime/DrawDebugLibrary/components/internal utilities.meta new file mode 100644 index 0000000..1aa0d11 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 450795ad44b90d74dab526a755954264 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/BezierSplineDrawerBase.cs b/Runtime/DrawDebugLibrary/components/internal utilities/BezierSplineDrawerBase.cs new file mode 100644 index 0000000..3d3ff5d --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/BezierSplineDrawerBase.cs @@ -0,0 +1,12 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class BezierSplineDrawerBase : VisualizerParent + { + [SerializeField] protected Color color = DrawBasics.defaultColor; + [SerializeField] protected float lineWidth = 0.0f; + [SerializeField] protected int straightSubDivisionsPerSegment = 50; + protected float textSize = 0.1f; + } +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/BezierSplineDrawerBase.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/BezierSplineDrawerBase.cs.meta new file mode 100644 index 0000000..f04dc30 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/BezierSplineDrawerBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b97f2527d9d101a4bb1d9d042e866f70 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/CustomVectorConfigs.cs b/Runtime/DrawDebugLibrary/components/internal utilities/CustomVectorConfigs.cs new file mode 100644 index 0000000..41250d3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/CustomVectorConfigs.cs @@ -0,0 +1,83 @@ +namespace DrawXXL +{ + using UnityEngine; + + /// + /// 可序列化的 CustomVector3 配置项,替代 VisualizerParent 中重复的 4 组独立字段。 + /// + [System.Serializable] + public struct CustomVector3Config + { + public VisualizerParent.CustomVector3Source source; + public Vector3 clipboardForManualInput; + public GameObject targetGameObject; + public bool hasForcedAbsLength; + public bool picker_isOutfolded; + public float forcedAbsLength; + [Range(0.1f, 10.0f)] public float lengthRelScaleFactor; + public VisualizerParent.VectorInterpretation vectorInterpretation; + public DrawBasics.CameraForAutomaticOrientation observerCamera; + + public CustomVector3Config(VisualizerParent.CustomVector3Source source, Vector3 clipboard, GameObject target, bool hasForcedAbs, bool pickerOutfolded, float forcedLen, float relScale, VisualizerParent.VectorInterpretation vecInterpretation, DrawBasics.CameraForAutomaticOrientation cam) + { + this.source = source; + this.clipboardForManualInput = clipboard; + this.targetGameObject = target; + this.hasForcedAbsLength = hasForcedAbs; + this.picker_isOutfolded = pickerOutfolded; + this.forcedAbsLength = forcedLen; + this.lengthRelScaleFactor = relScale; + this.vectorInterpretation = vecInterpretation; + this.observerCamera = cam; + } + + public static CustomVector3Config Default() + { + return new CustomVector3Config + { + source = (VisualizerParent.CustomVector3Source)(-1), + clipboardForManualInput = Vector3.zero, + targetGameObject = null, + hasForcedAbsLength = false, + picker_isOutfolded = false, + forcedAbsLength = 1.0f, + lengthRelScaleFactor = 1.0f, + vectorInterpretation = VisualizerParent.VectorInterpretation.globalSpace, + observerCamera = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera + }; + } + } + + /// + /// 可序列化的 CustomVector2 配置项,替代 VisualizerParent 中重复的 4 组独立字段。 + /// + [System.Serializable] + public struct CustomVector2Config + { + public VisualizerParent.CustomVector2Source source; + public Vector2 clipboardForManualInput; + public GameObject targetGameObject; + public bool hasForcedAbsLength; + public bool picker_isOutfolded; + [Range(-360.0f, 360.0f)] public float rotationFromRight; + public float forcedAbsLength; + [Range(0.1f, 10.0f)] public float lengthRelScaleFactor; + public VisualizerParent.VectorInterpretation vectorInterpretation; + + public static CustomVector2Config Default() + { + return new CustomVector2Config + { + source = (VisualizerParent.CustomVector2Source)(-1), + clipboardForManualInput = Vector2.zero, + targetGameObject = null, + hasForcedAbsLength = false, + picker_isOutfolded = false, + rotationFromRight = 0.0f, + forcedAbsLength = 1.0f, + lengthRelScaleFactor = 1.0f, + vectorInterpretation = VisualizerParent.VectorInterpretation.globalSpace + }; + } + } +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/CustomVectorConfigs.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/CustomVectorConfigs.cs.meta new file mode 100644 index 0000000..6d918e2 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/CustomVectorConfigs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5e4f2b3e473e17499602464b5b4dc9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSpline2DConnection.cs b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSpline2DConnection.cs new file mode 100644 index 0000000..bfa0d3a --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSpline2DConnection.cs @@ -0,0 +1,374 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Internal Not For Manual Creation/Draw XXL Spline 2D Connection")] + [ExecuteInEditMode] + public class DrawXXLSpline2DConnection : MonoBehaviour + { + Quaternion lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf; //-> other than the position the spline control points don't save a "rotation" but only a "direction", so there is an extra member to care for the synchronisation here + public BezierSplineDrawer2D bezierSplineDrawer_thatHasReferencedThisGameobject; + //public InternalDXXL_BezierControlSubPoint2D bezierSubPoint_thatHasReferencedThisGameobject; //this is not suitable as reference, because in the serialized context "InternalDXXL_BezierControlSubPoint" acts as value type, not as reference type. + public bool componentHasBeenManuallyCreated = true; + public int i_ofControlPointTriplet_thisGameobjectIsBoundTo; + public InternalDXXL_BezierControlSubPoint.SubPointType subPointType_whereThisGameobjectIsBoundTo; + + void OnDestroy() + { + //-> calling "Undo.RegisterCompleteObjectUndo(bezierSplineDrawer_thatHasReferencedThisGameobject, "undoName")" also doesn't solve the bug, that the connectionReference cannot be restored via "Editor/Undo" after this connection component has been deleted. But it at least prevents the bool-comparison-error described in "TryEarlyReturnAndSelfDeleteBecauseReferenceGotLost()". Though this error can also be prevented with an additional bool-check. + //-> Moreover calling "Undo.RegisterCompleteObjectUndo(bezierSplineDrawer_thatHasReferencedThisGameobject, "undoName")" may lead to confusting undo states, because this connection component gets destroyed (and therewith this "OnDestroy()" here gets called) not only when the user deletes it (or the carrying boundGameobject), but also when the spline component gets destroyed (specifically this connection component is destroyed inside "OnDestroy()" of the spline component). So the spline most likely already has an "Undo.DestroyImmediate()" registered for itself through the spline deletion the was triggerd by manual control in the Editor. Then it would be saved into the undo state once more here. That seems to risky since the undo system can have obscure errors when used in such hacky ways, which can even crash the Unity Editor. + } + + void Update() + { + if (TryDestroyThisComponentIfItWasManuallyCreated()) { return; } + if (TryEarlyReturnAndSelfDeleteBecauseReferenceGotLost()) { return; } + + //No "register undo for spline" is done here before changed transform values get written to the spline: + //-> It is unclear how this gameobject changed it's transform. Has the "changer" already filed an "Undo" or should it be filed here? If it has already been filed is it harmful when it is filed twice into the undo state? + //-> It is not necessary: since the transform of this boundGameobject is authoritative for the spline shape, the spline shape will follow the undo as soon as the transform is reverted via an Undo. + //-> So the changer of this transform is responsible for caring for the undo entry registration. In most cases the transform will be changed via the Scene view handles or the Transform inspector, in which cases Unity already automatically registers the Undo entry. + + if (Get_bezierSubPoint_thatHasReferencedThisGameobject().isUsed) + { + if (false == UtilitiesDXXL_Math.CheckIf_twoVectorsAreExactlyEqual((Vector2)transform.position, Get_bezierSubPoint_thatHasReferencedThisGameobject().GetPos_inUnitsOfGlobalSpace())) + { + //Note: A position change of this bound gameobject has never effect on the direction of the control sub point, so this will not "come back via forwarding to dependent sub points" and set this gameobjects rotation. + Transfer_position_fromBoundGameobject_toSpline(); + } + } + + if (subPointType_whereThisGameobjectIsBoundTo == InternalDXXL_BezierControlSubPoint.SubPointType.anchor) + { + if (Get_bezierSubPoint_thatHasReferencedThisGameobject().Get_sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked() != InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject) + { + //-> only anchor points can arrive here, but no helper points + //-> anchor points cannot be unused (meaning "isUsed == true" is guarateed here) + if (false == UtilitiesDXXL_Math.CheckIf_twoQuaternionsAreExactlyEqual(transform.rotation, lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf)) + { + //Note: A rotation change of this bound gameobject has never effect on the position of the control sub point, so this will not "come back via forwarding to dependent sub points" and set this gameobjects position. + Transfer_aTransformDirection_fromBoundGameobject_toSpline(); + } + } + } + } + + InternalDXXL_BezierControlSubPoint2D Get_bezierSubPoint_thatHasReferencedThisGameobject() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + if (bezierSplineDrawer_thatHasReferencedThisGameobject != null) + { + if (i_ofControlPointTriplet_thisGameobjectIsBoundTo < bezierSplineDrawer_thatHasReferencedThisGameobject.listOfControlPointTriplets.Count) + { + return bezierSplineDrawer_thatHasReferencedThisGameobject.listOfControlPointTriplets[i_ofControlPointTriplet_thisGameobjectIsBoundTo].GetASubPoint(subPointType_whereThisGameobjectIsBoundTo); + } + else + { + return null; + } + } + else + { + return null; + } + } + + public void Transfer_position_fromBoundGameobject_toSpline() + { + if (CheckIf_thisConnectionComponentIsActive()) + { + Get_bezierSubPoint_thatHasReferencedThisGameobject().SetPos_inUnitsOfGlobalSpace(transform.position, true, this.gameObject); + } + } + + public void Transfer_aTransformDirection_fromBoundGameobject_toSpline() + { + if (CheckIf_thisConnectionComponentIsActive()) + { + if (subPointType_whereThisGameobjectIsBoundTo != InternalDXXL_BezierControlSubPoint.SubPointType.anchor) + { + UtilitiesDXXL_Log.PrintErrorCode("69"); + } + + InternalDXXL_BezierControlSubPoint2D anchorPoint = Get_bezierSubPoint_thatHasReferencedThisGameobject(); //-> only for code readability + if (anchorPoint.GetJunctureType() == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + if (anchorPoint.GetBackwardHelper().isUsed == true) + { + if (anchorPoint.GetBackwardHelper().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject) + { + Vector2 newDirection_toBackwardHelper_inUnitsOfGlobalSpace_normalized = GetDirectionNormalizedFromRotation(anchorPoint.GetBackwardHelper().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture); + anchorPoint.Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(newDirection_toBackwardHelper_inUnitsOfGlobalSpace_normalized, true, this.gameObject); + lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf = transform.rotation; + } + } + + if (anchorPoint.GetForwardHelper().isUsed == true) + { + if (anchorPoint.GetForwardHelper().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject) + { + Vector2 newDirection_toForwardHelper_inUnitsOfGlobalSpace_normalized = GetDirectionNormalizedFromRotation(anchorPoint.GetForwardHelper().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture); + anchorPoint.Set_direction_toForward_inUnitsOfGlobalSpace_normalized(newDirection_toForwardHelper_inUnitsOfGlobalSpace_normalized, true, this.gameObject); + lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf = transform.rotation; + } + } + } + else + { + if (anchorPoint.Get_sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked() != InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject) + { + Vector2 newDirection_toForwardHelper_inUnitsOfGlobalSpace_normalized = GetDirectionNormalizedFromRotation(anchorPoint.Get_sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked()); + anchorPoint.Set_direction_toForward_inUnitsOfGlobalSpace_normalized(newDirection_toForwardHelper_inUnitsOfGlobalSpace_normalized, true, this.gameObject); + lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf = transform.rotation; + } + } + } + } + + Vector2 GetDirectionNormalizedFromRotation(InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D directionSource) + { + switch (directionSource) + { + case InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject: + UtilitiesDXXL_Log.PrintErrorCode("58"); + return Vector2.right; + case InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.gameobjectsUp: + return ConvertDirectionV3_toDirectionV2Normalized(transform.up); + case InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.gameobjectsRight: + return ConvertDirectionV3_toDirectionV2Normalized(transform.right); + case InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.gameobjectsDown: + return ConvertDirectionV3_toDirectionV2Normalized(-transform.up); + case InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.gameobjectsLeft: + return ConvertDirectionV3_toDirectionV2Normalized(-transform.right); + default: + UtilitiesDXXL_Log.PrintErrorCode("59"); + return Vector2.right; + } + } + + Vector2 ConvertDirectionV3_toDirectionV2Normalized(Vector3 directionV3_toConvert) + { + Vector2 direction_projectedPerpOntoXYPlane = UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero.Get_projectionOfVectorOntoPlane(directionV3_toConvert); + Vector2 direction_projectedPerpOntoXYPlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(direction_projectedPerpOntoXYPlane); + + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(direction_projectedPerpOntoXYPlane_normalized)) + { + return Vector2.right; + } + else + { + return direction_projectedPerpOntoXYPlane_normalized; + } + } + + public void Transfer_newDirectionToAHelperPointInUnitsOfGlobalSpaceNormalized_fromSpline_toBoundGameobject(Vector2 newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized, InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D directionSource_thatTheNewDirectionDescribes, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (CheckIf_thisConnectionComponentIsActive()) + { + if (subPointType_whereThisGameobjectIsBoundTo != InternalDXXL_BezierControlSubPoint.SubPointType.anchor) + { + UtilitiesDXXL_Log.PrintErrorCode("70"); + } + + if (this.gameObject != boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) //-> this should prevent "continuous slow drifting of the values". The values the get set here could otherwise be converted somehow in the sub points and then be written back to the transform of this gameobject. The therewith calculated value can be slightly different (due to float calculation imprecision). + { + switch (directionSource_thatTheNewDirectionDescribes) + { + case InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject: + UtilitiesDXXL_Log.PrintErrorCode("60"); + break; + case InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.gameobjectsUp: + AssignNewTransformUp(newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized); + break; + case InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.gameobjectsRight: + AssignNewTransformRight(newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized); + break; + case InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.gameobjectsDown: + AssignNewTransformUp(-newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized); + break; + case InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.gameobjectsLeft: + AssignNewTransformRight(-newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized); + break; + default: + break; + } + lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf = transform.rotation; + } + } + } + + void AssignNewTransformUp(Vector2 newUp_normalized_insideXYPlane) + { + Vector3 newUp_normalized_insideXYPlane_asV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(newUp_normalized_insideXYPlane); + Vector3 oldUpOfTransform_projectedOntoXYPlane = UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero.Get_projectionOfVectorOntoPlane(transform.up); + Vector3 oldUpOfTransform_projectedOntoXYPlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(oldUpOfTransform_projectedOntoXYPlane); + + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(oldUpOfTransform_projectedOntoXYPlane_normalized) == false) + { + Quaternion rotationIncrement = Quaternion.FromToRotation(oldUpOfTransform_projectedOntoXYPlane_normalized, newUp_normalized_insideXYPlane_asV3); + transform.rotation = rotationIncrement * transform.rotation; + } + } + + void AssignNewTransformRight(Vector2 newRight_normalized_insideXYPlane) + { + Vector3 newRight_normalized_insideXYPlane_asV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(newRight_normalized_insideXYPlane); + Vector3 oldRightOfTransform_projectedOntoXYPlane = UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero.Get_projectionOfVectorOntoPlane(transform.right); + Vector3 oldRightOfTransform_projectedOntoXYPlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(oldRightOfTransform_projectedOntoXYPlane); + + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(oldRightOfTransform_projectedOntoXYPlane_normalized) == false) + { + Quaternion rotationIncrement = Quaternion.FromToRotation(oldRightOfTransform_projectedOntoXYPlane_normalized, newRight_normalized_insideXYPlane_asV3); + transform.rotation = rotationIncrement * transform.rotation; + } + } + + bool TryDestroyThisComponentIfItWasManuallyCreated() + { + if (componentHasBeenManuallyCreated) + { + Debug.LogError("'DrawXXLSpline2DConnection' should not be created manually. It will be automatically created and destroyed by the 'Bezier Spline Drawer 2D' component."); + DestroyThisComponent(false); + return true; + } + else + { + return false; + } + } + + bool TryEarlyReturnAndSelfDeleteBecauseReferenceGotLost() + { + if (bezierSplineDrawer_thatHasReferencedThisGameobject == null) + { + //-> "bezierSplineDrawer_thatHasReferencedThisGameobject" has been deleted + //-> actually this component could also be deleted now, but the problem is: If the deletion of "bezierSplineDrawer_thatHasReferencedThisGameobject" is reverted via the editors "Undo"-functionality, then the retrieved bezierSplineDrawer doesn't have this spline connection anymore and the "undo" is not complete in this regard. + //-> see also more detialled explantation in "subPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled()" + //-> The connection component here stays inactive as long as it doesn't have a "bezierSplineDrawer_thatHasReferencedThisGameobject" + + DestroyThisComponent(false); + return true; + } + else + { + InternalDXXL_BezierControlSubPoint2D bezierSubPoint = Get_bezierSubPoint_thatHasReferencedThisGameobject(); + if (bezierSubPoint == null) + { + UtilitiesDXXL_Log.PrintErrorCode("76-" + bezierSplineDrawer_thatHasReferencedThisGameobject.listOfControlPointTriplets.Count + "-" + i_ofControlPointTriplet_thisGameobjectIsBoundTo); + DestroyThisComponent(false); + return true; + } + else + { + if (bezierSubPoint.bezierSplineDrawer_thisSubPointIsPartOf != bezierSplineDrawer_thatHasReferencedThisGameobject) + { + UtilitiesDXXL_Log.PrintErrorCode("77-" + bezierSubPoint.bezierSplineDrawer_thisSubPointIsPartOf + "-" + bezierSplineDrawer_thatHasReferencedThisGameobject); + DestroyThisComponent(false); + return true; + } + else + { + if (bezierSubPoint.boundGameobject != this.gameObject) + { + //-> case 1: the gameobject that carries this connection-component has been copied. + //-> case 2: connection-component has been manually copied to another gameobject + //-> the connection gets deleted here. It stays only at the pre-copy-gameobject + //-> case 3: some "copy spline component -> undo -> redo" to-and-fro arrives here, see also + //-> see also more detialled explantation in "subPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled()" + + DestroyThisComponent(false); + return true; + } + else + { + //The following "if (bezierSubPoint.connectionComponent_onBoundGameobject != this)"-check gives false evaluations in some cases. + //Observed case: + //-> Add boundGamobject(this) to a spline control point. + //-> Then delete the bound gameobject. + //-> Then the deletion via the editors "undo"-functionality. + //-> Then "bezierSubPoint.connectionComponent_onBoundGameobject" is "null" (probably due to the Unity bug, see explanation in "subPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled()" + //-> Despite "bezierSubPoint.connectionComponent_onBoundGameobject" beeing "null" and "this" not beeing "null" the check "if (bezierSubPoint.connectionComponent_onBoundGameobject != this)" results in "is the same". + //-> It has probably to do with Unitys way of serialization and undo + + if (bezierSubPoint.connectionComponent_onBoundGameobject != this) + { + //-> this connection component has been manually copied as duplicate to the same gameobject + //-> some delete/undo/redo-to and fro may also arrive here + DestroyThisComponent(false); + return true; + } + else + { + if (bezierSubPoint.connectionComponent_onBoundGameobject == null) //-> additional check as double bottom that fixes the comparison error described above + { + DestroyThisComponent(false); + return true; + } + else + { + if (bezierSubPoint.i_ofContainingControlPoint_insideControlPointsList != i_ofControlPointTriplet_thisGameobjectIsBoundTo) + { + UtilitiesDXXL_Log.PrintErrorCode("78-" + bezierSplineDrawer_thatHasReferencedThisGameobject.listOfControlPointTriplets.Count + "-" + i_ofControlPointTriplet_thisGameobjectIsBoundTo + "-" + bezierSubPoint.i_ofContainingControlPoint_insideControlPointsList); + DestroyThisComponent(false); + return true; + } + else + { + if (bezierSubPoint.subPointType != subPointType_whereThisGameobjectIsBoundTo) + { + UtilitiesDXXL_Log.PrintErrorCode("79-" + bezierSplineDrawer_thatHasReferencedThisGameobject.listOfControlPointTriplets.Count + "-" + i_ofControlPointTriplet_thisGameobjectIsBoundTo + "-" + bezierSubPoint.subPointType + "-" + subPointType_whereThisGameobjectIsBoundTo); + DestroyThisComponent(false); + return true; + } + else + { + return false; + } + } + } + } + } + } + } + } + } + + void DestroyThisComponent(bool withDestructionUndo) + { + //Destroying only the component, but keeping the gameObject and all other components: + if (Application.isPlaying) + { + Destroy(this); + } + else + { + if (withDestructionUndo) + { +#if UNITY_EDITOR + UnityEditor.Undo.DestroyObjectImmediate(this); +#else + //How can the code arrive here? + UtilitiesDXXL_Log.PrintErrorCode("84-"+ Application.isPlaying); + Destroy(this); +#endif + } + else + { + DestroyImmediate(this); + } + } + } + + bool CheckIf_thisConnectionComponentIsActive() + { + if (bezierSplineDrawer_thatHasReferencedThisGameobject != null) //this is only due to the undo-mechanic-selfDestruction-delay + { + return isActiveAndEnabled; + } + return false; + } + + } + +} \ No newline at end of file diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSpline2DConnection.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSpline2DConnection.cs.meta new file mode 100644 index 0000000..5351df0 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSpline2DConnection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a3859fc5b45a9a46a4ebb2fd6f7ba14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSplineConnection.cs b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSplineConnection.cs new file mode 100644 index 0000000..edc740b --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSplineConnection.cs @@ -0,0 +1,377 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Internal Not For Manual Creation/Draw XXL Spline Connection")] + [ExecuteInEditMode] + public class DrawXXLSplineConnection : MonoBehaviour + { + Quaternion lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf; //-> other than the position the spline control points don't save a "rotation" but only a "direction", so there is an extra member to care for the synchronisation here + public BezierSplineDrawer bezierSplineDrawer_thatHasReferencedThisGameobject; + //public InternalDXXL_BezierControlSubPoint bezierSubPoint_thatHasReferencedThisGameobject; //this is not suitable as reference, because in the serialized context "InternalDXXL_BezierControlSubPoint" acts as value type, not as reference type. + public bool componentHasBeenManuallyCreated = true; + public int i_ofControlPointTriplet_thisGameobjectIsBoundTo; + public InternalDXXL_BezierControlSubPoint.SubPointType subPointType_whereThisGameobjectIsBoundTo; + + void OnDestroy() + { + //-> calling "Undo.RegisterCompleteObjectUndo(bezierSplineDrawer_thatHasReferencedThisGameobject, "undoName")" also doesn't solve the bug, that the connectionReference cannot be restored via "Editor/Undo" after this connection component has been deleted. But it at least prevents the bool-comparison-error described in "TryEarlyReturnAndSelfDeleteBecauseReferenceGotLost()". Though this error can also be prevented with an additional bool-check. + //-> Moreover calling "Undo.RegisterCompleteObjectUndo(bezierSplineDrawer_thatHasReferencedThisGameobject, "undoName")" may lead to confusting undo states, because this connection component gets destroyed (and therewith this "OnDestroy()" here gets called) not only when the user deletes it (or the carrying boundGameobject), but also when the spline component gets destroyed (specifically this connection component is destroyed inside "OnDestroy()" of the spline component). So the spline most likely already has an "Undo.DestroyImmediate()" registered for itself through the spline deletion the was triggerd by manual control in the Editor. Then it would be saved into the undo state once more here. That seems to risky since the undo system can have obscure errors when used in such hacky ways, which can even crash the Unity Editor. + } + + void Update() + { + if (TryDestroyThisComponentIfItWasManuallyCreated()) { return; } + if (TryEarlyReturnAndSelfDeleteBecauseReferenceGotLost()) { return; } + + //No "register undo for spline" is done here before changed transform values get written to the spline: + //-> It is unclear how this gameobject changed it's transform. Has the "changer" already filed an "Undo" or should it be filed here? If it has already been filed is it harmful when it is filed twice into the undo state? + //-> It is not necessary: since the transform of this boundGameobject is authoritative for the spline shape, the spline shape will follow the undo as soon as the transform is reverted via an Undo. + //-> So the changer of this transform is responsible for caring for the undo entry registration. In most cases the transform will be changed via the Scene view handles or the Transform inspector, in which cases Unity already automatically registers the Undo entry. + + if (Get_bezierSubPoint_thatHasReferencedThisGameobject().isUsed) + { + if (false == UtilitiesDXXL_Math.CheckIf_twoVectorsAreExactlyEqual(transform.position, Get_bezierSubPoint_thatHasReferencedThisGameobject().GetPos_inUnitsOfGlobalSpace())) + { + //Note: A position change of this bound gameobject has never effect on the direction of the control sub point, so this will not "come back via forwarding to dependent sub points" and set this gameobjects rotation. + Transfer_position_fromBoundGameobject_toSpline(); + } + } + + if (subPointType_whereThisGameobjectIsBoundTo == InternalDXXL_BezierControlSubPoint.SubPointType.anchor) + { + if (Get_bezierSubPoint_thatHasReferencedThisGameobject().Get_sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked() != InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject) + { + //-> only anchor points can arrive here, but no helper points + //-> anchor points cannot be unused (meaning "isUsed == true" is guarateed here) + if (false == UtilitiesDXXL_Math.CheckIf_twoQuaternionsAreExactlyEqual(transform.rotation, lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf)) + { + //Note: A rotation change of this bound gameobject has never effect on the position of the control sub point, so this will not "come back via forwarding to dependent sub points" and set this gameobjects position. + Transfer_aTransformDirection_fromBoundGameobject_toSpline(); + } + } + } + } + + InternalDXXL_BezierControlSubPoint Get_bezierSubPoint_thatHasReferencedThisGameobject() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + if (bezierSplineDrawer_thatHasReferencedThisGameobject != null) + { + if (i_ofControlPointTriplet_thisGameobjectIsBoundTo < bezierSplineDrawer_thatHasReferencedThisGameobject.listOfControlPointTriplets.Count) + { + return bezierSplineDrawer_thatHasReferencedThisGameobject.listOfControlPointTriplets[i_ofControlPointTriplet_thisGameobjectIsBoundTo].GetASubPoint(subPointType_whereThisGameobjectIsBoundTo); + } + else + { + return null; + } + } + else + { + return null; + } + } + + public void Transfer_position_fromBoundGameobject_toSpline() + { + if (CheckIf_thisConnectionComponentIsActive()) + { + Get_bezierSubPoint_thatHasReferencedThisGameobject().SetPos_inUnitsOfGlobalSpace(transform.position, true, this.gameObject); + } + } + + public void Transfer_aTransformDirection_fromBoundGameobject_toSpline() + { + if (CheckIf_thisConnectionComponentIsActive()) + { + if (subPointType_whereThisGameobjectIsBoundTo != InternalDXXL_BezierControlSubPoint.SubPointType.anchor) + { + UtilitiesDXXL_Log.PrintErrorCode("45"); + } + + InternalDXXL_BezierControlSubPoint anchorPoint = Get_bezierSubPoint_thatHasReferencedThisGameobject(); //-> only for code readability + if (anchorPoint.GetJunctureType() == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + if (anchorPoint.GetBackwardHelper().isUsed == true) + { + if (anchorPoint.GetBackwardHelper().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject) + { + Vector3 newDirection_toBackwardHelper_inUnitsOfGlobalSpace_normalized = GetDirectionFromRotation(anchorPoint.GetBackwardHelper().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture); + anchorPoint.Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(newDirection_toBackwardHelper_inUnitsOfGlobalSpace_normalized, true, this.gameObject); + lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf = transform.rotation; + } + } + + if (anchorPoint.GetForwardHelper().isUsed == true) + { + if (anchorPoint.GetForwardHelper().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject) + { + Vector3 newDirection_toForwardHelper_inUnitsOfGlobalSpace_normalized = GetDirectionFromRotation(anchorPoint.GetForwardHelper().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture); + anchorPoint.Set_direction_toForward_inUnitsOfGlobalSpace_normalized(newDirection_toForwardHelper_inUnitsOfGlobalSpace_normalized, true, this.gameObject); + lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf = transform.rotation; + } + } + } + else + { + if (anchorPoint.Get_sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked() != InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject) + { + Vector3 newDirection_toForwardHelper_inUnitsOfGlobalSpace_normalized = GetDirectionFromRotation(anchorPoint.Get_sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked()); + anchorPoint.Set_direction_toForward_inUnitsOfGlobalSpace_normalized(newDirection_toForwardHelper_inUnitsOfGlobalSpace_normalized, true, this.gameObject); + lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf = transform.rotation; + } + } + } + } + + Vector3 GetDirectionFromRotation(InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper directionSource) + { + switch (directionSource) + { + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject: + UtilitiesDXXL_Log.PrintErrorCode("34"); + return Vector3.forward; + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsForward: + return transform.forward; + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsUp: + return transform.up; + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsRight: + return transform.right; + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsBack: + return (-transform.forward); + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsDown: + return (-transform.up); + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsLeft: + return (-transform.right); + default: + UtilitiesDXXL_Log.PrintErrorCode("35"); + return Vector3.forward; + } + } + + public void Transfer_newDirectionToAHelperPointInUnitsOfGlobalSpaceNormalized_fromSpline_toBoundGameobject(Vector3 newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized, InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper directionSource_thatTheNewDirectionDescribes, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (CheckIf_thisConnectionComponentIsActive()) + { + if (subPointType_whereThisGameobjectIsBoundTo != InternalDXXL_BezierControlSubPoint.SubPointType.anchor) + { + UtilitiesDXXL_Log.PrintErrorCode("46"); + } + + if (this.gameObject != boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) //-> this should prevent "continuous slow drifting of the values". The values the get set here could otherwise be converted somehow in the sub points and then be written back to the transform of this gameobject. The therewith calculated value can be slightly different (due to float calculation imprecision). + { + Quaternion newRotation; + switch (directionSource_thatTheNewDirectionDescribes) + { + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject: + UtilitiesDXXL_Log.PrintErrorCode("36"); + break; + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsForward: + newRotation = Quaternion.LookRotation(newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized, transform.up); + transform.rotation = newRotation; + break; + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsUp: + AssignNewTransformUp(newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized); + break; + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsRight: + AssignNewTransformRight(newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized); + break; + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsBack: + newRotation = Quaternion.LookRotation(-newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized, transform.up); + transform.rotation = newRotation; + break; + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsDown: + AssignNewTransformUp(-newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized); + break; + case InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.gameobjectsLeft: + AssignNewTransformRight(-newDirection_toAHelperPoint_inUnitsOfGlobalSpace_normalized); + break; + default: + break; + } + lastGlobalRotationOfThisGameobject_thatTheSplineKnowsOf = transform.rotation; + } + } + } + + void AssignNewTransformUp(Vector3 newUp_normalized) + { + Vector3 newForward = UtilitiesDXXL_Math.Get_vector_projectedAlongOtherVectorToPerpToOtherVector(transform.forward, newUp_normalized, false); + newForward = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(newForward); + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(newForward) > 0.0001f) + { + Quaternion newRotation = Quaternion.LookRotation(newForward, newUp_normalized); + transform.rotation = newRotation; + } + else + { + transform.up = newUp_normalized; + } + } + + void AssignNewTransformRight(Vector3 newRight_normalized) + { + Vector3 newForward = UtilitiesDXXL_Math.Get_vector_projectedAlongOtherVectorToPerpToOtherVector(transform.forward, newRight_normalized, false); + newForward = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(newForward); + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(newForward) > 0.0001f) + { + Vector3 newUp = Vector3.Cross(newForward, newRight_normalized); + Quaternion newRotation = Quaternion.LookRotation(newForward, newUp); + transform.rotation = newRotation; + } + else + { + transform.right = newRight_normalized; + } + } + + bool TryDestroyThisComponentIfItWasManuallyCreated() + { + if (componentHasBeenManuallyCreated) + { + Debug.LogError("'DrawXXLSplineConnection' should not be created manually. It will be automatically created and destroyed by the 'Bezier Spline Drawer' component."); + DestroyThisComponent(false); + return true; + } + else + { + return false; + } + } + + bool TryEarlyReturnAndSelfDeleteBecauseReferenceGotLost() + { + if (bezierSplineDrawer_thatHasReferencedThisGameobject == null) + { + //-> "bezierSplineDrawer_thatHasReferencedThisGameobject" has been deleted + //-> actually this component could also be deleted now, but the problem is: If the deletion of "bezierSplineDrawer_thatHasReferencedThisGameobject" is reverted via the editors "Undo"-functionality, then the retrieved bezierSplineDrawer doesn't have this spline connection anymore and the "undo" is not complete in this regard. + //-> see also more detialled explantation in "subPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled()" + //-> The connection component here stays inactive as long as it doesn't have a "bezierSplineDrawer_thatHasReferencedThisGameobject" + + DestroyThisComponent(false); + return true; + } + else + { + InternalDXXL_BezierControlSubPoint bezierSubPoint = Get_bezierSubPoint_thatHasReferencedThisGameobject(); + if (bezierSubPoint == null) + { + UtilitiesDXXL_Log.PrintErrorCode("52-" + bezierSplineDrawer_thatHasReferencedThisGameobject.listOfControlPointTriplets.Count + "-" + i_ofControlPointTriplet_thisGameobjectIsBoundTo); + DestroyThisComponent(false); + return true; + } + else + { + if (bezierSubPoint.bezierSplineDrawer_thisSubPointIsPartOf != bezierSplineDrawer_thatHasReferencedThisGameobject) + { + UtilitiesDXXL_Log.PrintErrorCode("53-" + bezierSubPoint.bezierSplineDrawer_thisSubPointIsPartOf + "-" + bezierSplineDrawer_thatHasReferencedThisGameobject); + DestroyThisComponent(false); + return true; + } + else + { + if (bezierSubPoint.boundGameobject != this.gameObject) + { + //-> case 1: the gameobject that carries this connection-component has been copied. + //-> case 2: connection-component has been manually copied to another gameobject + //-> the connection gets deleted here. It stays only at the pre-copy-gameobject + //-> case 3: some "copy spline component -> undo -> redo" to-and-fro arrives here, see also + //-> see also more detialled explantation in "subPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled()" + + DestroyThisComponent(false); + return true; + } + else + { + //The following "if (bezierSubPoint.connectionComponent_onBoundGameobject != this)"-check gives false evaluations in some cases. + //Observed case: + //-> Add boundGamobject(this) to a spline control point. + //-> Then delete the bound gameobject. + //-> Then the deletion via the editors "undo"-functionality. + //-> Then "bezierSubPoint.connectionComponent_onBoundGameobject" is "null" (probably due to the Unity bug, see explanation in "subPoint.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled()" + //-> Despite "bezierSubPoint.connectionComponent_onBoundGameobject" beeing "null" and "this" not beeing "null" the check "if (bezierSubPoint.connectionComponent_onBoundGameobject != this)" results in "is the same". + //-> It has probably to do with Unitys way of serialization and undo + + if (bezierSubPoint.connectionComponent_onBoundGameobject != this) + { + //-> this connection component has been manually copied as duplicate to the same gameobject + //-> some delete/undo/redo-to and fro may also arrive here + DestroyThisComponent(false); + return true; + } + else + { + if (bezierSubPoint.connectionComponent_onBoundGameobject == null) //-> additional check as double bottom that fixes the comparison error described above + { + DestroyThisComponent(false); + return true; + } + else + { + if (bezierSubPoint.i_ofContainingControlPoint_insideControlPointsList != i_ofControlPointTriplet_thisGameobjectIsBoundTo) + { + UtilitiesDXXL_Log.PrintErrorCode("54-" + bezierSplineDrawer_thatHasReferencedThisGameobject.listOfControlPointTriplets.Count + "-" + i_ofControlPointTriplet_thisGameobjectIsBoundTo + "-" + bezierSubPoint.i_ofContainingControlPoint_insideControlPointsList); + DestroyThisComponent(false); + return true; + } + else + { + if (bezierSubPoint.subPointType != subPointType_whereThisGameobjectIsBoundTo) + { + UtilitiesDXXL_Log.PrintErrorCode("55-" + bezierSplineDrawer_thatHasReferencedThisGameobject.listOfControlPointTriplets.Count + "-" + i_ofControlPointTriplet_thisGameobjectIsBoundTo + "-" + bezierSubPoint.subPointType + "-" + subPointType_whereThisGameobjectIsBoundTo); + DestroyThisComponent(false); + return true; + } + else + { + return false; + } + } + } + } + } + } + } + } + } + + void DestroyThisComponent(bool withDestructionUndo) + { + //Destroying only the component, but keeping the gameObject and all other components: + if (Application.isPlaying) + { + Destroy(this); + } + else + { + if (withDestructionUndo) + { +#if UNITY_EDITOR + UnityEditor.Undo.DestroyObjectImmediate(this); +#else + //How can the code arrive here? + UtilitiesDXXL_Log.PrintErrorCode("83-"+ Application.isPlaying); + Destroy(this); +#endif + } + else + { + DestroyImmediate(this); + } + } + } + + bool CheckIf_thisConnectionComponentIsActive() + { + if (bezierSplineDrawer_thatHasReferencedThisGameobject != null) //this is only due to the undo-mechanic-selfDestruction-delay + { + return isActiveAndEnabled; + } + return false; + } + + } + +} \ No newline at end of file diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSplineConnection.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSplineConnection.cs.meta new file mode 100644 index 0000000..addb876 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXLSplineConnection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 166f076e426504e47a75ca709be57ce8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXL_LinesManager.cs b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXL_LinesManager.cs new file mode 100644 index 0000000..0a59a42 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXL_LinesManager.cs @@ -0,0 +1,3344 @@ +namespace DrawXXL +{ + using UnityEngine; + using UnityEngine.Rendering; + using System.Collections.Generic; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Internal Not For Manual Creation/Draw XXL Lines Manager")] + [DefaultExecutionOrder(32190)] //negative numers are early, positive numbers are late. Range is till (incl) 32000 to both negative and positive direction. + [ExecuteInEditMode] + public class DrawXXL_LinesManager : MonoBehaviour + { + //This class contains (beside other things) a "virtual gizmo cylce mechanic". Details see here: + //-> It is just communicating to the static line counter, when a new OnDrawGizmo-cylce starts (via "UtilitiesDXXL_Components.ReportOnDrawGizmosCycleOfAMonoBehaviour()"). With that information the static line counter knows when to reset the lineCount. + //-> It has no effect on the functionality if this component exists multiple times in the scene, except that "gizmoLineCountManagerAutomaticallyRepaintsRendering" is "true", if ONE of the components has it as "true" + //-> Also this component has two further functions beside acting as "count" manager: + //---> Continuously repainting the Editor Windows depending on "gizmoLineCountManagerAutomaticallyRepaintsRendering" (see explanation in the inspector of the component) + //---> The "DrawBasics.UsedUnityLineDrawingMethod.debugLinesInPlayMode_gizmoLinesInEditModeAndPlaymodePauses"-mechanic depends on the "UtilitiesDXXL_Components.virtualGizmoCycleCount"-cycle, which is triggered here with this component + //-> Except for the "continuous repaint"-functionality any other drawer component already has the functionality implicitly inside, so if you can renounce of the continuous repaint and have already any drawer component in the scene, then you don't need this component here. + + /// ------- + + //-> when a "DrawXXL_LinesManager" gameobject/component is created via "automatic()" during playmode, then it is not there anymore after exiting playmode. "DrawBasics.CreateGizmoLineCountManager()" has to be called again (outside playmode) in this case. + //-> The whole "DrawXXL_LinesManager" mechanic is for edit mode, so this shouldn't be a problem: It doesn't make much sense to create it during playmode + //-> The exception from this is "pause mode" (which is actually "during playmode", but in respect to line drawing it behaves like edit mode). A user can create a counter component during pause mode, and it will not be there anymore when he leaves playmode. + //-> The irritation there is probably not big, because when the user knows how to draw in pause mode, then he knows about "OnDrawGizmos()" and therefore is easily able to create the counter component once more outside playmode. + //-> As an alternative the settings file (which is persistent during playmode exit) could hold a flag to indicate that the counter component should automatically be created after exit playmode, if the counter component has been created by the user during playmode, but then probably more confusing setting options could be needed, because this approach would create the problem that deleting the counter component gets more complicated, because it would get autocreated all the time. + +#if UNITY_EDITOR + [SerializeField] bool gizmoLineCountManagerAutomaticallyRepaintsRendering = false; //this setting is declared in the component instead of as global static field in "DrawBasics", so that it is persistent on domain reloads (that means "on scipt reloads" and "on enter playmode") +#endif + + public List lineStartAndEndPoints_asMeshVertices; + public List lineStartAndEndPoints_asMeshVertices_overlay; + public List lineStartAndEndPoints_asMeshVertices_delayed_version1; //"_version1" and "_version2" exists to prevent high numbers of "list.Insert()" and "list.RemoveAt()", which are expensive for lists. + public List lineStartAndEndPoints_asMeshVertices_delayed_version2; + public List colors_perMeshVertex; + public List colors_perMeshVertex_overlay; + public List colors_perMeshVertex_delayed_version1; + public List colors_perMeshVertex_delayed_version2; + public List time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version1; + public List time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version2; + public int activeDurationCacheVersion; + public List indicesOfTheMeshVertices_thatBuildUpTheSingleLinesOfTheMesh; + Mesh meshThatContainsTheDrawnLines; + MeshRenderer meshRenderer; + Material linesMaterial_hideable; + Material linesMaterial_overlay; + + public static DrawXXL_LinesManager instance; + public static void TryCreate() + { + if (instance == null) + { + TryFindExistingNonReferencedInstance(); + if (instance == null) + { + GameObject hosting_gameObject = new GameObject("Draw XXL Lines Manager"); + instance = hosting_gameObject.AddComponent(); + } + + if (Application.isPlaying) + { + RecreateMesh(); + RecreateCacheListsForMesh(); + } + } + else + { + if (Application.isPlaying) + { + if (instance.meshThatContainsTheDrawnLines == null) { RecreateMesh(); } + if (instance.lineStartAndEndPoints_asMeshVertices == null) { RecreateCacheListsForMesh(); } + } + } + } + + static void RecreateMesh() + { + //-> ".instance" is never null here + //-> "isPlaymode" is always true here + //-> "DrawBasics.usedUnityLineDrawingMethod == disabled" never arrives here + + instance.meshThatContainsTheDrawnLines = new Mesh(); + instance.meshThatContainsTheDrawnLines.name = "Draw XXL lines"; + instance.meshThatContainsTheDrawnLines.MarkDynamic(); + + MeshFilter meshFilter = instance.gameObject.AddComponent(); + meshFilter.mesh = instance.meshThatContainsTheDrawnLines; + + instance.meshRenderer = instance.gameObject.AddComponent(); + instance.linesMaterial_hideable = new Material(Resources.Load("DrawXXL_lines") as Shader); + //instance.linesMaterial_overlay = new Material(Resources.Load("DrawXXL_lines_overlay") as Shader); //the current overlay shader for builds may work well in many situations, but there are setups (Render Pipeline? Image Effects?) where it produces unforseen effects. + instance.linesMaterial_overlay = instance.linesMaterial_hideable; //<-to activate an overlay shader for meshes: comment this line out, and comment the preceding line in. But then still lines that have a "durationInSeconds" bigger than 0 may get assigned to the wrong hideable-vs-overlay-chunk. + instance.meshRenderer.material = instance.linesMaterial_hideable; + instance.meshRenderer.receiveShadows = false; + instance.meshRenderer.shadowCastingMode = ShadowCastingMode.Off; + instance.meshRenderer.lightProbeUsage = LightProbeUsage.Off; + } + + static void RecreateCacheListsForMesh() + { + //-> ".instance" is never null here + //-> "isPlaymode" is always true here + //-> "DrawBasics.usedUnityLineDrawingMethod == disabled" never arrives here + + instance.lineStartAndEndPoints_asMeshVertices = new List(); + instance.colors_perMeshVertex = new List(); + instance.indicesOfTheMeshVertices_thatBuildUpTheSingleLinesOfTheMesh = new List(); + instance.CreateReusableIndexList(); + instance.lineStartAndEndPoints_asMeshVertices_overlay = new List(); + instance.colors_perMeshVertex_overlay = new List(); + instance.lineStartAndEndPoints_asMeshVertices_delayed_version1 = new List(); + instance.lineStartAndEndPoints_asMeshVertices_delayed_version2 = new List(); + instance.colors_perMeshVertex_delayed_version1 = new List(); + instance.colors_perMeshVertex_delayed_version2 = new List(); + instance.time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version1 = new List(); + instance.time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version2 = new List(); + + instance.activeDurationCacheVersion = 1; + } + + void CreateReusableIndexList() + { + for (int i = 0; i < maxNumberOfIndices_perSubMesh; i++) + { + indicesOfTheMeshVertices_thatBuildUpTheSingleLinesOfTheMesh.Add(i); + } + } + + public static bool Exists() + { + if (instance == null) + { + //-> this is expensive, but is anyway only called in error-log-situations (or other seldom situations), so not during normal operation + //-> it is necessary because the static "instance" reference is wiped often due to Unitys save/load serialization system + TryFindExistingNonReferencedInstance(); + return (instance != null); + } + else + { + return true; + } + } + + static void TryFindExistingNonReferencedInstance() + { + instance = UnityEngine.Object.FindObjectOfType(); + } + +#if UNITY_EDITOR + [UnityEditor.InitializeOnLoadMethod] + static void ScriptDomainHasBeenReloaded() + { + if (Exists()) + { + //Why doing this? -> see notes in "Start()" + UtilitiesDXXL_Components.ReportOnDrawGizmosCycleOfAMonoBehaviour(instance.GetInstanceID()); + } + } +#endif + + void Awake() + { +#if UNITY_EDITOR + UtilitiesDXXL_Components.ExpandComponentInInspector(this); +#endif + } + + void Start() + { +#if UNITY_EDITOR + UtilitiesDXXL_Components.ExpandComponentInInspector(this); + + DXXLWrapperForUntiysBuildInDrawLines.ResetLinesPerFrameCounter(); //-> start with a defined line counter + + //Calling "ReportOnDrawGizmosCycleOfAMonoBehaviour" also on "Start()", because: + //-> Other components that draw lines could be fired earlier than this component inside the OnDrawGizmo-cylce. + //-> In this case the first frame after StartPlaymode is not covered by the line counting mechanic (because the virtualGizmoCycle only increments when a component "comes back", so it has to come at least twice. So this manager component could produce its first gizmo cycle not before the end of the second frame of his existence). + //-> This can result in false positive "Max lines exceeded" error logs in the first frame. + //-> Calling it here prevents these false positives + //-> The call in "ScriptDomainHasBeenReloaded()" may make this here obsolete though, but it doesn't harm to call it here again + UtilitiesDXXL_Components.ReportOnDrawGizmosCycleOfAMonoBehaviour(this.GetInstanceID()); +#endif + } + + void OnEnable() + { +#if UNITY_EDITOR + UtilitiesDXXL_Components.ExpandComponentInInspector(this); +#endif + } + + void Update() + { +#if UNITY_EDITOR + UtilitiesDXXL_Components.ExpandComponentInInspector(this); +#else + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.wireMesh) + { + //without this the mesh in builds will not be cleared for cases where there is a drawing pause. + DXXLWrapperForUntiysBuildInDrawLines.TryResetLinesPerFrameCounter(); + } +#endif + } + + void LateUpdate() + { + DrawSheduledScreenspaceShapes(); //should be executed BEFORE "TryUpdateMesh_fromCachedLines()", otherwise sheduled screenspace lines will not be included in the displayed wire mesh. + TryUpdateMesh_fromCachedLines(); + } + + void OnDrawGizmos() + { +#if UNITY_EDITOR + UtilitiesDXXL_Components.ExpandComponentInInspector(this); + if (gizmoLineCountManagerAutomaticallyRepaintsRendering) { UtilitiesDXXL_Components.currentVirtualOnDrawGizmoCycle_shouldRepaintAllViews = true; } + UtilitiesDXXL_Components.ReportOnDrawGizmosCycleOfAMonoBehaviour(this.GetInstanceID()); +#endif + } + + //Concerning "maxNumberOfIndices_perSubMesh": + //-> This seems to be wrongly formulated in the Unity documenation + //-> It self-contradictatoringly states that "to achieve meshes that are larger than 65535 vertices while using 16 bit index buffers", but also "maximum value supported in the index buffer is 65535". + //-> So I guess they mean this: + //---> maximum vertices is "65536" + //---> highest allowed vertex index is "65535" + //---> to be on the safe side I use "65000" + int maxNumberOfIndices_perSubMesh = 65000; + int maxSubMeshesOf65000IndexesEach = 30; //lines have to vertices, so the limit of "65535" means only (approximately) "33000 lines". //this setting of "maxSubMeshesOf65535IndexesEach" overdefines together with "UtilitiesDXXL_DrawBasics.maxMaxAllowedDrawnLinesPerFrame". + int numberOfVertices_combinedFromHiddenAndOverlayMeshes; + int i_startOfUnhiddenOverlayLines; + List subMeshs = new List(); + + void TryUpdateMesh_fromCachedLines() + { + if (meshThatContainsTheDrawnLines != null) + { + if (lineStartAndEndPoints_asMeshVertices != null) + { + Combine_hideableAndOverlayLines_intoTheSameLists(); + + meshThatContainsTheDrawnLines.SetVertices(lineStartAndEndPoints_asMeshVertices); //-> combined "hidden"+"overlay" into one list + meshThatContainsTheDrawnLines.SetColors(colors_perMeshVertex); //-> combined "hidden"+"overlay" into one list + + ConfigureTheSubMeshs(); + FillTheSubMeshsToTheMesh(); + RecreateMaterialsArrayToFitTheSubMeshes(); + } + } + } + + void Combine_hideableAndOverlayLines_intoTheSameLists() + { + meshThatContainsTheDrawnLines.Clear(); + + //Adding the unhiddenOverlay-lines: + i_startOfUnhiddenOverlayLines = lineStartAndEndPoints_asMeshVertices.Count; + for (int i_inOverlayList = 0; i_inOverlayList < lineStartAndEndPoints_asMeshVertices_overlay.Count; i_inOverlayList++) + { + lineStartAndEndPoints_asMeshVertices.Add(lineStartAndEndPoints_asMeshVertices_overlay[i_inOverlayList]); + colors_perMeshVertex.Add(colors_perMeshVertex_overlay[i_inOverlayList]); + } + + //Very obscure bug: + //-> only affects drawing IN BUILDS + //-> only affects drawing TO SCREENSPACE + //-> drawing to screenspace in builds currently doesn't work due to the following line of code. + //-> the code execution just stops with this line, despite this line not doing anything complicated + //-> it is no exception + numberOfVertices_combinedFromHiddenAndOverlayMeshes = lineStartAndEndPoints_asMeshVertices.Count; + } + + void ConfigureTheSubMeshs() + { + subMeshs.Clear(); + int i_startOfCurrentlyTreatedHideableSubMesh = 0; + int combinedLengthOfAllFull65000OverlayMeshesUpUntilNow = 0; + + for (int i_subMesh = 0; i_subMesh < maxSubMeshesOf65000IndexesEach; i_subMesh++) + { + InternalDXXL_SubMeshIdentifier currentlyAddedSubMesh = new InternalDXXL_SubMeshIdentifier(); + if (i_startOfCurrentlyTreatedHideableSubMesh < i_startOfUnhiddenOverlayLines) + { + //hideable mesh: + currentlyAddedSubMesh.depthTestType = InternalDXXL_SubMeshIdentifier.DepthTestType.meshIsHidableBehindOtherGeometry; + currentlyAddedSubMesh.i_startOfSubMesh_insideTheFinalVertsList = maxNumberOfIndices_perSubMesh * i_subMesh; + + if ((i_startOfCurrentlyTreatedHideableSubMesh + maxNumberOfIndices_perSubMesh) < i_startOfUnhiddenOverlayLines) + { + //hideable mesh (with max possible amount (65000) of verticesPerSubMesh): + currentlyAddedSubMesh.lengthOfSubMesh_inVertices = maxNumberOfIndices_perSubMesh; + } + else + { + //last hideable mesh (with arbitrarily decresed number of vertices): + currentlyAddedSubMesh.lengthOfSubMesh_inVertices = i_startOfUnhiddenOverlayLines - i_startOfCurrentlyTreatedHideableSubMesh; + } + i_startOfCurrentlyTreatedHideableSubMesh += maxNumberOfIndices_perSubMesh; + } + else + { + currentlyAddedSubMesh.i_startOfSubMesh_insideTheFinalVertsList = i_startOfUnhiddenOverlayLines + combinedLengthOfAllFull65000OverlayMeshesUpUntilNow; + if (currentlyAddedSubMesh.i_startOfSubMesh_insideTheFinalVertsList < numberOfVertices_combinedFromHiddenAndOverlayMeshes) + { + //overlaying mesh: + currentlyAddedSubMesh.depthTestType = InternalDXXL_SubMeshIdentifier.DepthTestType.meshAlwaysOverlaysOtherGeometry; + + if ((currentlyAddedSubMesh.i_startOfSubMesh_insideTheFinalVertsList + maxNumberOfIndices_perSubMesh) < numberOfVertices_combinedFromHiddenAndOverlayMeshes) + { + //overlaying mesh (with max possible amount (65000) of verticesPerSubMesh): + currentlyAddedSubMesh.lengthOfSubMesh_inVertices = maxNumberOfIndices_perSubMesh; + } + else + { + //overlaying mesh (with arbitrarily decresed number of vertices): + currentlyAddedSubMesh.lengthOfSubMesh_inVertices = numberOfVertices_combinedFromHiddenAndOverlayMeshes - currentlyAddedSubMesh.i_startOfSubMesh_insideTheFinalVertsList; + } + combinedLengthOfAllFull65000OverlayMeshesUpUntilNow += maxNumberOfIndices_perSubMesh; + } + else + { + break; + } + } + + subMeshs.Add(currentlyAddedSubMesh); + } + } + + void FillTheSubMeshsToTheMesh() + { + MeshTopology topology = MeshTopology.Lines; + bool calculateBounds = true; + meshThatContainsTheDrawnLines.subMeshCount = subMeshs.Count; + + for (int i_subMesh = 0; i_subMesh < subMeshs.Count; i_subMesh++) + { + int indicesStart = 0; + int indicesLength = subMeshs[i_subMesh].lengthOfSubMesh_inVertices; + int baseVertex = subMeshs[i_subMesh].i_startOfSubMesh_insideTheFinalVertsList; + + meshThatContainsTheDrawnLines.SetIndices(indicesOfTheMeshVertices_thatBuildUpTheSingleLinesOfTheMesh, indicesStart, indicesLength, topology, i_subMesh, calculateBounds, baseVertex); + } + } + + void RecreateMaterialsArrayToFitTheSubMeshes() + { + if (meshRenderer == null) + { + meshRenderer = gameObject.AddComponent(); + linesMaterial_hideable = new Material(Resources.Load("DrawXXL_lines") as Shader); + linesMaterial_overlay = new Material(Resources.Load("DrawXXL_lines_overlay") as Shader); + } + + Material[] materialsForAllSubMeshs = new Material[subMeshs.Count]; + for (int i_subMesh = 0; i_subMesh < subMeshs.Count; i_subMesh++) + { + switch (subMeshs[i_subMesh].depthTestType) + { + case InternalDXXL_SubMeshIdentifier.DepthTestType.meshIsHidableBehindOtherGeometry: + materialsForAllSubMeshs[i_subMesh] = linesMaterial_hideable; + break; + case InternalDXXL_SubMeshIdentifier.DepthTestType.meshAlwaysOverlaysOtherGeometry: + materialsForAllSubMeshs[i_subMesh] = linesMaterial_overlay; + break; + default: + break; + } + } + meshRenderer.materials = materialsForAllSubMeshs; + } + + public bool noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem = true; //details: See notes inside the "ScreenspaceShedulingStrucs" script file + public bool atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = false; + + public List listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace = new List(); + + public List listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam = new List(); + public List listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam = new List(); + public List listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam = new List(); + public List listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam = new List(); + public List listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam = new List(); + public List listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam = new List(); + public List listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam = new List(); + public List listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam = new List(); + + public List listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam = new List(); + public List listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam = new List(); + public List listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam = new List(); + + public List listOfSheduled_ArrayOfBool_screenspace_3Dpos = new List(); + public List listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ArrayOfBool_screenspace_2Dpos = new List(); + public List listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam = new List(); + public List listOfSheduled_ListOfBool_screenspace_3Dpos = new List(); + public List listOfSheduled_ListOfBool_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ListOfBool_screenspace_2Dpos = new List(); + public List listOfSheduled_ListOfBool_screenspace_2Dpos_cam = new List(); + + public List listOfSheduled_ArrayOfInt_screenspace_3Dpos = new List(); + public List listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ArrayOfInt_screenspace_2Dpos = new List(); + public List listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam = new List(); + public List listOfSheduled_ListOfInt_screenspace_3Dpos = new List(); + public List listOfSheduled_ListOfInt_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ListOfInt_screenspace_2Dpos = new List(); + public List listOfSheduled_ListOfInt_screenspace_2Dpos_cam = new List(); + + public List listOfSheduled_ArrayOfFloat_screenspace_3Dpos = new List(); + public List listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ArrayOfFloat_screenspace_2Dpos = new List(); + public List listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam = new List(); + public List listOfSheduled_ListOfFloat_screenspace_3Dpos = new List(); + public List listOfSheduled_ListOfFloat_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ListOfFloat_screenspace_2Dpos = new List(); + public List listOfSheduled_ListOfFloat_screenspace_2Dpos_cam = new List(); + + public List listOfSheduled_ArrayOfString_screenspace_3Dpos = new List(); + public List listOfSheduled_ArrayOfString_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ArrayOfString_screenspace_2Dpos = new List(); + public List listOfSheduled_ArrayOfString_screenspace_2Dpos_cam = new List(); + public List listOfSheduled_ListOfString_screenspace_3Dpos = new List(); + public List listOfSheduled_ListOfString_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ListOfString_screenspace_2Dpos = new List(); + public List listOfSheduled_ListOfString_screenspace_2Dpos_cam = new List(); + + public List listOfSheduled_ArrayOfVector2_screenspace_3Dpos = new List(); + public List listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ArrayOfVector2_screenspace_2Dpos = new List(); + public List listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam = new List(); + public List listOfSheduled_ListOfVector2_screenspace_3Dpos = new List(); + public List listOfSheduled_ListOfVector2_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ListOfVector2_screenspace_2Dpos = new List(); + public List listOfSheduled_ListOfVector2_screenspace_2Dpos_cam = new List(); + + public List listOfSheduled_ArrayOfVector3_screenspace_3Dpos = new List(); + public List listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ArrayOfVector3_screenspace_2Dpos = new List(); + public List listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam = new List(); + public List listOfSheduled_ListOfVector3_screenspace_3Dpos = new List(); + public List listOfSheduled_ListOfVector3_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ListOfVector3_screenspace_2Dpos = new List(); + public List listOfSheduled_ListOfVector3_screenspace_2Dpos_cam = new List(); + + public List listOfSheduled_ArrayOfVector4_screenspace_3Dpos = new List(); + public List listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ArrayOfVector4_screenspace_2Dpos = new List(); + public List listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam = new List(); + public List listOfSheduled_ListOfVector4_screenspace_3Dpos = new List(); + public List listOfSheduled_ListOfVector4_screenspace_3Dpos_cam = new List(); + public List listOfSheduled_ListOfVector4_screenspace_2Dpos = new List(); + public List listOfSheduled_ListOfVector4_screenspace_2Dpos_cam = new List(); + + public List listOfSheduled_TagGameObjectScreenspace = new List(); + public List listOfSheduled_GridScreenspace = new List(); + public List listOfSheduled_BoolDisplayerScreenspace_3Dpos = new List(); + public List listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam = new List(); + public List listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam = new List(); + + public List listOfSheduled_LogsOnScreen = new List(); + + public List listOfSheduled_ScreenspaceLine = new List(); + public List listOfSheduled_ScreenspaceRay = new List(); + public List listOfSheduled_ScreenspaceLineFrom = new List(); + public List listOfSheduled_ScreenspaceLineTo = new List(); + public List listOfSheduled_ScreenspaceLineColorFade = new List(); + public List listOfSheduled_ScreenspaceRayColorFade = new List(); + public List listOfSheduled_ScreenspaceLineFrom_withColorFade = new List(); + public List listOfSheduled_ScreenspaceLineTo_withColorFade = new List(); + public List listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam = new List(); + public List listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam = new List(); + public List listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam = new List(); + public List listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam = new List(); + public List listOfSheduled_ScreenspaceLineString_array_cam = new List(); + public List listOfSheduled_ScreenspaceLineString_list_cam = new List(); + public List listOfSheduled_ScreenspaceLineStringColorFade_array_cam = new List(); + public List listOfSheduled_ScreenspaceLineStringColorFade_list_cam = new List(); + public List listOfSheduled_ScreenspaceShape_3Dpos = new List(); + public List listOfSheduled_ScreenspaceShape_3Dpos_cam = new List(); + public List listOfSheduled_ScreenspaceShape_2Dpos_cam = new List(); + public List listOfSheduled_ScreenspaceRectangle = new List(); + public List listOfSheduled_ScreenspaceBox_rect_cam = new List(); + public List listOfSheduled_ScreenspaceBox_3Dpos_vec = new List(); + public List listOfSheduled_ScreenspaceBox_3Dpos_vec_cam = new List(); + public List listOfSheduled_ScreenspaceBox_2Dpos_vec_cam = new List(); + public List listOfSheduled_ScreenspaceCircle_rect_cam = new List(); + public List listOfSheduled_ScreenspaceCircle_3Dpos_vecRad = new List(); + public List listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam = new List(); + public List listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam = new List(); + public List listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos = new List(); + public List listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam = new List(); + public List listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam = new List(); + public List listOfSheduled_ScreenspaceCapsule_rect_cam = new List(); + public List listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize = new List(); + public List listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam = new List(); + public List listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam = new List(); + public List listOfSheduled_ScreenspacePointArray = new List(); + public List listOfSheduled_ScreenspacePointList = new List(); + public List listOfSheduled_ScreenspacePoint = new List(); + public List listOfSheduled_ScreenspacePoint_prioText_cam = new List(); + public List listOfSheduled_ScreenspacePointTag_3Dpos = new List(); + public List listOfSheduled_ScreenspacePointTag_3Dpos_cam = new List(); + public List listOfSheduled_ScreenspacePointTag_2Dpos_cam = new List(); + public List listOfSheduled_ScreenspaceVectorFrom = new List(); + public List listOfSheduled_ScreenspaceVectorTo = new List(); + public List listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam = new List(); + public List listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam = new List(); + public List listOfSheduled_ScreenspaceIcon_3Dpos = new List(); + public List listOfSheduled_ScreenspaceIcon_3Dpos_cam = new List(); + public List listOfSheduled_ScreenspaceIcon_2Dpos_cam = new List(); + public List listOfSheduled_ScreenspaceDot_3Dpos = new List(); + public List listOfSheduled_ScreenspaceDot_3Dpos_cam = new List(); + public List listOfSheduled_ScreenspaceDot_2Dpos_cam = new List(); + public List listOfSheduled_ScreenspaceMovingArrowsRay = new List(); + public List listOfSheduled_ScreenspaceMovingArrowsLine = new List(); + public List listOfSheduled_ScreenspaceRayWithAlternatingColors = new List(); + public List listOfSheduled_ScreenspaceLineWithAlternatingColors = new List(); + public List listOfSheduled_ScreenspaceBlinkingRay = new List(); + public List listOfSheduled_ScreenspaceBlinkingLine = new List(); + public List listOfSheduled_ScreenspaceRayUnderTension = new List(); + public List listOfSheduled_ScreenspaceLineUnderTension = new List(); + public List listOfSheduled_ScreenspaceVisualizeAutomaticCameraForDrawing = new List(); + + public List listOfSheduled_DrawScreenspaceChart = new List(); + public List listOfSheduled_DrawScreenspacePieChart = new List(); + + void DrawSheduledScreenspaceShapes() + { + noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem = false; + try + { + for (int i = 0; i < listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace.Count; i++) + { + listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace[i].Draw(); + } + listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace.Clear(); + + if (atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate) + { + for (int i = 0; i < listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam.Count; i++) + { + DrawText.WriteScreenspace(listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].screenCamera, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].text, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].position_in3DWorldspace, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].color, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].size_relToViewportHeight, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].textDirection, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].textAnchor, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].autoLineBreakAtViewportBorder, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].autoLineBreakWidth_relToViewportWidth, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].autoFlipTextToPreventUpsideDown, listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam[i].durationInSec); + } + listOfSheduled_TextScreenspace_3Dpos_dirViaVec_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam.Count; i++) + { + DrawText.WriteScreenspace(listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].screenCamera, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].text, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].position_in2DViewportSpace, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].color, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].size_relToViewportHeight, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].textDirection, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].textAnchor, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].autoLineBreakAtViewportBorder, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].autoLineBreakWidth_relToViewportWidth, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].autoFlipTextToPreventUpsideDown, listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam[i].durationInSec); + } + listOfSheduled_TextScreenspace_2Dpos_dirViaVec_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam.Count; i++) + { + DrawText.WriteScreenspaceFramed(listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].screenCamera, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].text, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].position_in3DWorldspace, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].color, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].size_relToViewportHeight, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].textDirection, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].textAnchor, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].enclosingBoxLineStyle, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].enclosingBox_lineWidth_relToTextSize, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].enclosingBox_paddingSize_relToTextSize, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].autoLineBreakAtViewportBorder, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].autoLineBreakWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].autoFlipTextToPreventUpsideDown, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam[i].durationInSec); + } + listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaVec_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam.Count; i++) + { + DrawText.WriteScreenspaceFramed(listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].screenCamera, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].text, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].position_in2DViewportSpace, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].color, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].size_relToViewportHeight, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].textDirection, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].textAnchor, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].enclosingBoxLineStyle, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].enclosingBox_lineWidth_relToTextSize, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].enclosingBox_paddingSize_relToTextSize, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].autoLineBreakAtViewportBorder, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].autoLineBreakWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].autoFlipTextToPreventUpsideDown, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam[i].durationInSec); + } + listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaVec_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam.Count; i++) + { + DrawText.WriteScreenspace(listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].screenCamera, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].text, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].position_in3DWorldspace, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].color, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].size_relToViewportHeight, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].zRotationDegCC, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].textAnchor, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].autoLineBreakAtViewportBorder, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].autoLineBreakWidth_relToViewportWidth, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].autoFlipTextToPreventUpsideDown, listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam[i].durationInSec); + } + listOfSheduled_TextScreenspace_3Dpos_dirViaAngle_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam.Count; i++) + { + DrawText.WriteScreenspace(listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].screenCamera, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].text, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].position_in2DViewportSpace, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].color, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].size_relToViewportHeight, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].zRotationDegCC, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].textAnchor, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].autoLineBreakAtViewportBorder, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].autoLineBreakWidth_relToViewportWidth, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].autoFlipTextToPreventUpsideDown, listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam[i].durationInSec); + } + listOfSheduled_TextScreenspace_2Dpos_dirViaAngle_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam.Count; i++) + { + DrawText.WriteScreenspaceFramed(listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].screenCamera, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].text, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].position_in3DWorldspace, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].color, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].size_relToViewportHeight, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].zRotationDegCC, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].textAnchor, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].enclosingBoxLineStyle, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].enclosingBox_lineWidth_relToTextSize, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].enclosingBox_paddingSize_relToTextSize, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].autoLineBreakAtViewportBorder, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].autoLineBreakWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].autoFlipTextToPreventUpsideDown, listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam[i].durationInSec); + } + listOfSheduled_TextScreenspaceFramed_3Dpos_dirViaAngle_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam.Count; i++) + { + DrawText.WriteScreenspaceFramed(listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].screenCamera, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].text, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].position_in2DViewportSpace, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].color, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].size_relToViewportHeight, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].zRotationDegCC, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].textAnchor, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].enclosingBoxLineStyle, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].enclosingBox_lineWidth_relToTextSize, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].enclosingBox_paddingSize_relToTextSize, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].autoLineBreakAtViewportBorder, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].autoLineBreakWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].autoFlipTextToPreventUpsideDown, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].durationInSec); + } + listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam.Count; i++) + { + DrawText.WriteScreenspaceFramed(listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].screenCamera, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].text, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].position_in2DViewportSpace, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].color, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].size_relToViewportHeight, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].zRotationDegCC, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].textAnchor, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].enclosingBoxLineStyle, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].enclosingBox_lineWidth_relToTextSize, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].enclosingBox_paddingSize_relToTextSize, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].autoLineBreakAtViewportBorder, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].autoLineBreakWidth_relToViewportWidth, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].autoFlipTextToPreventUpsideDown, listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam[i].durationInSec); + } + listOfSheduled_TextScreenspaceFramed_2Dpos_dirViaAngle_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam.Count; i++) + { + DrawText.WriteOnCircleScreenspace(listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam[i].screenCamera, listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam[i].text, listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam[i].textStartPos, listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam[i].circleCenterPosition, listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam[i].color, listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam[i].size_relToViewportHeight, listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam[i].textAnchor, listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam[i].autoLineBreakAngleDeg, listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam[i].durationInSec); + } + listOfSheduled_TextOnCircleScreenspace_viaStartPos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam.Count; i++) + { + DrawText.WriteOnCircleScreenspace(listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam[i].screenCamera, listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam[i].text, listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam[i].circleCenterPosition, listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam[i].radius_relToViewportHeight, listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam[i].color, listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam[i].size_relToViewportHeight, listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam[i].textsInitialUp, listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam[i].textAnchor, listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam[i].autoLineBreakAngleDeg, listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam[i].durationInSec); + } + listOfSheduled_TextOnCircleScreenspace_dirViaVecUp_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam.Count; i++) + { + DrawText.WriteOnCircleScreenspace(listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam[i].screenCamera, listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam[i].text, listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam[i].circleCenterPosition, listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam[i].radius_relToViewportHeight, listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam[i].color, listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam[i].size_relToViewportHeight, listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam[i].initialTextDirection_as_zRotationDegCCfromCamUp, listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam[i].textAnchor, listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam[i].autoLineBreakAngleDeg, listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam[i].durationInSec); + } + listOfSheduled_TextOnCircleScreenspace_dirViaAngle_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfBool_screenspace_3Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfBool_screenspace_3Dpos[i].boolArray, listOfSheduled_ArrayOfBool_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ArrayOfBool_screenspace_3Dpos[i].color, listOfSheduled_ArrayOfBool_screenspace_3Dpos[i].title, listOfSheduled_ArrayOfBool_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfBool_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfBool_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfBool_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfBool_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam[i].boolArray, listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam[i].color, listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam[i].title, listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfBool_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfBool_screenspace_2Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfBool_screenspace_2Dpos[i].boolArray, listOfSheduled_ArrayOfBool_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ArrayOfBool_screenspace_2Dpos[i].color, listOfSheduled_ArrayOfBool_screenspace_2Dpos[i].title, listOfSheduled_ArrayOfBool_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfBool_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfBool_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfBool_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfBool_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam[i].boolArray, listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam[i].color, listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam[i].title, listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfBool_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfBool_screenspace_3Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfBool_screenspace_3Dpos[i].boolList, listOfSheduled_ListOfBool_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ListOfBool_screenspace_3Dpos[i].color, listOfSheduled_ListOfBool_screenspace_3Dpos[i].title, listOfSheduled_ListOfBool_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfBool_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfBool_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfBool_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ListOfBool_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfBool_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfBool_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ListOfBool_screenspace_3Dpos_cam[i].boolList, listOfSheduled_ListOfBool_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ListOfBool_screenspace_3Dpos_cam[i].color, listOfSheduled_ListOfBool_screenspace_3Dpos_cam[i].title, listOfSheduled_ListOfBool_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfBool_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfBool_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfBool_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfBool_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfBool_screenspace_2Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfBool_screenspace_2Dpos[i].boolList, listOfSheduled_ListOfBool_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ListOfBool_screenspace_2Dpos[i].color, listOfSheduled_ListOfBool_screenspace_2Dpos[i].title, listOfSheduled_ListOfBool_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfBool_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfBool_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfBool_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ListOfBool_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfBool_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfBool_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ListOfBool_screenspace_2Dpos_cam[i].boolList, listOfSheduled_ListOfBool_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ListOfBool_screenspace_2Dpos_cam[i].color, listOfSheduled_ListOfBool_screenspace_2Dpos_cam[i].title, listOfSheduled_ListOfBool_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfBool_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfBool_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfBool_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfBool_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfInt_screenspace_3Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfInt_screenspace_3Dpos[i].intArray, listOfSheduled_ArrayOfInt_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ArrayOfInt_screenspace_3Dpos[i].color, listOfSheduled_ArrayOfInt_screenspace_3Dpos[i].title, listOfSheduled_ArrayOfInt_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfInt_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfInt_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfInt_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfInt_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam[i].intArray, listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam[i].color, listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam[i].title, listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfInt_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfInt_screenspace_2Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfInt_screenspace_2Dpos[i].intArray, listOfSheduled_ArrayOfInt_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ArrayOfInt_screenspace_2Dpos[i].color, listOfSheduled_ArrayOfInt_screenspace_2Dpos[i].title, listOfSheduled_ArrayOfInt_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfInt_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfInt_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfInt_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfInt_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam[i].intArray, listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam[i].color, listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam[i].title, listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfInt_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfInt_screenspace_3Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfInt_screenspace_3Dpos[i].intList, listOfSheduled_ListOfInt_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ListOfInt_screenspace_3Dpos[i].color, listOfSheduled_ListOfInt_screenspace_3Dpos[i].title, listOfSheduled_ListOfInt_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfInt_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfInt_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfInt_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ListOfInt_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfInt_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfInt_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ListOfInt_screenspace_3Dpos_cam[i].intList, listOfSheduled_ListOfInt_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ListOfInt_screenspace_3Dpos_cam[i].color, listOfSheduled_ListOfInt_screenspace_3Dpos_cam[i].title, listOfSheduled_ListOfInt_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfInt_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfInt_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfInt_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfInt_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfInt_screenspace_2Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfInt_screenspace_2Dpos[i].intList, listOfSheduled_ListOfInt_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ListOfInt_screenspace_2Dpos[i].color, listOfSheduled_ListOfInt_screenspace_2Dpos[i].title, listOfSheduled_ListOfInt_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfInt_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfInt_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfInt_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ListOfInt_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfInt_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfInt_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ListOfInt_screenspace_2Dpos_cam[i].intList, listOfSheduled_ListOfInt_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ListOfInt_screenspace_2Dpos_cam[i].color, listOfSheduled_ListOfInt_screenspace_2Dpos_cam[i].title, listOfSheduled_ListOfInt_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfInt_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfInt_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfInt_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfInt_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfFloat_screenspace_3Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfFloat_screenspace_3Dpos[i].floatArray, listOfSheduled_ArrayOfFloat_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ArrayOfFloat_screenspace_3Dpos[i].color, listOfSheduled_ArrayOfFloat_screenspace_3Dpos[i].title, listOfSheduled_ArrayOfFloat_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfFloat_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfFloat_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfFloat_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfFloat_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam[i].floatArray, listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam[i].color, listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam[i].title, listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfFloat_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfFloat_screenspace_2Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfFloat_screenspace_2Dpos[i].floatArray, listOfSheduled_ArrayOfFloat_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ArrayOfFloat_screenspace_2Dpos[i].color, listOfSheduled_ArrayOfFloat_screenspace_2Dpos[i].title, listOfSheduled_ArrayOfFloat_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfFloat_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfFloat_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfFloat_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfFloat_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam[i].floatArray, listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam[i].color, listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam[i].title, listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfFloat_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfFloat_screenspace_3Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfFloat_screenspace_3Dpos[i].floatList, listOfSheduled_ListOfFloat_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ListOfFloat_screenspace_3Dpos[i].color, listOfSheduled_ListOfFloat_screenspace_3Dpos[i].title, listOfSheduled_ListOfFloat_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfFloat_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfFloat_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfFloat_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ListOfFloat_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfFloat_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfFloat_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ListOfFloat_screenspace_3Dpos_cam[i].floatList, listOfSheduled_ListOfFloat_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ListOfFloat_screenspace_3Dpos_cam[i].color, listOfSheduled_ListOfFloat_screenspace_3Dpos_cam[i].title, listOfSheduled_ListOfFloat_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfFloat_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfFloat_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfFloat_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfFloat_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfFloat_screenspace_2Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfFloat_screenspace_2Dpos[i].floatList, listOfSheduled_ListOfFloat_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ListOfFloat_screenspace_2Dpos[i].color, listOfSheduled_ListOfFloat_screenspace_2Dpos[i].title, listOfSheduled_ListOfFloat_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfFloat_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfFloat_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfFloat_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ListOfFloat_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfFloat_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfFloat_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ListOfFloat_screenspace_2Dpos_cam[i].floatList, listOfSheduled_ListOfFloat_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ListOfFloat_screenspace_2Dpos_cam[i].color, listOfSheduled_ListOfFloat_screenspace_2Dpos_cam[i].title, listOfSheduled_ListOfFloat_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfFloat_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfFloat_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfFloat_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfFloat_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfString_screenspace_3Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfString_screenspace_3Dpos[i].stringArray, listOfSheduled_ArrayOfString_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ArrayOfString_screenspace_3Dpos[i].color, listOfSheduled_ArrayOfString_screenspace_3Dpos[i].title, listOfSheduled_ArrayOfString_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfString_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfString_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfString_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfString_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfString_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfString_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfString_screenspace_3Dpos_cam[i].stringArray, listOfSheduled_ArrayOfString_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ArrayOfString_screenspace_3Dpos_cam[i].color, listOfSheduled_ArrayOfString_screenspace_3Dpos_cam[i].title, listOfSheduled_ArrayOfString_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfString_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfString_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfString_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfString_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfString_screenspace_2Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfString_screenspace_2Dpos[i].stringArray, listOfSheduled_ArrayOfString_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ArrayOfString_screenspace_2Dpos[i].color, listOfSheduled_ArrayOfString_screenspace_2Dpos[i].title, listOfSheduled_ArrayOfString_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfString_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfString_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfString_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfString_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfString_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfString_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfString_screenspace_2Dpos_cam[i].stringArray, listOfSheduled_ArrayOfString_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ArrayOfString_screenspace_2Dpos_cam[i].color, listOfSheduled_ArrayOfString_screenspace_2Dpos_cam[i].title, listOfSheduled_ArrayOfString_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfString_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfString_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfString_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfString_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfString_screenspace_3Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfString_screenspace_3Dpos[i].stringList, listOfSheduled_ListOfString_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ListOfString_screenspace_3Dpos[i].color, listOfSheduled_ListOfString_screenspace_3Dpos[i].title, listOfSheduled_ListOfString_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfString_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfString_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfString_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ListOfString_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfString_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfString_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ListOfString_screenspace_3Dpos_cam[i].stringList, listOfSheduled_ListOfString_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ListOfString_screenspace_3Dpos_cam[i].color, listOfSheduled_ListOfString_screenspace_3Dpos_cam[i].title, listOfSheduled_ListOfString_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfString_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfString_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfString_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfString_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfString_screenspace_2Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfString_screenspace_2Dpos[i].stringList, listOfSheduled_ListOfString_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ListOfString_screenspace_2Dpos[i].color, listOfSheduled_ListOfString_screenspace_2Dpos[i].title, listOfSheduled_ListOfString_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfString_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfString_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfString_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ListOfString_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfString_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfString_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ListOfString_screenspace_2Dpos_cam[i].stringList, listOfSheduled_ListOfString_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ListOfString_screenspace_2Dpos_cam[i].color, listOfSheduled_ListOfString_screenspace_2Dpos_cam[i].title, listOfSheduled_ListOfString_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfString_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfString_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfString_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfString_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector2_screenspace_3Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector2_screenspace_3Dpos[i].vector2Array, listOfSheduled_ArrayOfVector2_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ArrayOfVector2_screenspace_3Dpos[i].color, listOfSheduled_ArrayOfVector2_screenspace_3Dpos[i].title, listOfSheduled_ArrayOfVector2_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector2_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector2_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector2_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfVector2_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam[i].vector2Array, listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam[i].color, listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam[i].title, listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfVector2_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector2_screenspace_2Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector2_screenspace_2Dpos[i].vector2Array, listOfSheduled_ArrayOfVector2_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ArrayOfVector2_screenspace_2Dpos[i].color, listOfSheduled_ArrayOfVector2_screenspace_2Dpos[i].title, listOfSheduled_ArrayOfVector2_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector2_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector2_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector2_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfVector2_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam[i].vector2Array, listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam[i].color, listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam[i].title, listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfVector2_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector2_screenspace_3Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector2_screenspace_3Dpos[i].vector2List, listOfSheduled_ListOfVector2_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ListOfVector2_screenspace_3Dpos[i].color, listOfSheduled_ListOfVector2_screenspace_3Dpos[i].title, listOfSheduled_ListOfVector2_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector2_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector2_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector2_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ListOfVector2_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector2_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector2_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ListOfVector2_screenspace_3Dpos_cam[i].vector2List, listOfSheduled_ListOfVector2_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ListOfVector2_screenspace_3Dpos_cam[i].color, listOfSheduled_ListOfVector2_screenspace_3Dpos_cam[i].title, listOfSheduled_ListOfVector2_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector2_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector2_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector2_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfVector2_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector2_screenspace_2Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector2_screenspace_2Dpos[i].vector2List, listOfSheduled_ListOfVector2_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ListOfVector2_screenspace_2Dpos[i].color, listOfSheduled_ListOfVector2_screenspace_2Dpos[i].title, listOfSheduled_ListOfVector2_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector2_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector2_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector2_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ListOfVector2_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector2_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector2_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ListOfVector2_screenspace_2Dpos_cam[i].vector2List, listOfSheduled_ListOfVector2_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ListOfVector2_screenspace_2Dpos_cam[i].color, listOfSheduled_ListOfVector2_screenspace_2Dpos_cam[i].title, listOfSheduled_ListOfVector2_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector2_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector2_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector2_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfVector2_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector3_screenspace_3Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector3_screenspace_3Dpos[i].vector3Array, listOfSheduled_ArrayOfVector3_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ArrayOfVector3_screenspace_3Dpos[i].color, listOfSheduled_ArrayOfVector3_screenspace_3Dpos[i].title, listOfSheduled_ArrayOfVector3_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector3_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector3_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector3_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfVector3_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam[i].vector3Array, listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam[i].color, listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam[i].title, listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfVector3_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector3_screenspace_2Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector3_screenspace_2Dpos[i].vector3Array, listOfSheduled_ArrayOfVector3_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ArrayOfVector3_screenspace_2Dpos[i].color, listOfSheduled_ArrayOfVector3_screenspace_2Dpos[i].title, listOfSheduled_ArrayOfVector3_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector3_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector3_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector3_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfVector3_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam[i].vector3Array, listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam[i].color, listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam[i].title, listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfVector3_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector3_screenspace_3Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector3_screenspace_3Dpos[i].vector3List, listOfSheduled_ListOfVector3_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ListOfVector3_screenspace_3Dpos[i].color, listOfSheduled_ListOfVector3_screenspace_3Dpos[i].title, listOfSheduled_ListOfVector3_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector3_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector3_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector3_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ListOfVector3_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector3_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector3_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ListOfVector3_screenspace_3Dpos_cam[i].vector3List, listOfSheduled_ListOfVector3_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ListOfVector3_screenspace_3Dpos_cam[i].color, listOfSheduled_ListOfVector3_screenspace_3Dpos_cam[i].title, listOfSheduled_ListOfVector3_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector3_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector3_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector3_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfVector3_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector3_screenspace_2Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector3_screenspace_2Dpos[i].vector3List, listOfSheduled_ListOfVector3_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ListOfVector3_screenspace_2Dpos[i].color, listOfSheduled_ListOfVector3_screenspace_2Dpos[i].title, listOfSheduled_ListOfVector3_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector3_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector3_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector3_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ListOfVector3_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector3_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector3_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ListOfVector3_screenspace_2Dpos_cam[i].vector3List, listOfSheduled_ListOfVector3_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ListOfVector3_screenspace_2Dpos_cam[i].color, listOfSheduled_ListOfVector3_screenspace_2Dpos_cam[i].title, listOfSheduled_ListOfVector3_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector3_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector3_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector3_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfVector3_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector4_screenspace_3Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector4_screenspace_3Dpos[i].vector4Array, listOfSheduled_ArrayOfVector4_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ArrayOfVector4_screenspace_3Dpos[i].color, listOfSheduled_ArrayOfVector4_screenspace_3Dpos[i].title, listOfSheduled_ArrayOfVector4_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector4_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector4_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector4_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfVector4_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam[i].vector4Array, listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam[i].color, listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam[i].title, listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfVector4_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector4_screenspace_2Dpos.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector4_screenspace_2Dpos[i].vector4Array, listOfSheduled_ArrayOfVector4_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ArrayOfVector4_screenspace_2Dpos[i].color, listOfSheduled_ArrayOfVector4_screenspace_2Dpos[i].title, listOfSheduled_ArrayOfVector4_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector4_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector4_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector4_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ArrayOfVector4_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteArrayScreenspace(listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam[i].vector4Array, listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam[i].color, listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam[i].title, listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ArrayOfVector4_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector4_screenspace_3Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector4_screenspace_3Dpos[i].vector4List, listOfSheduled_ListOfVector4_screenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_ListOfVector4_screenspace_3Dpos[i].color, listOfSheduled_ListOfVector4_screenspace_3Dpos[i].title, listOfSheduled_ListOfVector4_screenspace_3Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector4_screenspace_3Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector4_screenspace_3Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector4_screenspace_3Dpos[i].durationInSec); + } + listOfSheduled_ListOfVector4_screenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector4_screenspace_3Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector4_screenspace_3Dpos_cam[i].screenCamera, listOfSheduled_ListOfVector4_screenspace_3Dpos_cam[i].vector4List, listOfSheduled_ListOfVector4_screenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ListOfVector4_screenspace_3Dpos_cam[i].color, listOfSheduled_ListOfVector4_screenspace_3Dpos_cam[i].title, listOfSheduled_ListOfVector4_screenspace_3Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector4_screenspace_3Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector4_screenspace_3Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector4_screenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfVector4_screenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector4_screenspace_2Dpos.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector4_screenspace_2Dpos[i].vector4List, listOfSheduled_ListOfVector4_screenspace_2Dpos[i].position_in2DViewportSpace, listOfSheduled_ListOfVector4_screenspace_2Dpos[i].color, listOfSheduled_ListOfVector4_screenspace_2Dpos[i].title, listOfSheduled_ListOfVector4_screenspace_2Dpos[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector4_screenspace_2Dpos[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector4_screenspace_2Dpos[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector4_screenspace_2Dpos[i].durationInSec); + } + listOfSheduled_ListOfVector4_screenspace_2Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ListOfVector4_screenspace_2Dpos_cam.Count; i++) + { + DrawText.WriteListScreenspace(listOfSheduled_ListOfVector4_screenspace_2Dpos_cam[i].screenCamera, listOfSheduled_ListOfVector4_screenspace_2Dpos_cam[i].vector4List, listOfSheduled_ListOfVector4_screenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ListOfVector4_screenspace_2Dpos_cam[i].color, listOfSheduled_ListOfVector4_screenspace_2Dpos_cam[i].title, listOfSheduled_ListOfVector4_screenspace_2Dpos_cam[i].textSize_relToViewportHeight, listOfSheduled_ListOfVector4_screenspace_2Dpos_cam[i].forceHeightOfWholeTableBox_relToViewportHeight, listOfSheduled_ListOfVector4_screenspace_2Dpos_cam[i].position_isTopLeft_notLowLeft, listOfSheduled_ListOfVector4_screenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ListOfVector4_screenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_TagGameObjectScreenspace.Count; i++) + { + DrawEngineBasics.TagGameObjectScreenspace(listOfSheduled_TagGameObjectScreenspace[i].screenCamera, listOfSheduled_TagGameObjectScreenspace[i].gameObject, listOfSheduled_TagGameObjectScreenspace[i].text, listOfSheduled_TagGameObjectScreenspace[i].colorForText, listOfSheduled_TagGameObjectScreenspace[i].colorForTagBox, listOfSheduled_TagGameObjectScreenspace[i].linesWidth_relToViewportHeight, listOfSheduled_TagGameObjectScreenspace[i].drawPointerIfOffscreen, listOfSheduled_TagGameObjectScreenspace[i].relTextSizeScaling, listOfSheduled_TagGameObjectScreenspace[i].encapsulateChildren, listOfSheduled_TagGameObjectScreenspace[i].durationInSec); + } + listOfSheduled_TagGameObjectScreenspace.Clear(); + + for (int i = 0; i < listOfSheduled_GridScreenspace.Count; i++) + { + DrawEngineBasics.GridScreenspace(listOfSheduled_GridScreenspace[i].camera, listOfSheduled_GridScreenspace[i].color, listOfSheduled_GridScreenspace[i].linesWidth_relToViewportHeight, listOfSheduled_GridScreenspace[i].drawTenthLines, listOfSheduled_GridScreenspace[i].drawHundredthLines, listOfSheduled_GridScreenspace[i].gridScreenspaceMode, listOfSheduled_GridScreenspace[i].durationInSec); + } + listOfSheduled_GridScreenspace.Clear(); + + for (int i = 0; i < listOfSheduled_BoolDisplayerScreenspace_3Dpos.Count; i++) + { + DrawEngineBasics.BoolDisplayerScreenspace(listOfSheduled_BoolDisplayerScreenspace_3Dpos[i].boolValueToDisplay, listOfSheduled_BoolDisplayerScreenspace_3Dpos[i].boolName, listOfSheduled_BoolDisplayerScreenspace_3Dpos[i].position_in3DWorldspace, listOfSheduled_BoolDisplayerScreenspace_3Dpos[i].size_relToViewportHeight, listOfSheduled_BoolDisplayerScreenspace_3Dpos[i].color_forTextAndFrame, listOfSheduled_BoolDisplayerScreenspace_3Dpos[i].overwriteColor_forTrue, listOfSheduled_BoolDisplayerScreenspace_3Dpos[i].overwriteColor_forFalse, listOfSheduled_BoolDisplayerScreenspace_3Dpos[i].durationInSec); + } + listOfSheduled_BoolDisplayerScreenspace_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam.Count; i++) + { + DrawEngineBasics.BoolDisplayerScreenspace(listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam[i].screenCamera, listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam[i].boolValueToDisplay, listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam[i].boolName, listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam[i].size_relToViewportHeight, listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam[i].color_forTextAndFrame, listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam[i].overwriteColor_forTrue, listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam[i].overwriteColor_forFalse, listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam[i].durationInSec); + } + listOfSheduled_BoolDisplayerScreenspace_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam.Count; i++) + { + DrawEngineBasics.BoolDisplayerScreenspace(listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam[i].screenCamera, listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam[i].boolValueToDisplay, listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam[i].boolName, listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam[i].size_relToViewportHeight, listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam[i].color_forTextAndFrame, listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam[i].overwriteColor_forTrue, listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam[i].overwriteColor_forFalse, listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam[i].durationInSec); + } + listOfSheduled_BoolDisplayerScreenspace_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_LogsOnScreen.Count; i++) + { + bool logListenerBoolState_before = DrawLogs.LogMessageListenerForLogsOnScreen_isActivated; + if (listOfSheduled_LogsOnScreen[i].logListenerWasActive) + { + DrawLogs.ActivateLogMessageListenerForLogsOnScreen(); + } + else + { + DrawLogs.DeactivateLogMessageListenerForLogsOnScreen(); + } + DrawLogs.LogsOnScreen(listOfSheduled_LogsOnScreen[i].cameraWhereToDraw, listOfSheduled_LogsOnScreen[i].drawNormalPrio, listOfSheduled_LogsOnScreen[i].drawWarningPrio, listOfSheduled_LogsOnScreen[i].drawErrorPrio, listOfSheduled_LogsOnScreen[i].maxNumberOfDisplayedLogMessages, listOfSheduled_LogsOnScreen[i].textSize_relToViewportHeight, listOfSheduled_LogsOnScreen[i].textColor, listOfSheduled_LogsOnScreen[i].stackTraceForNormalPrio, listOfSheduled_LogsOnScreen[i].stackTraceForWarningPrio, listOfSheduled_LogsOnScreen[i].stackTraceForErrorPrio, listOfSheduled_LogsOnScreen[i].durationInSec); + if (logListenerBoolState_before) + { + DrawLogs.ActivateLogMessageListenerForLogsOnScreen(); + } + else + { + DrawLogs.DeactivateLogMessageListenerForLogsOnScreen(); + } + } + listOfSheduled_LogsOnScreen.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLine.Count; i++) + { + DrawScreenspace.Line(listOfSheduled_ScreenspaceLine[i].targetCamera, listOfSheduled_ScreenspaceLine[i].start, listOfSheduled_ScreenspaceLine[i].end, listOfSheduled_ScreenspaceLine[i].color, listOfSheduled_ScreenspaceLine[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLine[i].text, listOfSheduled_ScreenspaceLine[i].style, listOfSheduled_ScreenspaceLine[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLine[i].animationSpeed, listOfSheduled_ScreenspaceLine[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceLine[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceLine[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceLine[i].durationInSec); + } + listOfSheduled_ScreenspaceLine.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceRay.Count; i++) + { + DrawScreenspace.Ray(listOfSheduled_ScreenspaceRay[i].targetCamera, listOfSheduled_ScreenspaceRay[i].start, listOfSheduled_ScreenspaceRay[i].direction, listOfSheduled_ScreenspaceRay[i].color, listOfSheduled_ScreenspaceRay[i].width_relToViewportHeight, listOfSheduled_ScreenspaceRay[i].text, listOfSheduled_ScreenspaceRay[i].interpretDirectionAsUnwarped, listOfSheduled_ScreenspaceRay[i].style, listOfSheduled_ScreenspaceRay[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceRay[i].animationSpeed, listOfSheduled_ScreenspaceRay[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceRay[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceRay[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceRay[i].durationInSec); + } + listOfSheduled_ScreenspaceRay.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineFrom.Count; i++) + { + DrawScreenspace.LineFrom(listOfSheduled_ScreenspaceLineFrom[i].targetCamera, listOfSheduled_ScreenspaceLineFrom[i].start, listOfSheduled_ScreenspaceLineFrom[i].direction, listOfSheduled_ScreenspaceLineFrom[i].color, listOfSheduled_ScreenspaceLineFrom[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineFrom[i].text, listOfSheduled_ScreenspaceLineFrom[i].interpretDirectionAsUnwarped, listOfSheduled_ScreenspaceLineFrom[i].style, listOfSheduled_ScreenspaceLineFrom[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLineFrom[i].animationSpeed, listOfSheduled_ScreenspaceLineFrom[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceLineFrom[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceLineFrom[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceLineFrom[i].durationInSec); + } + listOfSheduled_ScreenspaceLineFrom.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineTo.Count; i++) + { + DrawScreenspace.LineTo(listOfSheduled_ScreenspaceLineTo[i].targetCamera, listOfSheduled_ScreenspaceLineTo[i].direction, listOfSheduled_ScreenspaceLineTo[i].end, listOfSheduled_ScreenspaceLineTo[i].color, listOfSheduled_ScreenspaceLineTo[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineTo[i].text, listOfSheduled_ScreenspaceLineTo[i].interpretDirectionAsUnwarped, listOfSheduled_ScreenspaceLineTo[i].style, listOfSheduled_ScreenspaceLineTo[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLineTo[i].animationSpeed, listOfSheduled_ScreenspaceLineTo[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceLineTo[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceLineTo[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceLineTo[i].durationInSec); + } + listOfSheduled_ScreenspaceLineTo.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineColorFade.Count; i++) + { + DrawScreenspace.LineColorFade(listOfSheduled_ScreenspaceLineColorFade[i].targetCamera, listOfSheduled_ScreenspaceLineColorFade[i].start, listOfSheduled_ScreenspaceLineColorFade[i].end, listOfSheduled_ScreenspaceLineColorFade[i].startColor, listOfSheduled_ScreenspaceLineColorFade[i].endColor, listOfSheduled_ScreenspaceLineColorFade[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineColorFade[i].text, listOfSheduled_ScreenspaceLineColorFade[i].style, listOfSheduled_ScreenspaceLineColorFade[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLineColorFade[i].animationSpeed, listOfSheduled_ScreenspaceLineColorFade[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceLineColorFade[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceLineColorFade[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceLineColorFade[i].durationInSec); + } + listOfSheduled_ScreenspaceLineColorFade.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceRayColorFade.Count; i++) + { + DrawScreenspace.RayColorFade(listOfSheduled_ScreenspaceRayColorFade[i].targetCamera, listOfSheduled_ScreenspaceRayColorFade[i].start, listOfSheduled_ScreenspaceRayColorFade[i].direction, listOfSheduled_ScreenspaceRayColorFade[i].startColor, listOfSheduled_ScreenspaceRayColorFade[i].endColor, listOfSheduled_ScreenspaceRayColorFade[i].width_relToViewportHeight, listOfSheduled_ScreenspaceRayColorFade[i].text, listOfSheduled_ScreenspaceRayColorFade[i].interpretDirectionAsUnwarped, listOfSheduled_ScreenspaceRayColorFade[i].style, listOfSheduled_ScreenspaceRayColorFade[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceRayColorFade[i].animationSpeed, listOfSheduled_ScreenspaceRayColorFade[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceRayColorFade[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceRayColorFade[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceRayColorFade[i].durationInSec); + } + listOfSheduled_ScreenspaceRayColorFade.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineFrom_withColorFade.Count; i++) + { + DrawScreenspace.LineFrom_withColorFade(listOfSheduled_ScreenspaceLineFrom_withColorFade[i].targetCamera, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].start, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].direction, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].startColor, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].endColor, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].text, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].interpretDirectionAsUnwarped, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].style, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].animationSpeed, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceLineFrom_withColorFade[i].durationInSec); + } + listOfSheduled_ScreenspaceLineFrom_withColorFade.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineTo_withColorFade.Count; i++) + { + DrawScreenspace.LineTo_withColorFade(listOfSheduled_ScreenspaceLineTo_withColorFade[i].targetCamera, listOfSheduled_ScreenspaceLineTo_withColorFade[i].direction, listOfSheduled_ScreenspaceLineTo_withColorFade[i].end, listOfSheduled_ScreenspaceLineTo_withColorFade[i].startColor, listOfSheduled_ScreenspaceLineTo_withColorFade[i].endColor, listOfSheduled_ScreenspaceLineTo_withColorFade[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineTo_withColorFade[i].text, listOfSheduled_ScreenspaceLineTo_withColorFade[i].interpretDirectionAsUnwarped, listOfSheduled_ScreenspaceLineTo_withColorFade[i].style, listOfSheduled_ScreenspaceLineTo_withColorFade[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLineTo_withColorFade[i].animationSpeed, listOfSheduled_ScreenspaceLineTo_withColorFade[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceLineTo_withColorFade[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceLineTo_withColorFade[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceLineTo_withColorFade[i].durationInSec); + } + listOfSheduled_ScreenspaceLineTo_withColorFade.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam.Count; i++) + { + DrawScreenspace.LineCircled(listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].targetCamera, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].circleCenter, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].startAngleDegCC_relativeToUp, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].endAngleDegCC_relativeToUp, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].color, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].text, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].skipFallbackDisplayOfZeroAngles, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].minAngleDeg_withoutTextLineBreak, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].textAnchor, listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceLineCircled_angleToAngle_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam.Count; i++) + { + DrawScreenspace.LineCircled(listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].targetCamera, listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].startPos, listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].circleCenter, listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].turnAngleDegCC, listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].color, listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].text, listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].skipFallbackDisplayOfZeroAngles, listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].minAngleDeg_withoutTextLineBreak, listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].textAnchor, listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceLineCircled_angleFromStartPos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam.Count; i++) + { + DrawScreenspace.CircleSegment(listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].targetCamera, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].circleCenter, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].startAngleDegCC_relativeToUp, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].endAngleDegCC_relativeToUp, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].color, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].text, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].radiusPortionWhereDrawFillStarts, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].skipFallbackDisplayOfZeroAngles, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].fillDensity, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].minAngleDeg_withoutTextLineBreak, listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceCircleSegment_angleToAngle_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam.Count; i++) + { + DrawScreenspace.CircleSegment(listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].targetCamera, listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].startPosOnPerimeter, listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].circleCenter, listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].turnAngleDegCC, listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].color, listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].text, listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].radiusPortionWhereDrawFillStarts, listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].skipFallbackDisplayOfZeroAngles, listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].fillDensity, listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].minAngleDeg_withoutTextLineBreak, listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceCircleSegment_angleFromStartPos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineString_array_cam.Count; i++) + { + DrawScreenspace.LineString(listOfSheduled_ScreenspaceLineString_array_cam[i].targetCamera, listOfSheduled_ScreenspaceLineString_array_cam[i].points, listOfSheduled_ScreenspaceLineString_array_cam[i].color, listOfSheduled_ScreenspaceLineString_array_cam[i].closeGapBetweenLastAndFirstPoint, listOfSheduled_ScreenspaceLineString_array_cam[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineString_array_cam[i].text, listOfSheduled_ScreenspaceLineString_array_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceLineString_array_cam[i].style, listOfSheduled_ScreenspaceLineString_array_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLineString_array_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceLineString_array_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineString_list_cam.Count; i++) + { + DrawScreenspace.LineString(listOfSheduled_ScreenspaceLineString_list_cam[i].targetCamera, listOfSheduled_ScreenspaceLineString_list_cam[i].points, listOfSheduled_ScreenspaceLineString_list_cam[i].color, listOfSheduled_ScreenspaceLineString_list_cam[i].closeGapBetweenLastAndFirstPoint, listOfSheduled_ScreenspaceLineString_list_cam[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineString_list_cam[i].text, listOfSheduled_ScreenspaceLineString_list_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceLineString_list_cam[i].style, listOfSheduled_ScreenspaceLineString_list_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLineString_list_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceLineString_list_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineStringColorFade_array_cam.Count; i++) + { + DrawScreenspace.LineStringColorFade(listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].targetCamera, listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].points, listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].startColor, listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].endColor, listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].closeGapBetweenLastAndFirstPoint, listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].text, listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].style, listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLineStringColorFade_array_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceLineStringColorFade_array_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineStringColorFade_list_cam.Count; i++) + { + DrawScreenspace.LineStringColorFade(listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].targetCamera, listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].points, listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].startColor, listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].endColor, listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].closeGapBetweenLastAndFirstPoint, listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].text, listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].style, listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLineStringColorFade_list_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceLineStringColorFade_list_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceShape_3Dpos.Count; i++) + { + DrawScreenspace.Shape(listOfSheduled_ScreenspaceShape_3Dpos[i].centerPosition_in3DWorldspace, listOfSheduled_ScreenspaceShape_3Dpos[i].shape, listOfSheduled_ScreenspaceShape_3Dpos[i].color, listOfSheduled_ScreenspaceShape_3Dpos[i].width_relToViewportHeight, listOfSheduled_ScreenspaceShape_3Dpos[i].height_relToViewportHeight, listOfSheduled_ScreenspaceShape_3Dpos[i].zRotationDegCC, listOfSheduled_ScreenspaceShape_3Dpos[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceShape_3Dpos[i].text, listOfSheduled_ScreenspaceShape_3Dpos[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceShape_3Dpos[i].lineStyle, listOfSheduled_ScreenspaceShape_3Dpos[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceShape_3Dpos[i].fillStyle, listOfSheduled_ScreenspaceShape_3Dpos[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceShape_3Dpos[i].durationInSec); + } + listOfSheduled_ScreenspaceShape_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceShape_3Dpos_cam.Count; i++) + { + DrawScreenspace.Shape(listOfSheduled_ScreenspaceShape_3Dpos_cam[i].targetCamera, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].centerPosition_in3DWorldspace, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].shape, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].color, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].width_relToViewportHeight, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].height_relToViewportHeight, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].zRotationDegCC, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].text, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].lineStyle, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].fillStyle, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceShape_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceShape_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceShape_2Dpos_cam.Count; i++) + { + DrawScreenspace.Shape(listOfSheduled_ScreenspaceShape_2Dpos_cam[i].targetCamera, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].centerPosition_in2DViewportSpace, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].shape, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].color, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].width_relToViewportHeight, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].height_relToViewportHeight, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].zRotationDegCC, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].text, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].lineStyle, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].fillStyle, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceShape_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceShape_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceRectangle.Count; i++) + { + DrawScreenspace.Rectangle(listOfSheduled_ScreenspaceRectangle[i].targetCamera, listOfSheduled_ScreenspaceRectangle[i].lowLeftCorner, listOfSheduled_ScreenspaceRectangle[i].width_relToScreenWidth, listOfSheduled_ScreenspaceRectangle[i].height_relToScreenHeight, listOfSheduled_ScreenspaceRectangle[i].color, listOfSheduled_ScreenspaceRectangle[i].shape, listOfSheduled_ScreenspaceRectangle[i].linesWidth_relToScreenHeight, listOfSheduled_ScreenspaceRectangle[i].text, listOfSheduled_ScreenspaceRectangle[i].lineStyle, listOfSheduled_ScreenspaceRectangle[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceRectangle[i].fillStyle, listOfSheduled_ScreenspaceRectangle[i].durationInSec); + } + listOfSheduled_ScreenspaceRectangle.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceBox_rect_cam.Count; i++) + { + DrawScreenspace.Box(listOfSheduled_ScreenspaceBox_rect_cam[i].targetCamera, listOfSheduled_ScreenspaceBox_rect_cam[i].rect, listOfSheduled_ScreenspaceBox_rect_cam[i].color, listOfSheduled_ScreenspaceBox_rect_cam[i].zRotationDegCC, listOfSheduled_ScreenspaceBox_rect_cam[i].shape, listOfSheduled_ScreenspaceBox_rect_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceBox_rect_cam[i].text, listOfSheduled_ScreenspaceBox_rect_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceBox_rect_cam[i].lineStyle, listOfSheduled_ScreenspaceBox_rect_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceBox_rect_cam[i].fillStyle, listOfSheduled_ScreenspaceBox_rect_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceBox_rect_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceBox_rect_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceBox_3Dpos_vec.Count; i++) + { + DrawScreenspace.Box(listOfSheduled_ScreenspaceBox_3Dpos_vec[i].centerPosition_in3DWorldspace, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].size_relToViewportHeight, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].color, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].zRotationDegCC, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].shape, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].text, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].lineStyle, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].fillStyle, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].forceSizeInterpretationToWarpedViewportSpace, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceBox_3Dpos_vec[i].durationInSec); + } + listOfSheduled_ScreenspaceBox_3Dpos_vec.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceBox_3Dpos_vec_cam.Count; i++) + { + DrawScreenspace.Box(listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].targetCamera, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].centerPosition_in3DWorldspace, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].size_relToViewportHeight, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].color, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].zRotationDegCC, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].shape, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].text, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].lineStyle, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].fillStyle, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].forceSizeInterpretationToWarpedViewportSpace, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceBox_3Dpos_vec_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceBox_3Dpos_vec_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceBox_2Dpos_vec_cam.Count; i++) + { + DrawScreenspace.Box(listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].targetCamera, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].centerPosition_in2DViewportSpace, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].size_relToViewportHeight, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].color, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].zRotationDegCC, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].shape, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].text, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].lineStyle, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].fillStyle, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].forceSizeInterpretationToWarpedViewportSpace, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceBox_2Dpos_vec_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceBox_2Dpos_vec_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCircle_rect_cam.Count; i++) + { + DrawScreenspace.Circle(listOfSheduled_ScreenspaceCircle_rect_cam[i].targetCamera, listOfSheduled_ScreenspaceCircle_rect_cam[i].rect, listOfSheduled_ScreenspaceCircle_rect_cam[i].color, listOfSheduled_ScreenspaceCircle_rect_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCircle_rect_cam[i].text, listOfSheduled_ScreenspaceCircle_rect_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCircle_rect_cam[i].lineStyle, listOfSheduled_ScreenspaceCircle_rect_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCircle_rect_cam[i].fillStyle, listOfSheduled_ScreenspaceCircle_rect_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCircle_rect_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceCircle_rect_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCircle_3Dpos_vecRad.Count; i++) + { + DrawScreenspace.Circle(listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].centerPosition_in3DWorldspace, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].color, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].text, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].lineStyle, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].fillStyle, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad[i].durationInSec); + } + listOfSheduled_ScreenspaceCircle_3Dpos_vecRad.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam.Count; i++) + { + DrawScreenspace.Circle(listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].targetCamera, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].centerPosition_in3DWorldspace, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].color, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].text, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].lineStyle, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].fillStyle, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceCircle_3Dpos_vecRad_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam.Count; i++) + { + DrawScreenspace.Circle(listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].targetCamera, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].centerPosition_in2DViewportSpace, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].color, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].text, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].lineStyle, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].fillStyle, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceCircle_2Dpos_vecRad_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos.Count; i++) + { + DrawScreenspace.Capsule(listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].posOfCircle1_in3DWorldspace, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].posOfCircle2_in3DWorldspace, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].color, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].text, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].lineStyle, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].fillStyle, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos[i].durationInSec); + } + listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam.Count; i++) + { + DrawScreenspace.Capsule(listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].targetCamera, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].posOfCircle1_in3DWorldspace, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].posOfCircle2_in3DWorldspace, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].color, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].text, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].lineStyle, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].fillStyle, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam.Count; i++) + { + DrawScreenspace.Capsule(listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].targetCamera, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].posOfCircle1_in2DViewportSpace, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].posOfCircle2_in2DViewportSpace, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].color, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].text, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].lineStyle, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].fillStyle, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCapsule_rect_cam.Count; i++) + { + DrawScreenspace.Capsule(listOfSheduled_ScreenspaceCapsule_rect_cam[i].targetCamera, listOfSheduled_ScreenspaceCapsule_rect_cam[i].rect, listOfSheduled_ScreenspaceCapsule_rect_cam[i].color, listOfSheduled_ScreenspaceCapsule_rect_cam[i].capsuleDirection, listOfSheduled_ScreenspaceCapsule_rect_cam[i].zRotationDegCC, listOfSheduled_ScreenspaceCapsule_rect_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_rect_cam[i].text, listOfSheduled_ScreenspaceCapsule_rect_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCapsule_rect_cam[i].lineStyle, listOfSheduled_ScreenspaceCapsule_rect_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCapsule_rect_cam[i].fillStyle, listOfSheduled_ScreenspaceCapsule_rect_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCapsule_rect_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceCapsule_rect_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize.Count; i++) + { + DrawScreenspace.Capsule(listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].centerPosition_in3DWorldspace, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].size_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].color, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].capsuleDirection, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].zRotationDegCC, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].text, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].lineStyle, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].fillStyle, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].forceSizeInterpretationToWarpedViewportSpace, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize[i].durationInSec); + } + listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam.Count; i++) + { + DrawScreenspace.Capsule(listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].targetCamera, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].centerPosition_in3DWorldspace, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].size_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].color, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].capsuleDirection, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].zRotationDegCC, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].text, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].lineStyle, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].fillStyle, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].forceSizeInterpretationToWarpedViewportSpace, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceCapsule_3Dpos_vecPosSize_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam.Count; i++) + { + DrawScreenspace.Capsule(listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].targetCamera, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].centerPosition_in2DViewportSpace, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].size_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].color, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].capsuleDirection, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].zRotationDegCC, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].text, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].lineStyle, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].fillStyle, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].forceSizeInterpretationToWarpedViewportSpace, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceCapsule_2Dpos_vecPosSize_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspacePointArray.Count; i++) + { + DrawScreenspace.PointArray(listOfSheduled_ScreenspacePointArray[i].targetCamera, listOfSheduled_ScreenspacePointArray[i].points, listOfSheduled_ScreenspacePointArray[i].color, listOfSheduled_ScreenspacePointArray[i].sizeOfMarkingCross_relToViewportHeight, listOfSheduled_ScreenspacePointArray[i].markingCrossLinesWidth_relToViewportHeight, listOfSheduled_ScreenspacePointArray[i].drawCoordsAsText, listOfSheduled_ScreenspacePointArray[i].durationInSec); + } + listOfSheduled_ScreenspacePointArray.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspacePointList.Count; i++) + { + DrawScreenspace.PointList(listOfSheduled_ScreenspacePointList[i].targetCamera, listOfSheduled_ScreenspacePointList[i].points, listOfSheduled_ScreenspacePointList[i].color, listOfSheduled_ScreenspacePointList[i].sizeOfMarkingCross_relToViewportHeight, listOfSheduled_ScreenspacePointList[i].markingCrossLinesWidth_relToViewportHeight, listOfSheduled_ScreenspacePointList[i].drawCoordsAsText, listOfSheduled_ScreenspacePointList[i].durationInSec); + } + listOfSheduled_ScreenspacePointList.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspacePoint.Count; i++) + { + DrawScreenspace.Point(listOfSheduled_ScreenspacePoint[i].position, listOfSheduled_ScreenspacePoint[i].color, listOfSheduled_ScreenspacePoint[i].sizeOfMarkingCross_relToViewportHeight, listOfSheduled_ScreenspacePoint[i].zRotationDegCC, listOfSheduled_ScreenspacePoint[i].markingCrossLinesWidth_relToViewportHeight, listOfSheduled_ScreenspacePoint[i].drawPointerIfOffscreen, listOfSheduled_ScreenspacePoint[i].text, listOfSheduled_ScreenspacePoint[i].pointer_as_textAttachStyle, listOfSheduled_ScreenspacePoint[i].drawCoordsAsText, listOfSheduled_ScreenspacePoint[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspacePoint[i].durationInSec); + } + listOfSheduled_ScreenspacePoint.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspacePoint_prioText_cam.Count; i++) + { + DrawScreenspace.Point(listOfSheduled_ScreenspacePoint_prioText_cam[i].targetCamera, listOfSheduled_ScreenspacePoint_prioText_cam[i].position, listOfSheduled_ScreenspacePoint_prioText_cam[i].text, listOfSheduled_ScreenspacePoint_prioText_cam[i].color, listOfSheduled_ScreenspacePoint_prioText_cam[i].sizeOfMarkingCross_relToViewportHeight, listOfSheduled_ScreenspacePoint_prioText_cam[i].markingCrossLinesWidth_relToViewportHeight, listOfSheduled_ScreenspacePoint_prioText_cam[i].zRotationDegCC, listOfSheduled_ScreenspacePoint_prioText_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspacePoint_prioText_cam[i].pointer_as_textAttachStyle, listOfSheduled_ScreenspacePoint_prioText_cam[i].drawCoordsAsText, listOfSheduled_ScreenspacePoint_prioText_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspacePoint_prioText_cam[i].durationInSec); + } + listOfSheduled_ScreenspacePoint_prioText_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspacePointTag_3Dpos.Count; i++) + { + DrawScreenspace.PointTag(listOfSheduled_ScreenspacePointTag_3Dpos[i].position_in3DWorldspace, listOfSheduled_ScreenspacePointTag_3Dpos[i].text, listOfSheduled_ScreenspacePointTag_3Dpos[i].titleText, listOfSheduled_ScreenspacePointTag_3Dpos[i].color, listOfSheduled_ScreenspacePointTag_3Dpos[i].drawPointerIfOffscreen, listOfSheduled_ScreenspacePointTag_3Dpos[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspacePointTag_3Dpos[i].size_asTextOffsetDistance_relToViewportHeight, listOfSheduled_ScreenspacePointTag_3Dpos[i].textOffsetDirection, listOfSheduled_ScreenspacePointTag_3Dpos[i].textSizeScaleFactor, listOfSheduled_ScreenspacePointTag_3Dpos[i].skipConeDrawing, listOfSheduled_ScreenspacePointTag_3Dpos[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspacePointTag_3Dpos[i].durationInSec, listOfSheduled_ScreenspacePointTag_3Dpos[i].customTowardsPoint_ofDefaultTextOffsetDirection); + } + listOfSheduled_ScreenspacePointTag_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspacePointTag_3Dpos_cam.Count; i++) + { + DrawScreenspace.PointTag(listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].targetCamera, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].text, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].titleText, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].color, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].size_asTextOffsetDistance_relToViewportHeight, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].textOffsetDirection, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].textSizeScaleFactor, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].skipConeDrawing, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].durationInSec, listOfSheduled_ScreenspacePointTag_3Dpos_cam[i].customTowardsPoint_ofDefaultTextOffsetDirection); + } + listOfSheduled_ScreenspacePointTag_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspacePointTag_2Dpos_cam.Count; i++) + { + DrawScreenspace.PointTag(listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].targetCamera, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].text, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].titleText, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].color, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].drawPointerIfOffscreen, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].linesWidth_relToViewportHeight, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].size_asTextOffsetDistance_relToViewportHeight, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].textOffsetDirection, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].textSizeScaleFactor, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].skipConeDrawing, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].addTextForOutsideDistance_toOffscreenPointer, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].durationInSec, listOfSheduled_ScreenspacePointTag_2Dpos_cam[i].customTowardsPoint_ofDefaultTextOffsetDirection); + } + listOfSheduled_ScreenspacePointTag_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceVectorFrom.Count; i++) + { + DrawScreenspace.VectorFrom(listOfSheduled_ScreenspaceVectorFrom[i].targetCamera, listOfSheduled_ScreenspaceVectorFrom[i].vectorStartPos, listOfSheduled_ScreenspaceVectorFrom[i].vector, listOfSheduled_ScreenspaceVectorFrom[i].color, listOfSheduled_ScreenspaceVectorFrom[i].lineWidth_relToViewportHeight, listOfSheduled_ScreenspaceVectorFrom[i].text, listOfSheduled_ScreenspaceVectorFrom[i].interpretVectorAsUnwarped, listOfSheduled_ScreenspaceVectorFrom[i].coneLength_relToViewportHeight, listOfSheduled_ScreenspaceVectorFrom[i].pointerAtBothSides, listOfSheduled_ScreenspaceVectorFrom[i].writeComponentValuesAsText, listOfSheduled_ScreenspaceVectorFrom[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceVectorFrom[i].durationInSec); + } + listOfSheduled_ScreenspaceVectorFrom.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceVectorTo.Count; i++) + { + DrawScreenspace.VectorTo(listOfSheduled_ScreenspaceVectorTo[i].targetCamera, listOfSheduled_ScreenspaceVectorTo[i].vector, listOfSheduled_ScreenspaceVectorTo[i].vectorEndPos, listOfSheduled_ScreenspaceVectorTo[i].color, listOfSheduled_ScreenspaceVectorTo[i].lineWidth_relToViewportHeight, listOfSheduled_ScreenspaceVectorTo[i].text, listOfSheduled_ScreenspaceVectorTo[i].interpretVectorAsUnwarped, listOfSheduled_ScreenspaceVectorTo[i].coneLength_relToViewportHeight, listOfSheduled_ScreenspaceVectorTo[i].pointerAtBothSides, listOfSheduled_ScreenspaceVectorTo[i].writeComponentValuesAsText, listOfSheduled_ScreenspaceVectorTo[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceVectorTo[i].durationInSec); + } + listOfSheduled_ScreenspaceVectorTo.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam.Count; i++) + { + DrawScreenspace.VectorCircled(listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].targetCamera, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].circleCenter, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].startAngleDegCC_relativeToUp, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].endAngleDegCC_relativeToUp, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].color, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].lineWidth_relToViewportHeight, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].text, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].coneLength_relToViewportHeight, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].skipFallbackDisplayOfZeroAngles, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].pointerAtBothSides, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].minAngleDeg_withoutTextLineBreak, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].textAnchor, listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceVectorCircled_angleToAngle_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam.Count; i++) + { + DrawScreenspace.VectorCircled(listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].targetCamera, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].startPos, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].circleCenter, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].turnAngleDegCC, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].color, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].lineWidth_relToViewportHeight, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].text, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].coneLength_relToViewportHeight, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].skipFallbackDisplayOfZeroAngles, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].pointerAtBothSides, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].minAngleDeg_withoutTextLineBreak, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].textAnchor, listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceVectorCircled_angleFromStartPos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceIcon_3Dpos.Count; i++) + { + DrawScreenspace.Icon(listOfSheduled_ScreenspaceIcon_3Dpos[i].position_in3DWorldspace, listOfSheduled_ScreenspaceIcon_3Dpos[i].icon, listOfSheduled_ScreenspaceIcon_3Dpos[i].color, listOfSheduled_ScreenspaceIcon_3Dpos[i].size_relToViewportHeight, listOfSheduled_ScreenspaceIcon_3Dpos[i].text, listOfSheduled_ScreenspaceIcon_3Dpos[i].zRotationDegCC, listOfSheduled_ScreenspaceIcon_3Dpos[i].strokeWidth_relToViewportHeight, listOfSheduled_ScreenspaceIcon_3Dpos[i].displayPointerIfOffscreen, listOfSheduled_ScreenspaceIcon_3Dpos[i].mirrorHorizontally, listOfSheduled_ScreenspaceIcon_3Dpos[i].durationInSec); + } + listOfSheduled_ScreenspaceIcon_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceIcon_3Dpos_cam.Count; i++) + { + DrawScreenspace.Icon(listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].targetCamera, listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].icon, listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].color, listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].size_relToViewportHeight, listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].text, listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].zRotationDegCC, listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].strokeWidth_relToViewportHeight, listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].displayPointerIfOffscreen, listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].mirrorHorizontally, listOfSheduled_ScreenspaceIcon_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceIcon_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceIcon_2Dpos_cam.Count; i++) + { + DrawScreenspace.Icon(listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].targetCamera, listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].icon, listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].color, listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].size_relToViewportHeight, listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].text, listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].zRotationDegCC, listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].strokeWidth_relToViewportHeight, listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].displayPointerIfOffscreen, listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].mirrorHorizontally, listOfSheduled_ScreenspaceIcon_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceIcon_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceDot_3Dpos.Count; i++) + { + DrawScreenspace.Dot(listOfSheduled_ScreenspaceDot_3Dpos[i].position_in3DWorldspace, listOfSheduled_ScreenspaceDot_3Dpos[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceDot_3Dpos[i].color, listOfSheduled_ScreenspaceDot_3Dpos[i].text, listOfSheduled_ScreenspaceDot_3Dpos[i].density, listOfSheduled_ScreenspaceDot_3Dpos[i].displayPointerIfOffscreen, listOfSheduled_ScreenspaceDot_3Dpos[i].durationInSec); + } + listOfSheduled_ScreenspaceDot_3Dpos.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceDot_3Dpos_cam.Count; i++) + { + DrawScreenspace.Dot(listOfSheduled_ScreenspaceDot_3Dpos_cam[i].targetCamera, listOfSheduled_ScreenspaceDot_3Dpos_cam[i].position_in3DWorldspace, listOfSheduled_ScreenspaceDot_3Dpos_cam[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceDot_3Dpos_cam[i].color, listOfSheduled_ScreenspaceDot_3Dpos_cam[i].text, listOfSheduled_ScreenspaceDot_3Dpos_cam[i].density, listOfSheduled_ScreenspaceDot_3Dpos_cam[i].displayPointerIfOffscreen, listOfSheduled_ScreenspaceDot_3Dpos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceDot_3Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceDot_2Dpos_cam.Count; i++) + { + DrawScreenspace.Dot(listOfSheduled_ScreenspaceDot_2Dpos_cam[i].targetCamera, listOfSheduled_ScreenspaceDot_2Dpos_cam[i].position_in2DViewportSpace, listOfSheduled_ScreenspaceDot_2Dpos_cam[i].radius_relToViewportHeight, listOfSheduled_ScreenspaceDot_2Dpos_cam[i].color, listOfSheduled_ScreenspaceDot_2Dpos_cam[i].text, listOfSheduled_ScreenspaceDot_2Dpos_cam[i].density, listOfSheduled_ScreenspaceDot_2Dpos_cam[i].displayPointerIfOffscreen, listOfSheduled_ScreenspaceDot_2Dpos_cam[i].durationInSec); + } + listOfSheduled_ScreenspaceDot_2Dpos_cam.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceMovingArrowsRay.Count; i++) + { + DrawScreenspace.MovingArrowsRay(listOfSheduled_ScreenspaceMovingArrowsRay[i].targetCamera, listOfSheduled_ScreenspaceMovingArrowsRay[i].start, listOfSheduled_ScreenspaceMovingArrowsRay[i].direction, listOfSheduled_ScreenspaceMovingArrowsRay[i].color, listOfSheduled_ScreenspaceMovingArrowsRay[i].lineWidth_relToViewportHeight, listOfSheduled_ScreenspaceMovingArrowsRay[i].distanceBetweenArrows_relToViewportHeight, listOfSheduled_ScreenspaceMovingArrowsRay[i].lengthOfArrows_relToViewportHeight, listOfSheduled_ScreenspaceMovingArrowsRay[i].text, listOfSheduled_ScreenspaceMovingArrowsRay[i].animationSpeed, listOfSheduled_ScreenspaceMovingArrowsRay[i].backwardAnimationFlipsArrowDirection, listOfSheduled_ScreenspaceMovingArrowsRay[i].interpretDirectionAsUnwarped, listOfSheduled_ScreenspaceMovingArrowsRay[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceMovingArrowsRay[i].durationInSec); + } + listOfSheduled_ScreenspaceMovingArrowsRay.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceMovingArrowsLine.Count; i++) + { + DrawScreenspace.MovingArrowsLine(listOfSheduled_ScreenspaceMovingArrowsLine[i].targetCamera, listOfSheduled_ScreenspaceMovingArrowsLine[i].start, listOfSheduled_ScreenspaceMovingArrowsLine[i].end, listOfSheduled_ScreenspaceMovingArrowsLine[i].color, listOfSheduled_ScreenspaceMovingArrowsLine[i].lineWidth_relToViewportHeight, listOfSheduled_ScreenspaceMovingArrowsLine[i].distanceBetweenArrows_relToViewportHeight, listOfSheduled_ScreenspaceMovingArrowsLine[i].lengthOfArrows_relToViewportHeight, listOfSheduled_ScreenspaceMovingArrowsLine[i].text, listOfSheduled_ScreenspaceMovingArrowsLine[i].animationSpeed, listOfSheduled_ScreenspaceMovingArrowsLine[i].backwardAnimationFlipsArrowDirection, listOfSheduled_ScreenspaceMovingArrowsLine[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceMovingArrowsLine[i].durationInSec); + } + listOfSheduled_ScreenspaceMovingArrowsLine.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceRayWithAlternatingColors.Count; i++) + { + DrawScreenspace.RayWithAlternatingColors(listOfSheduled_ScreenspaceRayWithAlternatingColors[i].targetCamera, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].start, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].direction, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].color1, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].color2, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].lineWidth_relToViewportHeight, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].lengthOfStripes_relToViewportHeight, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].text, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].interpretDirectionAsUnwarped, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].animationSpeed, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceRayWithAlternatingColors[i].durationInSec); + } + listOfSheduled_ScreenspaceRayWithAlternatingColors.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineWithAlternatingColors.Count; i++) + { + DrawScreenspace.LineWithAlternatingColors(listOfSheduled_ScreenspaceLineWithAlternatingColors[i].targetCamera, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].start, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].end, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].color1, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].color2, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].lineWidth_relToViewportHeight, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].lengthOfStripes_relToViewportHeight, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].text, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].animationSpeed, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceLineWithAlternatingColors[i].durationInSec); + } + listOfSheduled_ScreenspaceLineWithAlternatingColors.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceBlinkingRay.Count; i++) + { + DrawScreenspace.BlinkingRay(listOfSheduled_ScreenspaceBlinkingRay[i].targetCamera, listOfSheduled_ScreenspaceBlinkingRay[i].start, listOfSheduled_ScreenspaceBlinkingRay[i].direction, listOfSheduled_ScreenspaceBlinkingRay[i].primaryColor, listOfSheduled_ScreenspaceBlinkingRay[i].blinkDurationInSec, listOfSheduled_ScreenspaceBlinkingRay[i].width_relToViewportHeight, listOfSheduled_ScreenspaceBlinkingRay[i].text, listOfSheduled_ScreenspaceBlinkingRay[i].interpretDirectionAsUnwarped, listOfSheduled_ScreenspaceBlinkingRay[i].style, listOfSheduled_ScreenspaceBlinkingRay[i].blinkColor, listOfSheduled_ScreenspaceBlinkingRay[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceBlinkingRay[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceBlinkingRay[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceBlinkingRay[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceBlinkingRay[i].durationInSec); + } + listOfSheduled_ScreenspaceBlinkingRay.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceBlinkingLine.Count; i++) + { + DrawScreenspace.BlinkingLine(listOfSheduled_ScreenspaceBlinkingLine[i].targetCamera, listOfSheduled_ScreenspaceBlinkingLine[i].start, listOfSheduled_ScreenspaceBlinkingLine[i].end, listOfSheduled_ScreenspaceBlinkingLine[i].primaryColor, listOfSheduled_ScreenspaceBlinkingLine[i].blinkDurationInSec, listOfSheduled_ScreenspaceBlinkingLine[i].width_relToViewportHeight, listOfSheduled_ScreenspaceBlinkingLine[i].text, listOfSheduled_ScreenspaceBlinkingLine[i].style, listOfSheduled_ScreenspaceBlinkingLine[i].blinkColor, listOfSheduled_ScreenspaceBlinkingLine[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceBlinkingLine[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceBlinkingLine[i].alphaFadeOutLength_0to1, listOfSheduled_ScreenspaceBlinkingLine[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceBlinkingLine[i].durationInSec); + } + listOfSheduled_ScreenspaceBlinkingLine.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceRayUnderTension.Count; i++) + { + DrawScreenspace.RayUnderTension(listOfSheduled_ScreenspaceRayUnderTension[i].targetCamera, listOfSheduled_ScreenspaceRayUnderTension[i].start, listOfSheduled_ScreenspaceRayUnderTension[i].direction, listOfSheduled_ScreenspaceRayUnderTension[i].relaxedLength_relToViewportHeight, listOfSheduled_ScreenspaceRayUnderTension[i].relaxedColor, listOfSheduled_ScreenspaceRayUnderTension[i].style, listOfSheduled_ScreenspaceRayUnderTension[i].stretchFactor_forStretchedTensionColor, listOfSheduled_ScreenspaceRayUnderTension[i].color_forStretchedTension, listOfSheduled_ScreenspaceRayUnderTension[i].stretchFactor_forSqueezedTensionColor, listOfSheduled_ScreenspaceRayUnderTension[i].color_forSqueezedTension, listOfSheduled_ScreenspaceRayUnderTension[i].width_relToViewportHeight, listOfSheduled_ScreenspaceRayUnderTension[i].text, listOfSheduled_ScreenspaceRayUnderTension[i].alphaOfReferenceLengthDisplay, listOfSheduled_ScreenspaceRayUnderTension[i].interpretDirectionAsUnwarped, listOfSheduled_ScreenspaceRayUnderTension[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceRayUnderTension[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceRayUnderTension[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceRayUnderTension[i].durationInSec); + } + listOfSheduled_ScreenspaceRayUnderTension.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceLineUnderTension.Count; i++) + { + DrawScreenspace.LineUnderTension(listOfSheduled_ScreenspaceLineUnderTension[i].targetCamera, listOfSheduled_ScreenspaceLineUnderTension[i].start, listOfSheduled_ScreenspaceLineUnderTension[i].end, listOfSheduled_ScreenspaceLineUnderTension[i].relaxedLength_relToViewportHeight, listOfSheduled_ScreenspaceLineUnderTension[i].relaxedColor, listOfSheduled_ScreenspaceLineUnderTension[i].style, listOfSheduled_ScreenspaceLineUnderTension[i].stretchFactor_forStretchedTensionColor, listOfSheduled_ScreenspaceLineUnderTension[i].color_forStretchedTension, listOfSheduled_ScreenspaceLineUnderTension[i].stretchFactor_forSqueezedTensionColor, listOfSheduled_ScreenspaceLineUnderTension[i].color_forSqueezedTension, listOfSheduled_ScreenspaceLineUnderTension[i].width_relToViewportHeight, listOfSheduled_ScreenspaceLineUnderTension[i].text, listOfSheduled_ScreenspaceLineUnderTension[i].alphaOfReferenceLengthDisplay, listOfSheduled_ScreenspaceLineUnderTension[i].stylePatternScaleFactor, listOfSheduled_ScreenspaceLineUnderTension[i].endPlatesSize_relToViewportHeight, listOfSheduled_ScreenspaceLineUnderTension[i].enlargeSmallTextToThisMinRelTextSize, listOfSheduled_ScreenspaceLineUnderTension[i].durationInSec); + } + listOfSheduled_ScreenspaceLineUnderTension.Clear(); + + for (int i = 0; i < listOfSheduled_ScreenspaceVisualizeAutomaticCameraForDrawing.Count; i++) + { + DrawScreenspace.VisualizeAutomaticCameraForDrawing(listOfSheduled_ScreenspaceVisualizeAutomaticCameraForDrawing[i].visualizeFrustum, listOfSheduled_ScreenspaceVisualizeAutomaticCameraForDrawing[i].logPositionToConsole, listOfSheduled_ScreenspaceVisualizeAutomaticCameraForDrawing[i].color, listOfSheduled_ScreenspaceVisualizeAutomaticCameraForDrawing[i].durationInSec); + } + listOfSheduled_ScreenspaceVisualizeAutomaticCameraForDrawing.Clear(); + + for (int i = 0; i < listOfSheduled_DrawScreenspaceChart.Count; i++) + { + listOfSheduled_DrawScreenspaceChart[i].concernedChartDrawing.DrawScreenspace(listOfSheduled_DrawScreenspaceChart[i].targetCamera, listOfSheduled_DrawScreenspaceChart[i].chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, listOfSheduled_DrawScreenspaceChart[i].durationInSec); + } + listOfSheduled_DrawScreenspaceChart.Clear(); + + for (int i = 0; i < listOfSheduled_DrawScreenspacePieChart.Count; i++) + { + listOfSheduled_DrawScreenspacePieChart[i].concernedPieChartDrawing.DrawScreenspace(listOfSheduled_DrawScreenspacePieChart[i].targetCamera, listOfSheduled_DrawScreenspacePieChart[i].chartSize_isDefinedRelTo_cameraWidth_notCameraHeight, listOfSheduled_DrawScreenspacePieChart[i].durationInSec); + } + listOfSheduled_DrawScreenspacePieChart.Clear(); + } + atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = false; + } + catch { } + + noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem = true; + } + + //-> The char-specificationsViaVectorPositions should not be "static" (e.g. inside "UtilitiesDXXL_CharsAndIcons"), and are therefore declared here as part of the instanced Manager-Component + //-> The problem with "static" here would be: + //---> Static member declarations will automatically get moved to the static constructor of the containing class by the compiler. + //---> Static constructors get initialized "lazy", that means the static constructor happens unpredictably delayed during the running game, in the moment when the member is used for the first time. + //---> Moreover the delayed static constructor is not guaranteed to happen inside the main thread, but can also happen in a worker thread. + //---> There is no controll over the worker threads in the background. This lead to "stack overflow" errors, and "nullReferenceExceptions" as aftereffect. + //Addendum: + //-> it was not enough to move the char and symbol definitions here to this class as non static fields. + //-> obscure errors appeared (freeze on enter playmode, freeze on addDrawerComponent, stack overflow on enter playmode in the DrawXXL_LinesManager.ctor, ...) + //-> for further details, see: https://forum.unity.com/threads/initializing-many-vector-arrays-in-constructor-causes-stack-overflow.1434982/ + //-> it somehow appears as if the field initializers of the chars are moved to the DrawXXL_LinesManager.ctor and produce some kind of overload there. + //-> the fix for these errors was "lazy initialization" of the fields. They now get initialized when they are called the first time, but not all at once in the DrawXXL_LinesManager.ctor + + + const int maxStrokesPerSymbol = 30; + public int numberOfStrokes_forCurrUsedChar = 0; + public int[] numberOfPointsForEachStroke_forCurrUsedChar = new int[maxStrokesPerSymbol]; + public Vector3[][] currPrinted_charDef = new Vector3[maxStrokesPerSymbol][] + { + new Vector3[71], + new Vector3[44], + new Vector3[44], + new Vector3[20], + new Vector3[16], + new Vector3[16], + new Vector3[16], + new Vector3[16], + new Vector3[16], + new Vector3[14], + new Vector3[8], + new Vector3[8], + new Vector3[8], + new Vector3[8], + new Vector3[8], + new Vector3[8], + new Vector3[8], + new Vector3[8], + new Vector3[8], + new Vector3[7], + new Vector3[7], + new Vector3[7], + new Vector3[5], + new Vector3[5], + new Vector3[3], + new Vector3[3], + new Vector3[3], + new Vector3[3], + new Vector3[3], + new Vector3[3] + }; + + + + Vector3[][] Char_a() { if (char_a == null) { char_a = new Vector3[][] { new Vector3[] { new Vector2(0.723f, 0.165f), new Vector2(0.539f, 0.035f), new Vector2(0.263f, 0.037f), new Vector2(0.173f, 0.1421f), new Vector2(0.1761f, 0.2576f), new Vector2(0.3387f, 0.3954f), new Vector2(0.5582f, 0.4002f), new Vector2(0.7232f, 0.3654f) }, new Vector3[] { new Vector2(0.25f, 0.641f), new Vector2(0.397f, 0.698f), new Vector2(0.586f, 0.697f), new Vector2(0.724f, 0.579f), new Vector2(0.724f, 0.044f), new Vector2(0.84f, 0.044f) } }; } return char_a; } + Vector3[][] Char_b() { if (char_b == null) { char_b = new Vector3[][] { new Vector3[] { new Vector2(0.225f, 0.256f), new Vector2(0.458f, 0.035f), new Vector2(0.644f, 0.037f), new Vector2(0.795f, 0.1421f), new Vector2(0.873f, 0.289f), new Vector2(0.875f, 0.438f), new Vector2(0.791f, 0.583f), new Vector2(0.651f, 0.692f), new Vector2(0.465f, 0.692f), new Vector2(0.226f, 0.481f) }, new Vector3[] { new Vector2(0.1f, 0.972f), new Vector2(0.23f, 0.966f), new Vector2(0.227f, 0.042f), new Vector2(0.122f, 0.043f) } }; } return char_b; } + Vector3[][] Char_c() { if (char_c == null) { char_c = new Vector3[][] { new Vector3[] { new Vector2(0.877f, 0.158f), new Vector2(0.653f, 0.035f), new Vector2(0.425f, 0.037f), new Vector2(0.265f, 0.147f), new Vector2(0.1991f, 0.289f), new Vector2(0.2052f, 0.438f), new Vector2(0.279f, 0.595f), new Vector2(0.4362f, 0.692f), new Vector2(0.6296f, 0.692f), new Vector2(0.7598f, 0.6229f), new Vector2(0.8288f, 0.511f), new Vector2(0.826f, 0.6743f) } }; } return char_c; } + Vector3[][] Char_d() { if (char_d == null) { char_d = new Vector3[][] { new Vector3[] { new Vector2(0.806f, 0.265f), new Vector2(0.579f, 0.035f), new Vector2(0.3861f, 0.037f), new Vector2(0.2268f, 0.147f), new Vector2(0.1556f, 0.289f), new Vector2(0.1541f, 0.438f), new Vector2(0.2408f, 0.595f), new Vector2(0.3874f, 0.692f), new Vector2(0.5582f, 0.692f), new Vector2(0.6832f, 0.6229f), new Vector2(0.8036f, 0.4701f) }, new Vector3[] { new Vector2(0.91f, 0.049f), new Vector2(0.807f, 0.05f), new Vector2(0.807f, 0.968f), new Vector2(0.677f, 0.97f) } }; } return char_d; } + Vector3[][] Char_e() { if (char_e == null) { char_e = new Vector3[][] { new Vector3[] { new Vector2(0.837f, 0.128f), new Vector2(0.654f, 0.035f), new Vector2(0.419f, 0.037f), new Vector2(0.256f, 0.147f), new Vector2(0.174f, 0.303f), new Vector2(0.171f, 0.438f), new Vector2(0.259f, 0.595f), new Vector2(0.423f, 0.692f), new Vector2(0.584f, 0.692f), new Vector2(0.747f, 0.581f), new Vector2(0.824f, 0.376f), new Vector2(0.172f, 0.376f) } }; } return char_e; } + Vector3[][] Char_f() { if (char_f == null) { char_f = new Vector3[][] { new Vector3[] { new Vector2(0.43f, 0.041f), new Vector2(0.431f, 0.827f), new Vector2(0.566f, 0.97f), new Vector2(0.863f, 0.956f) }, new Vector3[] { new Vector2(0.228f, 0.04f), new Vector2(0.764f, 0.048f) }, new Vector3[] { new Vector2(0.23f, 0.671f), new Vector2(0.762f, 0.677f) } }; } return char_f; } + Vector3[][] Char_g() { if (char_g == null) { char_g = new Vector3[][] { new Vector3[] { new Vector2(0.758f, 0.246f), new Vector2(0.578f, 0.051f), new Vector2(0.374f, 0.049f), new Vector2(0.183f, 0.273f), new Vector2(0.184f, 0.484f), new Vector2(0.358f, 0.682f), new Vector2(0.56f, 0.682f), new Vector2(0.757f, 0.495f) }, new Vector3[] { new Vector2(0.334f, -0.252f), new Vector2(0.559f, -0.255f), new Vector2(0.757f, -0.082f), new Vector2(0.76f, 0.674f), new Vector2(0.861f, 0.676f) } }; } return char_g; } + Vector3[][] Char_h() { if (char_h == null) { char_h = new Vector3[][] { new Vector3[] { new Vector2(0.242f, 0.532f), new Vector2(0.435f, 0.691f), new Vector2(0.63f, 0.69f), new Vector2(0.775f, 0.552f), new Vector2(0.776f, 0.046f) }, new Vector3[] { new Vector2(0.118f, 0.965f), new Vector2(0.242f, 0.963f), new Vector2(0.241f, 0.047f) }, new Vector3[] { new Vector2(0.13f, 0.048f), new Vector2(0.361f, 0.046f) }, new Vector3[] { new Vector2(0.662f, 0.045f), new Vector2(0.878f, 0.044f) } }; } return char_h; } + Vector3[][] Char_i() { if (char_i == null) { char_i = new Vector3[][] { new Vector3[] { new Vector2(0.271f, 0.68f), new Vector2(0.502f, 0.676f), new Vector2(0.503f, 0.041f) }, new Vector3[] { new Vector2(0.206f, 0.045f), new Vector2(0.792f, 0.044f) }, new Vector3[] { new Vector2(0.485f, 1.006f), new Vector2(0.486f, 0.901f) } }; } return char_i; } + Vector3[][] Char_j() { if (char_j == null) { char_j = new Vector3[][] { new Vector3[] { new Vector2(0.216f, 0.68f), new Vector2(0.637f, 0.676f), new Vector2(0.639f, -0.071f), new Vector2(0.499f, -0.249f), new Vector2(0.211f, -0.253f) }, new Vector3[] { new Vector2(0.561f, 0.999f), new Vector2(0.558f, 0.903f) } }; } return char_j; } + Vector3[][] Char_k() { if (char_k == null) { char_k = new Vector3[][] { new Vector3[] { new Vector2(0.216f, 0.97f), new Vector2(0.335f, 0.969f), new Vector2(0.331f, 0.044f), new Vector2(0.23f, 0.046f) }, new Vector3[] { new Vector2(0.735f, 0.671f), new Vector2(0.345f, 0.327f) }, new Vector3[] { new Vector2(0.667f, 0.05f), new Vector2(0.888f, 0.05f) }, new Vector3[] { new Vector2(0.64f, 0.672f), new Vector2(0.826f, 0.668f) }, new Vector3[] { new Vector2(0.46f, 0.403f), new Vector2(0.811f, 0.05f) } }; } return char_k; } + Vector3[][] Char_l() { if (char_l == null) { char_l = new Vector3[][] { new Vector3[] { new Vector2(0.266f, 0.97f), new Vector2(0.496f, 0.969f), new Vector2(0.497f, 0.044f) }, new Vector3[] { new Vector2(0.206f, 0.043f), new Vector2(0.785f, 0.045f) } }; } return char_l; } + Vector3[][] Char_m() { if (char_m == null) { char_m = new Vector3[][] { new Vector3[] { new Vector2(0.178f, 0.55f), new Vector2(0.317f, 0.688f), new Vector2(0.426f, 0.686f), new Vector2(0.527f, 0.603f), new Vector2(0.523f, 0.05f), new Vector2(0.623f, 0.048f) }, new Vector3[] { new Vector2(0.523f, 0.549f), new Vector2(0.658f, 0.689f), new Vector2(0.787f, 0.691f), new Vector2(0.871f, 0.592f), new Vector2(0.872f, 0.046f), new Vector2(0.943f, 0.045f) }, new Vector3[] { new Vector2(0.074f, 0.681f), new Vector2(0.178f, 0.678f), new Vector2(0.175f, 0.047f) }, new Vector3[] { new Vector2(0.075f, 0.047f), new Vector2(0.275f, 0.046f) } }; } return char_m; } + Vector3[][] Char_n() { if (char_n == null) { char_n = new Vector3[][] { new Vector3[] { new Vector2(0.277f, 0.514f), new Vector2(0.465f, 0.688f), new Vector2(0.65f, 0.686f), new Vector2(0.784f, 0.538f), new Vector2(0.784f, 0.05f) }, new Vector3[] { new Vector2(0.161f, 0.685f), new Vector2(0.272f, 0.681f), new Vector2(0.274f, 0.045f) }, new Vector3[] { new Vector2(0.163f, 0.045f), new Vector2(0.374f, 0.045f) }, new Vector3[] { new Vector2(0.684f, 0.047f), new Vector2(0.897f, 0.046f) } }; } return char_n; } + Vector3[][] Char_o() { if (char_o == null) { char_o = new Vector3[][] { new Vector3[] { new Vector2(0.182f, 0.438f), new Vector2(0.254f, 0.587f), new Vector2(0.407f, 0.686f), new Vector2(0.595f, 0.686f), new Vector2(0.767f, 0.59f), new Vector2(0.847f, 0.439f), new Vector2(0.849f, 0.304f), new Vector2(0.776f, 0.152f), new Vector2(0.611f, 0.038f), new Vector2(0.414f, 0.039f), new Vector2(0.26f, 0.134f), new Vector2(0.184f, 0.267f), new Vector2(0.182f, 0.438f) } }; } return char_o; } + Vector3[][] Char_p() { if (char_p == null) { char_p = new Vector3[][] { new Vector3[] { new Vector2(0.212f, 0.438f), new Vector2(0.284f, 0.587f), new Vector2(0.437f, 0.686f), new Vector2(0.625f, 0.686f), new Vector2(0.797f, 0.59f), new Vector2(0.877f, 0.439f), new Vector2(0.8789999f, 0.304f), new Vector2(0.806f, 0.152f), new Vector2(0.641f, 0.038f), new Vector2(0.444f, 0.039f), new Vector2(0.29f, 0.134f), new Vector2(0.214f, 0.267f), new Vector2(0.212f, 0.438f) }, new Vector3[] { new Vector2(0.107f, 0.676f), new Vector2(0.219f, 0.675f), new Vector2(0.218f, -0.249f) }, new Vector3[] { new Vector2(0.106f, -0.25f), new Vector2(0.414f, -0.252f) } }; } return char_p; } + Vector3[][] Char_q() { if (char_q == null) { char_q = new Vector3[][] { new Vector3[] { new Vector2(0.139f, 0.438f), new Vector2(0.211f, 0.587f), new Vector2(0.364f, 0.686f), new Vector2(0.552f, 0.686f), new Vector2(0.724f, 0.59f), new Vector2(0.804f, 0.439f), new Vector2(0.806f, 0.304f), new Vector2(0.733f, 0.152f), new Vector2(0.568f, 0.038f), new Vector2(0.371f, 0.039f), new Vector2(0.217f, 0.134f), new Vector2(0.141f, 0.267f), new Vector2(0.139f, 0.438f) }, new Vector3[] { new Vector2(0.896f, 0.676f), new Vector2(0.797f, 0.675f), new Vector2(0.798f, -0.249f) }, new Vector3[] { new Vector2(0.605f, -0.25f), new Vector2(0.891f, -0.252f) } }; } return char_q; } + Vector3[][] Char_r() { if (char_r == null) { char_r = new Vector3[][] { new Vector3[] { new Vector2(0.408f, 0.445f), new Vector2(0.602f, 0.644f), new Vector2(0.682f, 0.686f), new Vector2(0.8f, 0.686f), new Vector2(0.864f, 0.629f) }, new Vector3[] { new Vector2(0.245f, 0.676f), new Vector2(0.399f, 0.675f), new Vector2(0.403f, 0.041f) }, new Vector3[] { new Vector2(0.207f, 0.044f), new Vector2(0.72f, 0.048f) } }; } return char_r; } + Vector3[][] Char_s() { if (char_s == null) { char_s = new Vector3[][] { new Vector3[] { new Vector2(0.222f, 0.137f), new Vector2(0.392f, 0.042f), new Vector2(0.643f, 0.041f), new Vector2(0.797f, 0.139f), new Vector2(0.796f, 0.251f), new Vector2(0.678f, 0.355f), new Vector2(0.371f, 0.414f), new Vector2(0.271f, 0.486f), new Vector2(0.271f, 0.594f), new Vector2(0.396f, 0.686f), new Vector2(0.6f, 0.696f), new Vector2(0.75f, 0.605f) }, new Vector3[] { new Vector2(0.748f, 0.676f), new Vector2(0.751f, 0.538f) }, new Vector3[] { new Vector2(0.218f, 0.044f), new Vector2(0.22f, 0.226f) } }; } return char_s; } + Vector3[][] Char_t() { if (char_t == null) { char_t = new Vector3[][] { new Vector3[] { new Vector2(0.331f, 0.906f), new Vector2(0.334f, 0.155f), new Vector2(0.43f, 0.038f), new Vector2(0.666f, 0.034f), new Vector2(0.815f, 0.109f) }, new Vector3[] { new Vector2(0.748f, 0.676f), new Vector2(0.18f, 0.677f) } }; } return char_t; } + Vector3[][] Char_u() { if (char_u == null) { char_u = new Vector3[][] { new Vector3[] { new Vector2(0.136f, 0.675f), new Vector2(0.24f, 0.676f), new Vector2(0.242f, 0.164f), new Vector2(0.347f, 0.04f), new Vector2(0.543f, 0.04f), new Vector2(0.779f, 0.185f) }, new Vector3[] { new Vector2(0.617f, 0.676f), new Vector2(0.776f, 0.677f), new Vector2(0.779f, 0.044f), new Vector2(0.87f, 0.045f) } }; } return char_u; } + Vector3[][] Char_v() { if (char_v == null) { char_v = new Vector3[][] { new Vector3[] { new Vector2(0.241f, 0.675f), new Vector2(0.529f, 0.036f), new Vector2(0.819f, 0.678f) }, new Vector3[] { new Vector2(0.651f, 0.676f), new Vector2(0.906f, 0.677f) }, new Vector3[] { new Vector2(0.137f, 0.674f), new Vector2(0.395f, 0.675f) } }; } return char_v; } + Vector3[][] Char_w() { if (char_w == null) { char_w = new Vector3[][] { new Vector3[] { new Vector2(0.169f, 0.675f), new Vector2(0.299f, 0.036f), new Vector2(0.52f, 0.495f), new Vector2(0.743f, 0.034f), new Vector2(0.877f, 0.675f) }, new Vector3[] { new Vector2(0.754f, 0.676f), new Vector2(0.923f, 0.677f) }, new Vector3[] { new Vector2(0.101f, 0.674f), new Vector2(0.282f, 0.675f) } }; } return char_w; } + Vector3[][] Char_x() { if (char_x == null) { char_x = new Vector3[][] { new Vector3[] { new Vector2(0.232f, 0.675f), new Vector2(0.836f, 0.053f) }, new Vector3[] { new Vector2(0.637f, 0.676f), new Vector2(0.823f, 0.677f) }, new Vector3[] { new Vector2(0.179f, 0.674f), new Vector2(0.368f, 0.675f) }, new Vector3[] { new Vector2(0.136f, 0.048f), new Vector2(0.351f, 0.049f) }, new Vector3[] { new Vector2(0.653f, 0.051f), new Vector2(0.874f, 0.053f) }, new Vector3[] { new Vector2(0.174f, 0.049f), new Vector2(0.782f, 0.676f) } }; } return char_x; } + Vector3[][] Char_y() { if (char_y == null) { char_y = new Vector3[][] { new Vector3[] { new Vector2(0.232f, 0.675f), new Vector2(0.553f, 0.031f) }, new Vector3[] { new Vector2(0.737f, 0.676f), new Vector2(0.914f, 0.677f) }, new Vector3[] { new Vector2(0.179f, 0.674f), new Vector2(0.357f, 0.675f) }, new Vector3[] { new Vector2(0.428f, -0.252f), new Vector2(0.865f, 0.674f) }, new Vector3[] { new Vector2(0.193f, -0.252f), new Vector2(0.531f, -0.25f) } }; } return char_y; } + Vector3[][] Char_z() { if (char_z == null) { char_z = new Vector3[][] { new Vector3[] { new Vector2(0.268f, 0.567f), new Vector2(0.27f, 0.677f), new Vector2(0.8f, 0.677f), new Vector2(0.208f, 0.04f), new Vector2(0.8f, 0.04f), new Vector2(0.802f, 0.158f) } }; } return char_z; } + Vector3[][] Char_ae() { if (char_ae == null) { char_ae = new Vector3[][] { new Vector3[] { new Vector2(0.723f, 0.165f), new Vector2(0.539f, 0.035f), new Vector2(0.263f, 0.037f), new Vector2(0.173f, 0.1421f), new Vector2(0.1761f, 0.2576f), new Vector2(0.3387f, 0.3954f), new Vector2(0.5582f, 0.4002f), new Vector2(0.7232f, 0.3654f) }, new Vector3[] { new Vector2(0.25f, 0.641f), new Vector2(0.397f, 0.698f), new Vector2(0.586f, 0.697f), new Vector2(0.724f, 0.579f), new Vector2(0.724f, 0.044f), new Vector2(0.84f, 0.044f) }, new Vector3[] { new Vector2(0.328f, 0.83f), new Vector2(0.277f, 0.855f), new Vector2(0.277f, 0.913f), new Vector2(0.329f, 0.95f), new Vector2(0.382f, 0.923f), new Vector2(0.383f, 0.855f), new Vector2(0.328f, 0.83f) }, new Vector3[] { new Vector2(0.655f, 0.83f), new Vector2(0.598f, 0.856f), new Vector2(0.598f, 0.921f), new Vector2(0.651f, 0.951f), new Vector2(0.71f, 0.9191f), new Vector2(0.709f, 0.8543f), new Vector2(0.655f, 0.83f) } }; } return char_ae; } + Vector3[][] Char_oe() { if (char_oe == null) { char_oe = new Vector3[][] { new Vector3[] { new Vector2(0.182f, 0.438f), new Vector2(0.254f, 0.587f), new Vector2(0.407f, 0.686f), new Vector2(0.595f, 0.686f), new Vector2(0.767f, 0.59f), new Vector2(0.847f, 0.439f), new Vector2(0.849f, 0.304f), new Vector2(0.776f, 0.152f), new Vector2(0.611f, 0.038f), new Vector2(0.414f, 0.039f), new Vector2(0.26f, 0.134f), new Vector2(0.184f, 0.267f), new Vector2(0.182f, 0.438f) }, new Vector3[] { new Vector2(0.372f, 0.83f), new Vector2(0.321f, 0.855f), new Vector2(0.321f, 0.913f), new Vector2(0.373f, 0.95f), new Vector2(0.426f, 0.923f), new Vector2(0.427f, 0.855f), new Vector2(0.372f, 0.83f) }, new Vector3[] { new Vector2(0.699f, 0.83f), new Vector2(0.642f, 0.856f), new Vector2(0.642f, 0.921f), new Vector2(0.6950001f, 0.951f), new Vector2(0.754f, 0.9191f), new Vector2(0.753f, 0.8543f), new Vector2(0.699f, 0.83f) } }; } return char_oe; } + Vector3[][] Char_ue() { if (char_ue == null) { char_ue = new Vector3[][] { new Vector3[] { new Vector2(0.136f, 0.675f), new Vector2(0.24f, 0.676f), new Vector2(0.242f, 0.164f), new Vector2(0.347f, 0.04f), new Vector2(0.543f, 0.04f), new Vector2(0.779f, 0.185f) }, new Vector3[] { new Vector2(0.617f, 0.676f), new Vector2(0.776f, 0.677f), new Vector2(0.779f, 0.044f), new Vector2(0.87f, 0.045f) }, new Vector3[] { new Vector2(0.372f, 0.83f), new Vector2(0.321f, 0.855f), new Vector2(0.321f, 0.913f), new Vector2(0.373f, 0.95f), new Vector2(0.426f, 0.923f), new Vector2(0.427f, 0.855f), new Vector2(0.372f, 0.83f) }, new Vector3[] { new Vector2(0.699f, 0.83f), new Vector2(0.642f, 0.856f), new Vector2(0.642f, 0.921f), new Vector2(0.6950001f, 0.951f), new Vector2(0.754f, 0.9191f), new Vector2(0.753f, 0.8543f), new Vector2(0.699f, 0.83f) } }; } return char_ue; } + + Vector3[][] Char_A() { if (char_A == null) { char_A = new Vector3[][] { new Vector3[] { new Vector2(0.227f, 0.882f), new Vector2(0.56f, 0.88f), new Vector2(0.868f, 0.035f) }, new Vector3[] { new Vector2(0.152f, 0.03f), new Vector2(0.461f, 0.877f) }, new Vector3[] { new Vector2(0.267f, 0.327f), new Vector2(0.751f, 0.328f) }, new Vector3[] { new Vector2(0.082f, 0.031f), new Vector2(0.296f, 0.033f) }, new Vector3[] { new Vector2(0.721f, 0.035f), new Vector2(0.93f, 0.037f) } }; } return char_A; } + Vector3[][] Char_B() { if (char_B == null) { char_B = new Vector3[][] { new Vector3[] { new Vector2(0.133f, 0.882f), new Vector2(0.633f, 0.88f), new Vector2(0.8f, 0.755f), new Vector2(0.801f, 0.627f), new Vector2(0.631f, 0.469f) }, new Vector3[] { new Vector2(0.247f, 0.469f), new Vector2(0.631f, 0.469f), new Vector2(0.865f, 0.322f), new Vector2(0.867f, 0.161f), new Vector2(0.712f, 0.028f), new Vector2(0.144f, 0.028f) }, new Vector3[] { new Vector2(0.246f, 0.883f), new Vector2(0.247f, 0.029f) } }; } return char_B; } + Vector3[][] Char_C() { if (char_C == null) { char_C = new Vector3[][] { new Vector3[] { new Vector2(0.821f, 0.732f), new Vector2(0.662f, 0.877f), new Vector2(0.514f, 0.91f), new Vector2(0.302f, 0.84f), new Vector2(0.146f, 0.594f), new Vector2(0.148f, 0.32f), new Vector2(0.252f, 0.136f), new Vector2(0.435f, 0.014f), new Vector2(0.647f, 0.009f), new Vector2(0.867f, 0.166f) }, new Vector3[] { new Vector2(0.824f, 0.666f), new Vector2(0.825f, 0.884f) } }; } return char_C; } + Vector3[][] Char_D() { if (char_D == null) { char_D = new Vector3[][] { new Vector3[] { new Vector2(0.201f, 0.879f), new Vector2(0.628f, 0.877f), new Vector2(0.811f, 0.771f), new Vector2(0.897f, 0.577f), new Vector2(0.9f, 0.31f), new Vector2(0.81f, 0.142f), new Vector2(0.624f, 0.028f), new Vector2(0.205f, 0.025f) }, new Vector3[] { new Vector2(0.294f, 0.025f), new Vector2(0.295f, 0.879f) } }; } return char_D; } + Vector3[][] Char_E() { if (char_E == null) { char_E = new Vector3[][] { new Vector3[] { new Vector2(0.14f, 0.879f), new Vector2(0.777f, 0.877f), new Vector2(0.777f, 0.701f) }, new Vector3[] { new Vector2(0.149f, 0.025f), new Vector2(0.825f, 0.024f), new Vector2(0.826f, 0.234f) }, new Vector3[] { new Vector2(0.248f, 0.025f), new Vector2(0.249f, 0.88f) }, new Vector3[] { new Vector2(0.249f, 0.466f), new Vector2(0.548f, 0.466f) }, new Vector3[] { new Vector2(0.551f, 0.567f), new Vector2(0.55f, 0.367f) } }; } return char_E; } + Vector3[][] Char_F() { if (char_F == null) { char_F = new Vector3[][] { new Vector3[] { new Vector2(0.226f, 0.879f), new Vector2(0.908f, 0.877f), new Vector2(0.908f, 0.701f) }, new Vector3[] { new Vector2(0.233f, 0.025f), new Vector2(0.597f, 0.024f) }, new Vector3[] { new Vector2(0.338f, 0.025f), new Vector2(0.339f, 0.88f) }, new Vector3[] { new Vector2(0.341f, 0.466f), new Vector2(0.64f, 0.466f) }, new Vector3[] { new Vector2(0.643f, 0.567f), new Vector2(0.642f, 0.367f) } }; } return char_F; } + Vector3[][] Char_G() { if (char_G == null) { char_G = new Vector3[][] { new Vector3[] { new Vector2(0.824f, 0.769f), new Vector2(0.614f, 0.9f), new Vector2(0.423f, 0.903f), new Vector2(0.261f, 0.798f), new Vector2(0.152f, 0.58f), new Vector2(0.152f, 0.309f), new Vector2(0.238f, 0.128f), new Vector2(0.433f, 0.009f), new Vector2(0.635f, 0.004f), new Vector2(0.824f, 0.078f), new Vector2(0.826f, 0.37f) }, new Vector3[] { new Vector2(0.582f, 0.371f), new Vector2(0.88f, 0.371f) }, new Vector3[] { new Vector2(0.824f, 0.713f), new Vector2(0.825f, 0.885f) } }; } return char_G; } + Vector3[][] Char_H() { if (char_H == null) { char_H = new Vector3[][] { new Vector3[] { new Vector2(0.158f, 0.882f), new Vector2(0.354f, 0.882f) }, new Vector3[] { new Vector2(0.135f, 0.027f), new Vector2(0.343f, 0.027f) }, new Vector3[] { new Vector2(0.671f, 0.882f), new Vector2(0.856f, 0.882f) }, new Vector3[] { new Vector2(0.669f, 0.027f), new Vector2(0.871f, 0.027f) }, new Vector3[] { new Vector2(0.243f, 0.027f), new Vector2(0.243f, 0.882f) }, new Vector3[] { new Vector2(0.778f, 0.027f), new Vector2(0.779f, 0.882f) }, new Vector3[] { new Vector2(0.244f, 0.466f), new Vector2(0.777f, 0.467f) } }; } return char_H; } + Vector3[][] Char_I() { if (char_I == null) { char_I = new Vector3[][] { new Vector3[] { new Vector2(0.239f, 0.882f), new Vector2(0.758f, 0.882f) }, new Vector3[] { new Vector2(0.24f, 0.027f), new Vector2(0.757f, 0.027f) }, new Vector3[] { new Vector2(0.501f, 0.882f), new Vector2(0.501f, 0.027f) } }; } return char_I; } + Vector3[][] Char_J() { if (char_J == null) { char_J = new Vector3[][] { new Vector3[] { new Vector2(0.729f, 0.882f), new Vector2(0.729f, 0.203f), new Vector2(0.647f, 0.074f), new Vector2(0.459f, 0.001f), new Vector2(0.3f, 0.044f), new Vector2(0.194f, 0.134f), new Vector2(0.196f, 0.305f) }, new Vector3[] { new Vector2(0.471f, 0.882f), new Vector2(0.879f, 0.882f) } }; } return char_J; } + Vector3[][] Char_K() { if (char_K == null) { char_K = new Vector3[][] { new Vector3[] { new Vector2(0.437f, 0.52f), new Vector2(0.661f, 0.358f), new Vector2(0.796f, 0.03f), new Vector2(0.89f, 0.028f) }, new Vector3[] { new Vector2(0.132f, 0.882f), new Vector2(0.375f, 0.882f) }, new Vector3[] { new Vector2(0.713f, 0.882f), new Vector2(0.897f, 0.885f) }, new Vector3[] { new Vector2(0.237f, 0.88f), new Vector2(0.237f, 0.025f) }, new Vector3[] { new Vector2(0.142f, 0.024f), new Vector2(0.375f, 0.025f) }, new Vector3[] { new Vector2(0.237f, 0.386f), new Vector2(0.857f, 0.882f) } }; } return char_K; } + Vector3[][] Char_L() { if (char_L == null) { char_L = new Vector3[][] { new Vector3[] { new Vector2(0.177f, 0.03f), new Vector2(0.873f, 0.03f), new Vector2(0.875f, 0.25f) }, new Vector3[] { new Vector2(0.184f, 0.882f), new Vector2(0.535f, 0.882f) }, new Vector3[] { new Vector2(0.366f, 0.882f), new Vector2(0.365f, 0.027f) } }; } return char_L; } + Vector3[][] Char_M() { if (char_M == null) { char_M = new Vector3[][] { new Vector3[] { new Vector2(0.103f, 0.882f), new Vector2(0.253f, 0.883f), new Vector2(0.528f, 0.286f), new Vector2(0.782f, 0.884f), new Vector2(0.913f, 0.886f) }, new Vector3[] { new Vector2(0.178f, 0.882f), new Vector2(0.178f, 0.026f) }, new Vector3[] { new Vector2(0.098f, 0.026f), new Vector2(0.302f, 0.027f) }, new Vector3[] { new Vector2(0.85f, 0.885f), new Vector2(0.847f, 0.028f) }, new Vector3[] { new Vector2(0.723f, 0.024f), new Vector2(0.918f, 0.025f) } }; } return char_M; } + Vector3[][] Char_N() { if (char_N == null) { char_N = new Vector3[][] { new Vector3[] { new Vector2(0.103f, 0.882f), new Vector2(0.253f, 0.883f), new Vector2(0.799f, 0.023f), new Vector2(0.8f, 0.884f) }, new Vector3[] { new Vector2(0.217f, 0.882f), new Vector2(0.219f, 0.026f) }, new Vector3[] { new Vector2(0.135f, 0.026f), new Vector2(0.362f, 0.027f) }, new Vector3[] { new Vector2(0.66f, 0.885f), new Vector2(0.877f, 0.885f) } }; } return char_N; } + Vector3[][] Char_O() { if (char_O == null) { char_O = new Vector3[][] { new Vector3[] { new Vector2(0.516f, 0.906f), new Vector2(0.713f, 0.846f), new Vector2(0.844f, 0.673f), new Vector2(0.896f, 0.471f), new Vector2(0.848f, 0.241f), new Vector2(0.708f, 0.061f), new Vector2(0.521f, 0.006f), new Vector2(0.337f, 0.06f), new Vector2(0.191f, 0.229f), new Vector2(0.148f, 0.441f), new Vector2(0.189f, 0.672f), new Vector2(0.312f, 0.833f), new Vector2(0.516f, 0.906f) } }; } return char_O; } + Vector3[][] Char_P() { if (char_P == null) { char_P = new Vector3[][] { new Vector3[] { new Vector2(0.237f, 0.883f), new Vector2(0.663f, 0.883f), new Vector2(0.829f, 0.79f), new Vector2(0.875f, 0.644f), new Vector2(0.824f, 0.497f), new Vector2(0.651f, 0.395f), new Vector2(0.34f, 0.395f) }, new Vector3[] { new Vector2(0.345f, 0.882f), new Vector2(0.346f, 0.027f) }, new Vector3[] { new Vector2(0.236f, 0.026f), new Vector2(0.568f, 0.027f) } }; } return char_P; } + Vector3[][] Char_Q() { if (char_Q == null) { char_Q = new Vector3[][] { new Vector3[] { new Vector2(0.516f, 0.906f), new Vector2(0.713f, 0.846f), new Vector2(0.844f, 0.673f), new Vector2(0.896f, 0.471f), new Vector2(0.848f, 0.241f), new Vector2(0.708f, 0.061f), new Vector2(0.521f, 0.006f), new Vector2(0.337f, 0.06f), new Vector2(0.191f, 0.229f), new Vector2(0.148f, 0.441f), new Vector2(0.189f, 0.672f), new Vector2(0.312f, 0.833f), new Vector2(0.516f, 0.906f) }, new Vector3[] { new Vector2(0.577f, 0.237f), new Vector2(0.871f, -0.077f) } }; } return char_Q; } + Vector3[][] Char_R() { if (char_R == null) { char_R = new Vector3[][] { new Vector3[] { new Vector2(0.138f, 0.883f), new Vector2(0.564f, 0.883f), new Vector2(0.725f, 0.803f), new Vector2(0.782f, 0.664f), new Vector2(0.711f, 0.524f), new Vector2(0.517f, 0.437f), new Vector2(0.241f, 0.442f) }, new Vector3[] { new Vector2(0.519f, 0.436f), new Vector2(0.702f, 0.267f), new Vector2(0.821f, 0.03f), new Vector2(0.881f, 0.032f) }, new Vector3[] { new Vector2(0.142f, 0.026f), new Vector2(0.384f, 0.027f) }, new Vector3[] { new Vector2(0.246f, 0.026f), new Vector2(0.248f, 0.88f) } }; } return char_R; } + Vector3[][] Char_S() { if (char_S == null) { char_S = new Vector3[][] { new Vector3[] { new Vector2(0.756f, 0.763f), new Vector2(0.641f, 0.876f), new Vector2(0.503f, 0.91f), new Vector2(0.328f, 0.854f), new Vector2(0.25f, 0.709f), new Vector2(0.28f, 0.568f), new Vector2(0.424f, 0.486f), new Vector2(0.654f, 0.435f), new Vector2(0.769f, 0.359f), new Vector2(0.809f, 0.226f), new Vector2(0.756f, 0.102f), new Vector2(0.652f, 0.026f), new Vector2(0.502f, 0.001f), new Vector2(0.341f, 0.04f), new Vector2(0.208f, 0.144f) }, new Vector3[] { new Vector2(0.208f, 0.224f), new Vector2(0.207f, 0.047f) }, new Vector3[] { new Vector2(0.757f, 0.701f), new Vector2(0.759f, 0.872f) } }; } return char_S; } + Vector3[][] Char_T() { if (char_T == null) { char_T = new Vector3[][] { new Vector3[] { new Vector2(0.13f, 0.749f), new Vector2(0.132f, 0.879f), new Vector2(0.82f, 0.88f), new Vector2(0.822f, 0.747f) }, new Vector3[] { new Vector2(0.475f, 0.882f), new Vector2(0.474f, 0.027f) }, new Vector3[] { new Vector2(0.346f, 0.025f), new Vector2(0.603f, 0.026f) } }; } return char_T; } + Vector3[][] Char_U() { if (char_U == null) { char_U = new Vector3[][] { new Vector3[] { new Vector2(0.227f, 0.879f), new Vector2(0.227f, 0.242f), new Vector2(0.3f, 0.103f), new Vector2(0.437f, 0.013f), new Vector2(0.602f, 0.01f), new Vector2(0.731f, 0.09f), new Vector2(0.808f, 0.251f), new Vector2(0.811f, 0.879f) }, new Vector3[] { new Vector2(0.693f, 0.883f), new Vector2(0.885f, 0.879f) }, new Vector3[] { new Vector2(0.14f, 0.879f), new Vector2(0.343f, 0.878f) } }; } return char_U; } + Vector3[][] Char_V() { if (char_V == null) { char_V = new Vector3[][] { new Vector3[] { new Vector2(0.17f, 0.879f), new Vector2(0.514f, 0.003f), new Vector2(0.863f, 0.88f) }, new Vector3[] { new Vector2(0.729f, 0.883f), new Vector2(0.913f, 0.879f) }, new Vector3[] { new Vector2(0.107f, 0.879f), new Vector2(0.302f, 0.878f) } }; } return char_V; } + Vector3[][] Char_W() { if (char_W == null) { char_W = new Vector3[][] { new Vector3[] { new Vector2(0.153f, 0.879f), new Vector2(0.269f, 0.009f), new Vector2(0.509f, 0.684f), new Vector2(0.739f, 0.009f), new Vector2(0.854f, 0.878f) }, new Vector3[] { new Vector2(0.694f, 0.878f), new Vector2(0.905f, 0.879f) }, new Vector3[] { new Vector2(0.091f, 0.879f), new Vector2(0.308f, 0.878f) } }; } return char_W; } + Vector3[][] Char_X() { if (char_X == null) { char_X = new Vector3[][] { new Vector3[] { new Vector2(0.184f, 0.879f), new Vector2(0.862f, 0.028f) }, new Vector3[] { new Vector2(0.161f, 0.024f), new Vector2(0.792f, 0.879f) }, new Vector3[] { new Vector2(0.118f, 0.025f), new Vector2(0.302f, 0.026f) }, new Vector3[] { new Vector2(0.136f, 0.881f), new Vector2(0.298f, 0.881f) }, new Vector3[] { new Vector2(0.68f, 0.88f), new Vector2(0.84f, 0.879f) }, new Vector3[] { new Vector2(0.707f, 0.027f), new Vector2(0.902f, 0.027f) } }; } return char_X; } + Vector3[][] Char_Y() { if (char_Y == null) { char_Y = new Vector3[][] { new Vector3[] { new Vector2(0.197f, 0.879f), new Vector2(0.523f, 0.435f), new Vector2(0.836f, 0.88f) }, new Vector3[] { new Vector2(0.522f, 0.436f), new Vector2(0.521f, 0.027f) }, new Vector3[] { new Vector2(0.396f, 0.025f), new Vector2(0.641f, 0.026f) }, new Vector3[] { new Vector2(0.136f, 0.881f), new Vector2(0.311f, 0.881f) }, new Vector3[] { new Vector2(0.732f, 0.88f), new Vector2(0.904f, 0.879f) } }; } return char_Y; } + Vector3[][] Char_Z() { if (char_Z == null) { char_Z = new Vector3[][] { new Vector3[] { new Vector2(0.266f, 0.744f), new Vector2(0.266f, 0.88f), new Vector2(0.781f, 0.88f), new Vector2(0.208f, 0.024f), new Vector2(0.802f, 0.024f), new Vector2(0.802f, 0.198f) } }; } return char_Z; } + Vector3[][] Char_AE() { if (char_AE == null) { char_AE = new Vector3[][] { new Vector3[] { new Vector2(0.227f, 0.882f), new Vector2(0.56f, 0.88f), new Vector2(0.868f, 0.035f) }, new Vector3[] { new Vector2(0.152f, 0.03f), new Vector2(0.461f, 0.877f) }, new Vector3[] { new Vector2(0.267f, 0.327f), new Vector2(0.751f, 0.328f) }, new Vector3[] { new Vector2(0.082f, 0.031f), new Vector2(0.296f, 0.033f) }, new Vector3[] { new Vector2(0.721f, 0.035f), new Vector2(0.93f, 0.037f) }, new Vector3[] { new Vector2(0.303f, 1.024f), new Vector2(0.252f, 1.049f), new Vector2(0.252f, 1.107f), new Vector2(0.304f, 1.144f), new Vector2(0.357f, 1.117f), new Vector2(0.358f, 1.049f), new Vector2(0.303f, 1.024f) }, new Vector3[] { new Vector2(0.63f, 1.024f), new Vector2(0.573f, 1.05f), new Vector2(0.573f, 1.115f), new Vector2(0.626f, 1.145f), new Vector2(0.685f, 1.1131f), new Vector2(0.684f, 1.0483f), new Vector2(0.63f, 1.024f) } }; } return char_AE; } + Vector3[][] Char_OE() { if (char_OE == null) { char_OE = new Vector3[][] { new Vector3[] { new Vector2(0.516f, 0.906f), new Vector2(0.713f, 0.846f), new Vector2(0.844f, 0.673f), new Vector2(0.896f, 0.471f), new Vector2(0.848f, 0.241f), new Vector2(0.708f, 0.061f), new Vector2(0.521f, 0.006f), new Vector2(0.337f, 0.06f), new Vector2(0.191f, 0.229f), new Vector2(0.148f, 0.441f), new Vector2(0.189f, 0.672f), new Vector2(0.312f, 0.833f), new Vector2(0.516f, 0.906f) }, new Vector3[] { new Vector2(0.368f, 1.024f), new Vector2(0.317f, 1.049f), new Vector2(0.317f, 1.107f), new Vector2(0.369f, 1.144f), new Vector2(0.422f, 1.117f), new Vector2(0.423f, 1.049f), new Vector2(0.368f, 1.024f) }, new Vector3[] { new Vector2(0.695f, 1.024f), new Vector2(0.638f, 1.05f), new Vector2(0.638f, 1.115f), new Vector2(0.691f, 1.145f), new Vector2(0.75f, 1.1131f), new Vector2(0.749f, 1.0483f), new Vector2(0.695f, 1.024f) } }; } return char_OE; } + Vector3[][] Char_UE() { if (char_UE == null) { char_UE = new Vector3[][] { new Vector3[] { new Vector2(0.227f, 0.879f), new Vector2(0.227f, 0.242f), new Vector2(0.3f, 0.103f), new Vector2(0.437f, 0.013f), new Vector2(0.602f, 0.01f), new Vector2(0.731f, 0.09f), new Vector2(0.808f, 0.251f), new Vector2(0.811f, 0.879f) }, new Vector3[] { new Vector2(0.693f, 0.883f), new Vector2(0.885f, 0.879f) }, new Vector3[] { new Vector2(0.14f, 0.879f), new Vector2(0.343f, 0.878f) }, new Vector3[] { new Vector2(0.368f, 1.024f), new Vector2(0.317f, 1.049f), new Vector2(0.317f, 1.107f), new Vector2(0.369f, 1.144f), new Vector2(0.422f, 1.117f), new Vector2(0.423f, 1.049f), new Vector2(0.368f, 1.024f) }, new Vector3[] { new Vector2(0.695f, 1.024f), new Vector2(0.638f, 1.05f), new Vector2(0.638f, 1.115f), new Vector2(0.691f, 1.145f), new Vector2(0.75f, 1.1131f), new Vector2(0.749f, 1.0483f), new Vector2(0.695f, 1.024f) } }; } return char_UE; } + + Vector3[][] Char_0() { if (char_0 == null) { char_0 = new Vector3[][] { new Vector3[] { new Vector2(0.451f, 0.004f), new Vector2(0.601f, 0.003f), new Vector2(0.732f, 0.127f), new Vector2(0.803f, 0.317f), new Vector2(0.802f, 0.672f), new Vector2(0.73f, 0.856f), new Vector2(0.603f, 0.971f), new Vector2(0.437f, 0.971f), new Vector2(0.313f, 0.858f), new Vector2(0.246f, 0.671f), new Vector2(0.246f, 0.333f), new Vector2(0.311f, 0.127f), new Vector2(0.451f, 0.004f) } }; } return char_0; } + Vector3[][] Char_1() { if (char_1 == null) { char_1 = new Vector3[][] { new Vector3[] { new Vector2(0.241f, 0.874f), new Vector2(0.522f, 0.966f), new Vector2(0.524f, 0.028f) }, new Vector3[] { new Vector2(0.306f, 0.026f), new Vector2(0.732f, 0.027f) } }; } return char_1; } + Vector3[][] Char_2() { if (char_2 == null) { char_2 = new Vector3[][] { new Vector3[] { new Vector2(0.764f, 0.105f), new Vector2(0.764f, 0.031f), new Vector2(0.183f, 0.031f), new Vector2(0.72f, 0.596f), new Vector2(0.763f, 0.708f), new Vector2(0.752f, 0.804f), new Vector2(0.687f, 0.903f), new Vector2(0.568f, 0.972f), new Vector2(0.42f, 0.967f), new Vector2(0.286f, 0.888f), new Vector2(0.227f, 0.779f) } }; } return char_2; } + Vector3[][] Char_3() { if (char_3 == null) { char_3 = new Vector3[][] { new Vector3[] { new Vector2(0.228f, 0.094f), new Vector2(0.363f, 0.031f), new Vector2(0.519f, 0.001f), new Vector2(0.69f, 0.055f), new Vector2(0.783f, 0.157f), new Vector2(0.81f, 0.284f), new Vector2(0.755f, 0.414f), new Vector2(0.635f, 0.513f), new Vector2(0.481f, 0.535f), new Vector2(0.638f, 0.56f), new Vector2(0.75f, 0.635f), new Vector2(0.786f, 0.779f), new Vector2(0.713f, 0.908f), new Vector2(0.55f, 0.975f), new Vector2(0.375f, 0.951f), new Vector2(0.252f, 0.88f) } }; } return char_3; } + Vector3[][] Char_4() { if (char_4 == null) { char_4 = new Vector3[][] { new Vector3[] { new Vector2(0.66f, 0.03f), new Vector2(0.662f, 0.987f), new Vector2(0.194f, 0.303f), new Vector2(0.797f, 0.304f) }, new Vector3[] { new Vector2(0.528f, 0.029f), new Vector2(0.743f, 0.027f) } }; } return char_4; } + Vector3[][] Char_5() { if (char_5 == null) { char_5 = new Vector3[][] { new Vector3[] { new Vector2(0.228f, 0.124f), new Vector2(0.363f, 0.031f), new Vector2(0.519f, 0.001f), new Vector2(0.69f, 0.049f), new Vector2(0.796f, 0.157f), new Vector2(0.829f, 0.32f), new Vector2(0.791f, 0.491f), new Vector2(0.69f, 0.584f), new Vector2(0.564f, 0.609f), new Vector2(0.438f, 0.582f), new Vector2(0.319f, 0.53f), new Vector2(0.321f, 0.957f), new Vector2(0.722f, 0.958f) } }; } return char_5; } + Vector3[][] Char_6() { if (char_6 == null) { char_6 = new Vector3[][] { new Vector3[] { new Vector2(0.83f, 0.947f), new Vector2(0.707f, 0.98f), new Vector2(0.534f, 0.932f), new Vector2(0.365f, 0.791f), new Vector2(0.277f, 0.567f), new Vector2(0.288f, 0.328f), new Vector2(0.355f, 0.134f), new Vector2(0.51f, 0.009f), new Vector2(0.665f, 0.007f), new Vector2(0.801f, 0.143f), new Vector2(0.829f, 0.319f), new Vector2(0.747f, 0.491f), new Vector2(0.596f, 0.564f), new Vector2(0.431f, 0.51f), new Vector2(0.298f, 0.333f) } }; } return char_6; } + Vector3[][] Char_7() { if (char_7 == null) { char_7 = new Vector3[][] { new Vector3[] { new Vector2(0.222f, 0.863f), new Vector2(0.222f, 0.955f), new Vector2(0.759f, 0.955f), new Vector2(0.486f, 0.021f) } }; } return char_7; } + Vector3[][] Char_8() { if (char_8 == null) { char_8 = new Vector3[][] { new Vector3[] { new Vector2(0.59f, 0.515f), new Vector2(0.416f, 0.518f), new Vector2(0.303f, 0.597f), new Vector2(0.242f, 0.73f), new Vector2(0.296f, 0.875f), new Vector2(0.425f, 0.966f), new Vector2(0.591f, 0.969f), new Vector2(0.702f, 0.891f), new Vector2(0.764f, 0.758f), new Vector2(0.732f, 0.624f), new Vector2(0.59f, 0.515f) }, new Vector3[] { new Vector2(0.591f, 0.515f), new Vector2(0.729f, 0.401f), new Vector2(0.766f, 0.253f), new Vector2(0.713f, 0.098f), new Vector2(0.512f, 0.004f), new Vector2(0.329f, 0.074f), new Vector2(0.253f, 0.247f), new Vector2(0.292f, 0.405f), new Vector2(0.416f, 0.517f) } }; } return char_8; } + Vector3[][] Char_9() { if (char_9 == null) { char_9 = new Vector3[][] { new Vector3[] { new Vector2(0.267f, 0.026f), new Vector2(0.399f, -0.002f), new Vector2(0.572f, 0.047f), new Vector2(0.745f, 0.173f), new Vector2(0.821f, 0.361f), new Vector2(0.813f, 0.663f), new Vector2(0.753f, 0.84f), new Vector2(0.651f, 0.944f), new Vector2(0.52f, 0.978f), new Vector2(0.383f, 0.934f), new Vector2(0.28f, 0.776f), new Vector2(0.28f, 0.612f), new Vector2(0.362f, 0.46f), new Vector2(0.519f, 0.398f), new Vector2(0.696f, 0.468f), new Vector2(0.815f, 0.644f) } }; } return char_9; } + + Vector3[][] Char_space() { if (char_space == null) { char_space = new Vector3[][] { }; } return char_space; } + Vector3[][] Char_unknown() { if (char_unknown == null) { char_unknown = new Vector3[][] { new Vector3[] { new Vector2(0.576f, 0.236f), new Vector2(0.576f, 0.11f), new Vector2(0.751f, 0.111f), new Vector2(0.751f, 0.332f), new Vector2(0.483f, 0.332f), new Vector2(0.576f, 0.332f), new Vector2(0.576f, 0.465f), new Vector2(0.751f, 0.465f), new Vector2(0.751f, 0.685f), new Vector2(0.653f, 0.685f), new Vector2(0.653f, 0.577f), new Vector2(0.751f, 0.577f), new Vector2(0.751f, 0.685f), new Vector2(0.576f, 0.685f), new Vector2(0.576f, 0.577f) }, new Vector3[] { new Vector2(0.33f, 0.069f), new Vector2(0.22f, 0.069f), new Vector2(0.221f, 0.219f), new Vector2(0.33f, 0.219f), new Vector2(0.33f, 0.673f), new Vector2(0.22f, 0.673f), new Vector2(0.22f, 0.755f), new Vector2(0.33f, 0.755f), new Vector2(0.33f, 0.884f) }, new Vector3[] { new Vector2(0.066f, -0.02f), new Vector2(0.066f, 1.024f), new Vector2(0.934f, 1.024f), new Vector2(0.934f, -0.02f), new Vector2(0.066f, -0.02f) }, new Vector3[] { new Vector2(0.751f, 0.828f), new Vector2(0.615f, 0.828f), new Vector2(0.576f, 0.901f) }, new Vector3[] { new Vector2(0.33f, 0.418f), new Vector2(0.22f, 0.336f), new Vector2(0.22f, 0.411f) }, new Vector3[] { new Vector2(0.33f, 0.556f), new Vector2(0.22f, 0.476f), new Vector2(0.22f, 0.544f) }, new Vector3[] { new Vector2(0.22f, 0.141f), new Vector2(0.33f, 0.141f) }, new Vector3[] { new Vector2(0.33f, 0.615f), new Vector2(0.22f, 0.614f) }, new Vector3[] { new Vector2(0.33f, 0.884f), new Vector2(0.33f, 0.813f), new Vector2(0.22f, 0.813f), new Vector2(0.22f, 0.884f), new Vector2(0.4f, 0.884f), new Vector2(0.4f, 0.813f) }, new Vector3[] { new Vector2(0.22f, 0.279f), new Vector2(0.33f, 0.279f) } }; } return char_unknown; } + Vector3[][] Char_dollar() { if (char_dollar == null) { char_dollar = new Vector3[][] { new Vector3[] { new Vector2(0.758f, 0.833f), new Vector2(0.611f, 0.925f), new Vector2(0.419f, 0.918f), new Vector2(0.31f, 0.831f), new Vector2(0.26f, 0.714f), new Vector2(0.35f, 0.565f), new Vector2(0.69f, 0.473f), new Vector2(0.779f, 0.36f), new Vector2(0.779f, 0.253f), new Vector2(0.677f, 0.157f), new Vector2(0.522f, 0.109f), new Vector2(0.373f, 0.137f), new Vector2(0.251f, 0.202f) }, new Vector3[] { new Vector2(0.523f, 0.109f), new Vector2(0.527f, -0.146f) }, new Vector3[] { new Vector2(0.524f, 0.926f), new Vector2(0.523f, 1.063f) }, new Vector3[] { new Vector2(0.25f, 0.112f), new Vector2(0.25f, 0.258f) }, new Vector3[] { new Vector2(0.759f, 0.779f), new Vector2(0.758f, 0.913f) } }; } return char_dollar; } + Vector3[][] Char_euro() { if (char_euro == null) { char_euro = new Vector3[][] { new Vector3[] { new Vector2(0.823f, 0.738f), new Vector2(0.703f, 0.852f), new Vector2(0.603f, 0.902f), new Vector2(0.416f, 0.896f), new Vector2(0.277f, 0.817f), new Vector2(0.189f, 0.69f), new Vector2(0.146f, 0.546f), new Vector2(0.151f, 0.362f), new Vector2(0.208f, 0.198f), new Vector2(0.318f, 0.076f), new Vector2(0.459f, 0.009f), new Vector2(0.623f, 0.006f), new Vector2(0.751f, 0.064f), new Vector2(0.857f, 0.169f) }, new Vector3[] { new Vector2(0.062f, 0.407f), new Vector2(0.563f, 0.408f) }, new Vector3[] { new Vector2(0.062f, 0.522f), new Vector2(0.597f, 0.522f) }, new Vector3[] { new Vector2(0.823f, 0.669f), new Vector2(0.823f, 0.888f) } }; } return char_euro; } + Vector3[][] Char_hashtag() { if (char_hashtag == null) { char_hashtag = new Vector3[][] { new Vector3[] { new Vector2(0.23f, 0.604f), new Vector2(0.804f, 0.603f) }, new Vector3[] { new Vector2(0.232f, 0.348f), new Vector2(0.805f, 0.347f) }, new Vector3[] { new Vector2(0.315f, -0.069f), new Vector2(0.449f, 1.024f) }, new Vector3[] { new Vector2(0.59f, -0.066f), new Vector2(0.715f, 1.025f) } }; } return char_hashtag; } + Vector3[][] Char_exclamationMark() { if (char_exclamationMark == null) { char_exclamationMark = new Vector3[][] { new Vector3[] { new Vector2(0.522f, -0.009f), new Vector2(0.564f, 0.006f), new Vector2(0.583f, 0.047f), new Vector2(0.566f, 0.091f), new Vector2(0.531f, 0.101f), new Vector2(0.489f, 0.086f), new Vector2(0.465f, 0.046f), new Vector2(0.482f, 0.006f), new Vector2(0.522f, -0.009f) }, new Vector3[] { new Vector2(0.522f, 0.353f), new Vector2(0.523f, 0.941f) } }; } return char_exclamationMark; } + Vector3[][] Char_questionMark() { if (char_questionMark == null) { char_questionMark = new Vector3[][] { new Vector3[] { new Vector2(0.5399f, -0.009f), new Vector2(0.5924f, 0.0039f), new Vector2(0.6202f, 0.0459f), new Vector2(0.5862f, 0.0862f), new Vector2(0.54f, 0.101f), new Vector2(0.4869f, 0.0897f), new Vector2(0.4549f, 0.0508f), new Vector2(0.4862f, 0.0044f), new Vector2(0.5399f, -0.009f) }, new Vector3[] { new Vector2(0.525f, 0.328f), new Vector2(0.527f, 0.417f), new Vector2(0.672f, 0.495f), new Vector2(0.778f, 0.602f), new Vector2(0.779f, 0.745f), new Vector2(0.686f, 0.855f), new Vector2(0.527f, 0.908f), new Vector2(0.27f, 0.839f), new Vector2(0.271f, 0.754f) } }; } return char_questionMark; } + Vector3[][] Char_quote() { if (char_quote == null) { char_quote = new Vector3[][] { new Vector3[] { new Vector2(0.497f, 0.969f), new Vector2(0.497f, 0.534f) } }; } return char_quote; } + Vector3[][] Char_doublequote() { if (char_doublequote == null) { char_doublequote = new Vector3[][] { new Vector3[] { new Vector2(0.331f, 0.962f), new Vector2(0.331f, 0.576f) }, new Vector3[] { new Vector2(0.653f, 0.576f), new Vector2(0.653f, 0.958f) } }; } return char_doublequote; } + Vector3[][] Char_plus() { if (char_plus == null) { char_plus = new Vector3[][] { new Vector3[] { new Vector2(0.524f, 0.837f), new Vector2(0.524f, 0.101f) }, new Vector3[] { new Vector2(0.175f, 0.465f), new Vector2(0.856f, 0.465f) } }; } return char_plus; } + Vector3[][] Char_minus() { if (char_minus == null) { char_minus = new Vector3[][] { new Vector3[] { new Vector2(0.199f, 0.452f), new Vector2(0.821f, 0.452f) } }; } return char_minus; } + Vector3[][] Char_comma() { if (char_comma == null) { char_comma = new Vector3[][] { new Vector3[] { new Vector2(0.465f, 0.213f), new Vector2(0.298f, -0.201f) } }; } return char_comma; } + Vector3[][] Char_asterisk() { if (char_asterisk == null) { char_asterisk = new Vector3[][] { new Vector3[] { new Vector2(0.211f, 0.755f), new Vector2(0.499f, 0.675f), new Vector2(0.668f, 0.43f) }, new Vector3[] { new Vector2(0.323f, 0.434f), new Vector2(0.499f, 0.675f), new Vector2(0.776f, 0.75f) }, new Vector3[] { new Vector2(0.499f, 0.948f), new Vector2(0.499f, 0.675f) } }; } return char_asterisk; } + Vector3[][] Char_underscore() { if (char_underscore == null) { char_underscore = new Vector3[][] { new Vector3[] { new Vector2(0.094f, 0.018f), new Vector2(0.932f, 0.018f) } }; } return char_underscore; } + Vector3[][] Char_period() { if (char_period == null) { char_period = new Vector3[][] { new Vector3[] { new Vector2(0.493f, -0.009f), new Vector2(0.548f, 0.015f), new Vector2(0.5733f, 0.073f), new Vector2(0.546f, 0.116f), new Vector2(0.4931f, 0.143f), new Vector2(0.439f, 0.121f), new Vector2(0.408f, 0.074f), new Vector2(0.438f, 0.014f), new Vector2(0.493f, -0.009f) } }; } return char_period; } + Vector3[][] Char_forwardslash() { if (char_forwardslash == null) { char_forwardslash = new Vector3[][] { new Vector3[] { new Vector2(0.812f, 1.052f), new Vector2(0.238f, -0.118f) } }; } return char_forwardslash; } + Vector3[][] Char_backwardslash() { if (char_backwardslash == null) { char_backwardslash = new Vector3[][] { new Vector3[] { new Vector2(0.233f, 1.052f), new Vector2(0.806f, -0.118f) } }; } return char_backwardslash; } + Vector3[][] Char_colon() { if (char_colon == null) { char_colon = new Vector3[][] { new Vector3[] { new Vector2(0.493f, -0.009f), new Vector2(0.548f, 0.015f), new Vector2(0.5733f, 0.073f), new Vector2(0.546f, 0.116f), new Vector2(0.4931f, 0.143f), new Vector2(0.439f, 0.121f), new Vector2(0.408f, 0.074f), new Vector2(0.438f, 0.014f), new Vector2(0.493f, -0.009f) }, new Vector3[] { new Vector2(0.483f, 0.499f), new Vector2(0.542f, 0.515f), new Vector2(0.574f, 0.573f), new Vector2(0.55f, 0.636f), new Vector2(0.491f, 0.658f), new Vector2(0.427f, 0.63f), new Vector2(0.404f, 0.579f), new Vector2(0.434f, 0.518f), new Vector2(0.483f, 0.499f) } }; } return char_colon; } + Vector3[][] Char_semicolon() { if (char_semicolon == null) { char_semicolon = new Vector3[][] { new Vector3[] { new Vector2(0.517f, 0.5f), new Vector2(0.572f, 0.524f), new Vector2(0.5973001f, 0.582f), new Vector2(0.5700001f, 0.625f), new Vector2(0.5171f, 0.652f), new Vector2(0.463f, 0.63f), new Vector2(0.432f, 0.583f), new Vector2(0.462f, 0.523f), new Vector2(0.517f, 0.5f) }, new Vector3[] { new Vector2(0.483f, 0.207f), new Vector2(0.322f, -0.132f) } }; } return char_semicolon; } + Vector3[][] Char_lessthan() { if (char_lessthan == null) { char_lessthan = new Vector3[][] { new Vector3[] { new Vector2(0.842f, 0.827f), new Vector2(0.161f, 0.444f), new Vector2(0.825f, 0.06f) } }; } return char_lessthan; } + Vector3[][] Char_equals() { if (char_equals == null) { char_equals = new Vector3[][] { new Vector3[] { new Vector2(0.158f, 0.579f), new Vector2(0.849f, 0.579f) }, new Vector3[] { new Vector2(0.159f, 0.322f), new Vector2(0.848f, 0.322f) } }; } return char_equals; } + Vector3[][] Char_greaterthan() { if (char_greaterthan == null) { char_greaterthan = new Vector3[][] { new Vector3[] { new Vector2(0.197f, 0.827f), new Vector2(0.866f, 0.444f), new Vector2(0.181f, 0.06f) } }; } return char_greaterthan; } + Vector3[][] Char_percent() { if (char_percent == null) { char_percent = new Vector3[][] { new Vector3[] { new Vector2(0.357f, 0.594f), new Vector2(0.483f, 0.649f), new Vector2(0.54f, 0.777f), new Vector2(0.485f, 0.915f), new Vector2(0.35f, 0.9589999f), new Vector2(0.203f, 0.896f), new Vector2(0.1609999f, 0.786f), new Vector2(0.218f, 0.646f), new Vector2(0.357f, 0.594f) }, new Vector3[] { new Vector2(0.67f, -0.008f), new Vector2(0.794f, 0.05f), new Vector2(0.85f, 0.181f), new Vector2(0.786f, 0.307f), new Vector2(0.66f, 0.363f), new Vector2(0.525f, 0.301f), new Vector2(0.475f, 0.175f), new Vector2(0.531f, 0.046f), new Vector2(0.67f, -0.008f) }, new Vector3[] { new Vector2(0.171f, 0.238f), new Vector2(0.845f, 0.726f) } }; } return char_percent; } + Vector3[][] Char_ampersand() { if (char_ampersand == null) { char_ampersand = new Vector3[][] { new Vector3[] { new Vector2(0.682f, 0.811f), new Vector2(0.632f, 0.78f), new Vector2(0.554f, 0.813f), new Vector2(0.47f, 0.811f), new Vector2(0.388f, 0.76f), new Vector2(0.344f, 0.684f), new Vector2(0.347f, 0.619f), new Vector2(0.724f, 0.031f), new Vector2(0.809f, 0.032f) }, new Vector3[] { new Vector2(0.439f, 0.44f), new Vector2(0.303f, 0.368f), new Vector2(0.247f, 0.222f), new Vector2(0.301f, 0.08f), new Vector2(0.454f, 0.005f), new Vector2(0.588f, 0.051f), new Vector2(0.681f, 0.189f), new Vector2(0.733f, 0.372f), new Vector2(0.791f, 0.372f) } }; } return char_ampersand; } + Vector3[][] Char_openbracket() { if (char_openbracket == null) { char_openbracket = new Vector3[][] { new Vector3[] { new Vector2(0.695f, 0.954f), new Vector2(0.637f, 0.848f), new Vector2(0.588f, 0.736f), new Vector2(0.558f, 0.623f), new Vector2(0.538f, 0.527f), new Vector2(0.528f, 0.429f), new Vector2(0.525f, 0.318f), new Vector2(0.54f, 0.225f), new Vector2(0.568f, 0.124f), new Vector2(0.605f, 0.012f), new Vector2(0.646f, -0.094f), new Vector2(0.693f, -0.189f) } }; } return char_openbracket; } + Vector3[][] Char_closebracket() { if (char_closebracket == null) { char_closebracket = new Vector3[][] { new Vector3[] { new Vector2(0.34f, 0.954f), new Vector2(0.392f, 0.848f), new Vector2(0.439f, 0.736f), new Vector2(0.479f, 0.623f), new Vector2(0.495f, 0.527f), new Vector2(0.501f, 0.429f), new Vector2(0.501f, 0.318f), new Vector2(0.489f, 0.225f), new Vector2(0.472f, 0.124f), new Vector2(0.431f, 0.012f), new Vector2(0.385f, -0.094f), new Vector2(0.334f, -0.189f) } }; } return char_closebracket; } + Vector3[][] Char_opensquarebracket() { if (char_opensquarebracket == null) { char_opensquarebracket = new Vector3[][] { new Vector3[] { new Vector2(0.719f, 0.946f), new Vector2(0.506f, 0.946f), new Vector2(0.505f, -0.182f), new Vector2(0.704f, -0.183f) } }; } return char_opensquarebracket; } + Vector3[][] Char_closesquarebracket() { if (char_closesquarebracket == null) { char_closesquarebracket = new Vector3[][] { new Vector3[] { new Vector2(0.303f, 0.946f), new Vector2(0.506f, 0.946f), new Vector2(0.505f, -0.182f), new Vector2(0.314f, -0.183f) } }; } return char_closesquarebracket; } + Vector3[][] Char_leftbrace() { if (char_leftbrace == null) { char_leftbrace = new Vector3[][] { new Vector3[] { new Vector2(0.672f, 0.954f), new Vector2(0.61f, 0.948f), new Vector2(0.567f, 0.924f), new Vector2(0.536f, 0.881f), new Vector2(0.522f, 0.829f), new Vector2(0.523f, 0.505f), new Vector2(0.501f, 0.452f), new Vector2(0.455f, 0.413f), new Vector2(0.38f, 0.396f), new Vector2(0.455f, 0.379f), new Vector2(0.497f, 0.348f), new Vector2(0.522f, 0.295f), new Vector2(0.522f, -0.029f), new Vector2(0.546f, -0.101f), new Vector2(0.6f, -0.149f), new Vector2(0.666f, -0.164f) } }; } return char_leftbrace; } + Vector3[][] Char_rightbrace() { if (char_rightbrace == null) { char_rightbrace = new Vector3[][] { new Vector3[] { new Vector2(0.356f, 0.954f), new Vector2(0.408f, 0.948f), new Vector2(0.447f, 0.924f), new Vector2(0.482f, 0.881f), new Vector2(0.5f, 0.829f), new Vector2(0.501f, 0.505f), new Vector2(0.531f, 0.443f), new Vector2(0.58f, 0.413f), new Vector2(0.641f, 0.396f), new Vector2(0.58f, 0.379f), new Vector2(0.529f, 0.348f), new Vector2(0.5f, 0.295f), new Vector2(0.5f, -0.029f), new Vector2(0.475f, -0.101f), new Vector2(0.423f, -0.149f), new Vector2(0.36f, -0.164f) } }; } return char_rightbrace; } + Vector3[][] Char_verticalbar() { if (char_verticalbar == null) { char_verticalbar = new Vector3[][] { new Vector3[] { new Vector2(0.506f, 0.953f), new Vector2(0.505f, -0.196f) } }; } return char_verticalbar; } + Vector3[][] Char_at() { if (char_at == null) { char_at = new Vector3[][] { new Vector3[] { new Vector2(0.652f, 0.622f), new Vector2(0.619f, 0.236f), new Vector2(0.653f, 0.153f), new Vector2(0.705f, 0.145f), new Vector2(0.776f, 0.278f), new Vector2(0.794f, 0.644f), new Vector2(0.743f, 0.895f), new Vector2(0.586f, 0.995f), new Vector2(0.44f, 0.996f), new Vector2(0.249f, 0.847f), new Vector2(0.166f, 0.603f), new Vector2(0.165f, 0.274f), new Vector2(0.256f, 0.037f), new Vector2(0.428f, -0.087f), new Vector2(0.594f, -0.09f), new Vector2(0.797f, -0.049f) }, new Vector3[] { new Vector2(0.64f, 0.55f), new Vector2(0.564f, 0.615f), new Vector2(0.504f, 0.634f), new Vector2(0.425f, 0.593f), new Vector2(0.387f, 0.518f), new Vector2(0.388f, 0.333f), new Vector2(0.46f, 0.242f), new Vector2(0.534f, 0.244f), new Vector2(0.626f, 0.321f) } }; } return char_at; } + Vector3[][] Char_caret() { if (char_caret == null) { char_caret = new Vector3[][] { new Vector3[] { new Vector2(0.211f, 0.605f), new Vector2(0.501f, 0.942f), new Vector2(0.788f, 0.603f) } }; } return char_caret; } + Vector3[][] Char_tilde() { if (char_tilde == null) { char_tilde = new Vector3[][] { new Vector3[] { new Vector2(0.186f, 0.407f), new Vector2(0.237f, 0.475f), new Vector2(0.296f, 0.523f), new Vector2(0.357f, 0.542f), new Vector2(0.421f, 0.524f), new Vector2(0.471f, 0.486f), new Vector2(0.547f, 0.421f), new Vector2(0.594f, 0.388f), new Vector2(0.649f, 0.372f), new Vector2(0.712f, 0.383f), new Vector2(0.768f, 0.426f), new Vector2(0.824f, 0.479f) } }; } return char_tilde; } + Vector3[][] Char_degree() { if (char_degree == null) { char_degree = new Vector3[][] { new Vector3[] { new Vector2(0.531f, 0.767f), new Vector2(0.657f, 0.822f), new Vector2(0.714f, 0.95f), new Vector2(0.659f, 1.088f), new Vector2(0.524f, 1.132f), new Vector2(0.377f, 1.069f), new Vector2(0.3349999f, 0.959f), new Vector2(0.392f, 0.819f), new Vector2(0.531f, 0.767f) } }; } return char_degree; } + Vector3[][] Char_section() { if (char_section == null) { char_section = new Vector3[][] { new Vector3[] { new Vector2(0.807f, 0.835f), new Vector2(0.707f, 0.95f), new Vector2(0.441f, 0.948f), new Vector2(0.357f, 0.89f), new Vector2(0.326f, 0.801f), new Vector2(0.366f, 0.704f), new Vector2(0.723f, 0.5f), new Vector2(0.749f, 0.327f), new Vector2(0.648f, 0.187f) }, new Vector3[] { new Vector2(0.256f, 0.057f), new Vector2(0.346f, -0.071f), new Vector2(0.58f, -0.072f), new Vector2(0.69f, -0.023f), new Vector2(0.733f, 0.076f), new Vector2(0.671f, 0.167f), new Vector2(0.322f, 0.356f), new Vector2(0.304f, 0.53f), new Vector2(0.398f, 0.677f) } }; } return char_section; } + + + Vector3[][] Icon_profileFoto() { if (icon_profileFoto == null) { icon_profileFoto = new Vector3[][] { new Vector3[] { new Vector2(0.143f, 0.223f), new Vector2(0.213f, 0.313f), new Vector2(0.286f, 0.385f), new Vector2(0.405f, 0.447f) }, new Vector3[] { new Vector2(0.85f, 0.229f), new Vector2(0.796f, 0.314f), new Vector2(0.712f, 0.385f), new Vector2(0.586f, 0.448f) }, new Vector3[] { new Vector2(0.4985f, 0.05678758f), new Vector2(0.31975f, 0.09226254f), new Vector2(0.1865f, 0.177725f), new Vector2(0.09062499f, 0.3115626f), new Vector2(0.04674998f, 0.497f), new Vector2(0.07925001f, 0.6711501f), new Vector2(0.191375f, 0.8324f), new Vector2(0.32625f, 0.9178625f), new Vector2(0.505f, 0.9485f), new Vector2(0.6983749f, 0.9049625f), new Vector2(0.83325f, 0.8017625f), new Vector2(0.919375f, 0.6630876f), new Vector2(0.947f, 0.497f), new Vector2(0.9063749f, 0.3131751f), new Vector2(0.815375f, 0.1825626f), new Vector2(0.674f, 0.09387508f), new Vector2(0.4985f, 0.05678758f) }, new Vector3[] { new Vector2(0.492292f, 0.432179f), new Vector2(0.417822f, 0.447073f), new Vector2(0.362308f, 0.482954f), new Vector2(0.322365f, 0.539145f), new Vector2(0.304086f, 0.617f), new Vector2(0.317626f, 0.690116f), new Vector2(0.364339f, 0.757816f), new Vector2(0.42053f, 0.793697f), new Vector2(0.495f, 0.80656f), new Vector2(0.575563f, 0.788281f), new Vector2(0.631754f, 0.744953f), new Vector2(0.667635f, 0.686731f), new Vector2(0.679144f, 0.617f), new Vector2(0.662219f, 0.539822f), new Vector2(0.624307f, 0.484985f), new Vector2(0.565408f, 0.44775f), new Vector2(0.492292f, 0.432179f) } }; } return icon_profileFoto; } + Vector3[][] Icon_imageLandscape() { if (icon_imageLandscape == null) { icon_imageLandscape = new Vector3[][] { new Vector3[] { new Vector2(0.0373444f, 0.813278f), new Vector2(0.06224066f, 0.8381743f), new Vector2(0.9294606f, 0.8381743f), new Vector2(0.9522821f, 0.8153527f), new Vector2(0.9522821f, 0.1659751f), new Vector2(0.9190871f, 0.1369295f), new Vector2(0.06016598f, 0.1369295f), new Vector2(0.03319502f, 0.1680498f), new Vector2(0.03319502f, 0.8153527f) }, new Vector3[] { new Vector2(0.2738589f, 0.1473029f), new Vector2(0.4979253f, 0.373444f), new Vector2(0.5788382f, 0.4253112f), new Vector2(0.6721992f, 0.4626556f), new Vector2(0.7697095f, 0.466805f), new Vector2(0.8651452f, 0.4460581f), new Vector2(0.9502075f, 0.3692946f) }, new Vector3[] { new Vector2(0.03319502f, 0.3443983f), new Vector2(0.1161826f, 0.4024896f), new Vector2(0.1742739f, 0.4087137f), new Vector2(0.2489627f, 0.3672199f), new Vector2(0.3319502f, 0.2904564f) }, new Vector3[] { new Vector2(0.246888f, 0.4232365f), new Vector2(0.3153527f, 0.4834025f), new Vector2(0.3817427f, 0.5145229f), new Vector2(0.4522822f, 0.5103735f), new Vector2(0.5020747f, 0.4771784f), new Vector2(0.5394191f, 0.43361f) }, new Vector3[] { new Vector2(0.2945f, 0.6286171f), new Vector2(0.2474835f, 0.6481118f), new Vector2(0.2289062f, 0.691f), new Vector2(0.2467954f, 0.7359524f), new Vector2(0.2933533f, 0.7559057f), new Vector2(0.3383056f, 0.7380165f), new Vector2(0.3564242f, 0.6907706f), new Vector2(0.3380763f, 0.6460476f), new Vector2(0.2945f, 0.6286171f) }, new Vector3[] { new Vector2(0.9375352f, 0.8609958f), new Vector2(0.973029f, 0.8236514f), new Vector2(0.973029f, 0.1576764f), new Vector2(0.9211618f, 0.1161079f), new Vector2(0.04979253f, 0.1161079f), new Vector2(0.01244813f, 0.1639004f), new Vector2(0.01244813f, 0.8195021f), new Vector2(0.06016598f, 0.8569958f), new Vector2(0.9356846f, 0.8569958f) } }; } return icon_imageLandscape; } + Vector3[][] Icon_homeHouse() { if (icon_homeHouse == null) { icon_homeHouse = new Vector3[][] { new Vector3[] { new Vector2(0.5106209f, 0.9084967f), new Vector2(0.03349673f, 0.4493464f), new Vector2(0.1789216f, 0.4493464f), new Vector2(0.1789216f, 0.08333334f), new Vector2(0.4256536f, 0.08333334f), new Vector2(0.4256536f, 0.3039216f), new Vector2(0.5825163f, 0.3039216f), new Vector2(0.5825163f, 0.08333334f), new Vector2(0.8276144f, 0.08333334f), new Vector2(0.8276144f, 0.4509804f), new Vector2(0.9714052f, 0.4509804f), new Vector2(0.5106209f, 0.9084967f) } }; } return icon_homeHouse; } + Vector3[][] Icon_dataDisc() { if (icon_dataDisc == null) { icon_dataDisc = new Vector3[][] { new Vector3[] { new Vector2(0.4256536f, 0.245098f), new Vector2(0.5923203f, 0.245098f) }, new Vector3[] { new Vector2(0.4256536f, 0.1748366f), new Vector2(0.5906863f, 0.1748366f) }, new Vector3[] { new Vector2(0.4256536f, 0.1013072f), new Vector2(0.5890523f, 0.1013072f) }, new Vector3[] { new Vector2(0.3472222f, 0.0506536f), new Vector2(0.3472222f, 0.2973856f), new Vector2(0.6674837f, 0.2973856f), new Vector2(0.6674837f, 0.0506536f) }, new Vector3[] { new Vector2(0.7933006f, 0.5375817f), new Vector2(0.7933006f, 0.05228758f), new Vector2(0.2197712f, 0.05228758f), new Vector2(0.2197712f, 0.6715686f), new Vector2(0.6740196f, 0.6715686f), new Vector2(0.7933006f, 0.5375817f) } }; } return icon_dataDisc; } + Vector3[][] Icon_saveData() { if (icon_saveData == null) { icon_saveData = new Vector3[][] { new Vector3[] { new Vector2(0.4256536f, 0.245098f), new Vector2(0.5923203f, 0.245098f) }, new Vector3[] { new Vector2(0.4256536f, 0.1748366f), new Vector2(0.5906863f, 0.1748366f) }, new Vector3[] { new Vector2(0.4256536f, 0.1013072f), new Vector2(0.5890523f, 0.1013072f) }, new Vector3[] { new Vector2(0.3472222f, 0.0506536f), new Vector2(0.3472222f, 0.2973856f), new Vector2(0.6674837f, 0.2973856f), new Vector2(0.6674837f, 0.0506536f) }, new Vector3[] { new Vector2(0.7933006f, 0.5375817f), new Vector2(0.7933006f, 0.05228758f), new Vector2(0.2197712f, 0.05228758f), new Vector2(0.2197712f, 0.6715686f), new Vector2(0.4125817f, 0.6715686f) }, new Vector3[] { new Vector2(0.5972222f, 0.6699346f), new Vector2(0.6707516f, 0.6699346f), new Vector2(0.7933006f, 0.5359477f) }, new Vector3[] { new Vector2(0.499183f, 0.9787582f), new Vector2(0.499183f, 0.3676471f) }, new Vector3[] { new Vector2(0.3325163f, 0.5473856f), new Vector2(0.499183f, 0.3643791f), new Vector2(0.6642157f, 0.5424837f) } }; } return icon_saveData; } + Vector3[][] Icon_loadData() { if (icon_loadData == null) { icon_loadData = new Vector3[][] { new Vector3[] { new Vector2(0.4256536f, 0.245098f), new Vector2(0.5923203f, 0.245098f) }, new Vector3[] { new Vector2(0.4256536f, 0.1748366f), new Vector2(0.5906863f, 0.1748366f) }, new Vector3[] { new Vector2(0.4256536f, 0.1013072f), new Vector2(0.5890523f, 0.1013072f) }, new Vector3[] { new Vector2(0.3472222f, 0.0506536f), new Vector2(0.3472222f, 0.2973856f), new Vector2(0.6674837f, 0.2973856f), new Vector2(0.6674837f, 0.0506536f) }, new Vector3[] { new Vector2(0.7933006f, 0.5375817f), new Vector2(0.7933006f, 0.05228758f), new Vector2(0.2197712f, 0.05228758f), new Vector2(0.2197712f, 0.6715686f), new Vector2(0.4027778f, 0.6715686f) }, new Vector3[] { new Vector2(0.6053922f, 0.6699346f), new Vector2(0.6740196f, 0.6699346f), new Vector2(0.7949346f, 0.5359477f) }, new Vector3[] { new Vector2(0.5057189f, 0.3692811f), new Vector2(0.5057189f, 0.9558824f) }, new Vector3[] { new Vector2(0.3357843f, 0.7826797f), new Vector2(0.5040849f, 0.9591503f), new Vector2(0.6674837f, 0.7810457f) } }; } return icon_loadData; } + Vector3[][] Icon_speechBubble() { if (icon_speechBubble == null) { icon_speechBubble = new Vector3[][] { new Vector3[] { new Vector2(0.5f, 0.5f), new Vector2(0.7271242f, 0.7647059f), new Vector2(0.6748366f, 0.7745098f), new Vector2(0.6307189f, 0.8055556f), new Vector2(0.5964052f, 0.8431373f), new Vector2(0.5816994f, 0.8954248f), new Vector2(0.5816994f, 1.27451f), new Vector2(0.5947713f, 1.330065f), new Vector2(0.624183f, 1.370915f), new Vector2(0.6683006f, 1.397059f), new Vector2(0.7336601f, 1.408497f), new Vector2(1.285948f, 1.408497f), new Vector2(1.346405f, 1.392157f), new Vector2(1.388889f, 1.356209f), new Vector2(1.416667f, 1.315359f), new Vector2(1.418301f, 1.263072f), new Vector2(1.418301f, 0.8954248f), new Vector2(1.406863f, 0.8398693f), new Vector2(1.377451f, 0.8039216f), new Vector2(1.334967f, 0.7777778f), new Vector2(1.27451f, 0.7630719f), new Vector2(0.995098f, 0.7630719f), new Vector2(0.5f, 0.5f) }, new Vector3[] { new Vector2(0.6846405f, 1.253268f), new Vector2(1.313725f, 1.253268f) }, new Vector3[] { new Vector2(0.6879085f, 1.091503f), new Vector2(1.312092f, 1.091503f) }, new Vector3[] { new Vector2(0.6862745f, 0.9199346f), new Vector2(1.143791f, 0.9199346f) } }; } return icon_speechBubble; } + Vector3[][] Icon_speechBubbleEmpty() { if (icon_speechBubbleEmpty == null) { icon_speechBubbleEmpty = new Vector3[][] { new Vector3[] { new Vector2(0.5f, 0.5f), new Vector2(0.7271242f, 0.7647059f), new Vector2(0.6748366f, 0.7745098f), new Vector2(0.6307189f, 0.8055556f), new Vector2(0.5964052f, 0.8431373f), new Vector2(0.5816994f, 0.8954248f), new Vector2(0.5816994f, 1.27451f), new Vector2(0.5947713f, 1.330065f), new Vector2(0.624183f, 1.370915f), new Vector2(0.6683006f, 1.397059f), new Vector2(0.7336601f, 1.408497f), new Vector2(1.285948f, 1.408497f), new Vector2(1.346405f, 1.392157f), new Vector2(1.388889f, 1.356209f), new Vector2(1.416667f, 1.315359f), new Vector2(1.418301f, 1.263072f), new Vector2(1.418301f, 0.8954248f), new Vector2(1.406863f, 0.8398693f), new Vector2(1.377451f, 0.8039216f), new Vector2(1.334967f, 0.7777778f), new Vector2(1.27451f, 0.7630719f), new Vector2(0.995098f, 0.7630719f), new Vector2(0.5f, 0.5f) } }; } return icon_speechBubbleEmpty; } + Vector3[][] Icon_thumbUp() { if (icon_thumbUp == null) { icon_thumbUp = new Vector3[][] { new Vector3[] { new Vector2(0.2957516f, 0.1143791f), new Vector2(0.2957516f, 0.5130719f), new Vector2(0.3627451f, 0.5359477f), new Vector2(0.4313726f, 0.7107843f), new Vector2(0.4493464f, 0.9509804f), new Vector2(0.5228758f, 0.9460784f), new Vector2(0.5718954f, 0.9150327f), new Vector2(0.5980392f, 0.8594771f), new Vector2(0.6013072f, 0.7973856f), new Vector2(0.5915033f, 0.6486928f), new Vector2(0.8839869f, 0.6486928f), new Vector2(0.9428105f, 0.622549f), new Vector2(0.9346405f, 0.5245098f), new Vector2(0.8578432f, 0.4918301f), new Vector2(0.9232026f, 0.4542484f), new Vector2(0.9117647f, 0.3660131f), new Vector2(0.8137255f, 0.3300654f), new Vector2(0.875817f, 0.2990196f), new Vector2(0.8676471f, 0.1960784f), new Vector2(0.7712418f, 0.1764706f), new Vector2(0.8349673f, 0.1323529f), new Vector2(0.8251634f, 0.05882353f), new Vector2(0.7892157f, 0.03921569f), new Vector2(0.4918301f, 0.03921569f), new Vector2(0.3611111f, 0.1078431f), new Vector2(0.2957516f, 0.1143791f) }, new Vector3[] { new Vector2(0.03921569f, 0.5686275f), new Vector2(0.2647059f, 0.5686275f), new Vector2(0.2647059f, 0.04575163f), new Vector2(0.03921569f, 0.04575163f), new Vector2(0.03921569f, 0.5669935f) }, new Vector3[] { new Vector2(0.4444444f, 0.8382353f), new Vector2(0.4836601f, 0.8611111f), new Vector2(0.4918301f, 0.9444444f) } }; } return icon_thumbUp; } + Vector3[][] Icon_thumbDown() { if (icon_thumbDown == null) { icon_thumbDown = new Vector3[][] { new Vector3[] { new Vector2(0.7042483f, 0.885621f), new Vector2(0.7042484f, 0.4869281f), new Vector2(0.6372549f, 0.4640523f), new Vector2(0.5686275f, 0.2892157f), new Vector2(0.5506536f, 0.04901963f), new Vector2(0.4771242f, 0.05392158f), new Vector2(0.4281046f, 0.08496732f), new Vector2(0.4019608f, 0.1405229f), new Vector2(0.3986928f, 0.2026144f), new Vector2(0.4084967f, 0.3513072f), new Vector2(0.1160131f, 0.3513072f), new Vector2(0.05718952f, 0.377451f), new Vector2(0.06535947f, 0.4754902f), new Vector2(0.1421568f, 0.5081699f), new Vector2(0.07679737f, 0.5457516f), new Vector2(0.08823532f, 0.6339869f), new Vector2(0.1862745f, 0.6699346f), new Vector2(0.124183f, 0.7009804f), new Vector2(0.1323529f, 0.8039216f), new Vector2(0.2287581f, 0.8235294f), new Vector2(0.1650327f, 0.8676471f), new Vector2(0.1748365f, 0.9411764f), new Vector2(0.2107843f, 0.9607843f), new Vector2(0.5081699f, 0.9607843f), new Vector2(0.6388888f, 0.8921568f), new Vector2(0.7042483f, 0.885621f) }, new Vector3[] { new Vector2(0.9607843f, 0.4313726f), new Vector2(0.7352941f, 0.4313726f), new Vector2(0.735294f, 0.9542484f), new Vector2(0.9607843f, 0.9542484f), new Vector2(0.9607843f, 0.4330066f) }, new Vector3[] { new Vector2(0.5555556f, 0.1617647f), new Vector2(0.5163399f, 0.1388889f), new Vector2(0.50817f, 0.05555558f) } }; } return icon_thumbDown; } + Vector3[][] Icon_lightBulbOn() { if (icon_lightBulbOn == null) { icon_lightBulbOn = new Vector3[][] { new Vector3[] { new Vector2(0.3954248f, 0.2679739f), new Vector2(0.3905229f, 0.3251634f), new Vector2(0.3643791f, 0.3954248f), new Vector2(0.3251634f, 0.4689542f), new Vector2(0.3006536f, 0.5310457f), new Vector2(0.2957516f, 0.5931373f), new Vector2(0.3153595f, 0.6601307f), new Vector2(0.3529412f, 0.7189543f), new Vector2(0.4101307f, 0.7549019f), new Vector2(0.4738562f, 0.7745098f), new Vector2(0.5408497f, 0.7712418f), new Vector2(0.6045752f, 0.746732f), new Vector2(0.6503268f, 0.6993464f), new Vector2(0.6862745f, 0.6421568f), new Vector2(0.6977124f, 0.5767974f), new Vector2(0.6879085f, 0.5081699f), new Vector2(0.6617647f, 0.4558823f), new Vector2(0.6307189f, 0.3888889f), new Vector2(0.6062092f, 0.3284314f), new Vector2(0.5996732f, 0.2679739f) }, new Vector3[] { new Vector2(0.3823529f, 0.2009804f), new Vector2(0.3823529f, 0.245098f), new Vector2(0.624183f, 0.245098f), new Vector2(0.624183f, 0.1977124f), new Vector2(0.3807189f, 0.1977124f) }, new Vector3[] { new Vector2(0.3839869f, 0.1699346f), new Vector2(0.624183f, 0.1699346f), new Vector2(0.624183f, 0.124183f), new Vector2(0.3839869f, 0.124183f), new Vector2(0.3839869f, 0.1683007f) }, new Vector3[] { new Vector2(0.4297386f, 0.0882353f), new Vector2(0.5653595f, 0.0882353f), new Vector2(0.5359477f, 0.04084967f), new Vector2(0.4575163f, 0.04084967f), new Vector2(0.4297386f, 0.0882353f) }, new Vector3[] { new Vector2(0.4117647f, 0.5114379f), new Vector2(0.4362745f, 0.6356209f), new Vector2(0.4722222f, 0.503268f), new Vector2(0.5f, 0.6356209f), new Vector2(0.5310457f, 0.503268f), new Vector2(0.5620915f, 0.6339869f), new Vector2(0.5882353f, 0.5049019f) }, new Vector3[] { new Vector2(0.7761438f, 0.495098f), new Vector2(0.9150327f, 0.4509804f) }, new Vector3[] { new Vector2(0.7696078f, 0.6519608f), new Vector2(0.9084967f, 0.7009804f) }, new Vector3[] { new Vector2(0.6666667f, 0.7892157f), new Vector2(0.7614379f, 0.9052287f) }, new Vector3[] { new Vector2(0.501634f, 0.8480392f), new Vector2(0.501634f, 0.9869281f) }, new Vector3[] { new Vector2(0.3284314f, 0.7908497f), new Vector2(0.2369281f, 0.9003268f) }, new Vector3[] { new Vector2(0.2287582f, 0.6552287f), new Vector2(0.0882353f, 0.6960784f) }, new Vector3[] { new Vector2(0.2254902f, 0.4934641f), new Vector2(0.08006536f, 0.4493464f) } }; } return icon_lightBulbOn; } + Vector3[][] Icon_lightBulbOff() { if (icon_lightBulbOff == null) { icon_lightBulbOff = new Vector3[][] { new Vector3[] { new Vector2(0.3954248f, 0.2679739f), new Vector2(0.3905229f, 0.3251634f), new Vector2(0.3643791f, 0.3954248f), new Vector2(0.3251634f, 0.4689542f), new Vector2(0.3006536f, 0.5310457f), new Vector2(0.2957516f, 0.5931373f), new Vector2(0.3153595f, 0.6601307f), new Vector2(0.3529412f, 0.7189543f), new Vector2(0.4101307f, 0.7549019f), new Vector2(0.4738562f, 0.7745098f), new Vector2(0.5408497f, 0.7712418f), new Vector2(0.6045752f, 0.746732f), new Vector2(0.6503268f, 0.6993464f), new Vector2(0.6862745f, 0.6421568f), new Vector2(0.6977124f, 0.5767974f), new Vector2(0.6879085f, 0.5081699f), new Vector2(0.6617647f, 0.4558823f), new Vector2(0.6307189f, 0.3888889f), new Vector2(0.6062092f, 0.3284314f), new Vector2(0.5996732f, 0.2679739f) }, new Vector3[] { new Vector2(0.3823529f, 0.2009804f), new Vector2(0.3823529f, 0.245098f), new Vector2(0.624183f, 0.245098f), new Vector2(0.624183f, 0.1977124f), new Vector2(0.3807189f, 0.1977124f) }, new Vector3[] { new Vector2(0.3839869f, 0.1699346f), new Vector2(0.624183f, 0.1699346f), new Vector2(0.624183f, 0.124183f), new Vector2(0.3839869f, 0.124183f), new Vector2(0.3839869f, 0.1683007f) }, new Vector3[] { new Vector2(0.4297386f, 0.0882353f), new Vector2(0.5653595f, 0.0882353f), new Vector2(0.5359477f, 0.04084967f), new Vector2(0.4575163f, 0.04084967f), new Vector2(0.4297386f, 0.0882353f) } }; } return icon_lightBulbOff; } + Vector3[][] Icon_videoCamera() { if (icon_videoCamera == null) { icon_videoCamera = new Vector3[][] { new Vector3[] { new Vector2(0.1830065f, 0.5996732f), new Vector2(0.1339869f, 0.6470588f), new Vector2(0.1127451f, 0.7042484f), new Vector2(0.1176471f, 0.7777778f), new Vector2(0.1584967f, 0.8366013f), new Vector2(0.2140523f, 0.874183f), new Vector2(0.3055556f, 0.8709151f), new Vector2(0.3496732f, 0.8480392f), new Vector2(0.3807189f, 0.8088235f), new Vector2(0.4150327f, 0.8496732f), new Vector2(0.4820261f, 0.877451f), new Vector2(0.5571895f, 0.8643791f), new Vector2(0.6209151f, 0.8169935f), new Vector2(0.6519608f, 0.7418301f), new Vector2(0.6454248f, 0.6764706f), new Vector2(0.6176471f, 0.6339869f), new Vector2(0.5702614f, 0.5947713f) }, new Vector3[] { new Vector2(0.6748366f, 0.5964052f), new Vector2(0.08006536f, 0.5964052f), new Vector2(0.08006536f, 0.1666667f), new Vector2(0.6732026f, 0.1666667f), new Vector2(0.6748366f, 0.5964052f) }, new Vector3[] { new Vector2(0.6748366f, 0.4787582f), new Vector2(0.9281046f, 0.5931373f), new Vector2(0.9281046f, 0.1633987f), new Vector2(0.6732026f, 0.2663399f) } }; } return icon_videoCamera; } + Vector3[][] Icon_camera() { if (icon_camera == null) { icon_camera = new Vector3[][] { new Vector3[] { new Vector2(0.5015236f, 0.2749854f), new Vector2(0.4334225f, 0.2886056f), new Vector2(0.3826562f, 0.321418f), new Vector2(0.3461292f, 0.3728034f), new Vector2(0.3294135f, 0.444f), new Vector2(0.3417955f, 0.5108629f), new Vector2(0.3845135f, 0.572773f), new Vector2(0.4358989f, 0.6055854f), new Vector2(0.504f, 0.6173483f), new Vector2(0.577673f, 0.6006326f), new Vector2(0.6290585f, 0.5610101f), new Vector2(0.6618708f, 0.5077674f), new Vector2(0.6723955f, 0.444f), new Vector2(0.656918f, 0.3734225f), new Vector2(0.6222483f, 0.3232753f), new Vector2(0.5683866f, 0.2892247f), new Vector2(0.5015236f, 0.2749854f) }, new Vector3[] { new Vector2(0.748366f, 0.7205882f), new Vector2(0.8905229f, 0.7205882f), new Vector2(0.9330065f, 0.6813725f), new Vector2(0.9330065f, 0.1715686f), new Vector2(0.8921568f, 0.130719f), new Vector2(0.1045752f, 0.130719f), new Vector2(0.06045752f, 0.1781046f), new Vector2(0.06045752f, 0.6797386f), new Vector2(0.1029412f, 0.7189543f), new Vector2(0.253268f, 0.7189543f), new Vector2(0.3366013f, 0.8464052f), new Vector2(0.6732026f, 0.8464052f), new Vector2(0.748366f, 0.7205882f) } }; } return icon_camera; } + Vector3[][] Icon_music() { if (icon_music == null) { icon_music = new Vector3[][] { new Vector3[] { new Vector2(0.8464052f, 0.377451f), new Vector2(0.8006536f, 0.3839869f), new Vector2(0.7254902f, 0.3807189f), new Vector2(0.6470588f, 0.3480392f), new Vector2(0.6094771f, 0.2957516f), new Vector2(0.6045752f, 0.2205882f), new Vector2(0.6650327f, 0.1797386f), new Vector2(0.75f, 0.1666667f), new Vector2(0.8267974f, 0.1879085f), new Vector2(0.8839869f, 0.2173203f), new Vector2(0.9101307f, 0.2630719f), new Vector2(0.9150327f, 0.3284314f), new Vector2(0.9150327f, 0.9313725f), new Vector2(0.3104575f, 0.7859477f), new Vector2(0.3104575f, 0.2777778f), new Vector2(0.2303922f, 0.2761438f), new Vector2(0.1437909f, 0.245098f), new Vector2(0.08496732f, 0.1993464f), new Vector2(0.06535948f, 0.1339869f), new Vector2(0.09640523f, 0.0882353f), new Vector2(0.1781046f, 0.06045752f), new Vector2(0.2712418f, 0.06862745f), new Vector2(0.3513072f, 0.1143791f), new Vector2(0.3807189f, 0.1519608f), new Vector2(0.3888889f, 0.2156863f), new Vector2(0.3888889f, 0.6519608f), new Vector2(0.8447713f, 0.759804f), new Vector2(0.8447713f, 0.375817f) } }; } return icon_music; } + Vector3[][] Icon_audioSpeaker() { if (icon_audioSpeaker == null) { icon_audioSpeaker = new Vector3[][] { new Vector3[] { new Vector2(0.3284314f, 0.6405229f), new Vector2(0.06045752f, 0.6405229f), new Vector2(0.06045752f, 0.3562092f), new Vector2(0.3284314f, 0.3562092f), new Vector2(0.509804f, 0.1846405f), new Vector2(0.509804f, 0.8202614f), new Vector2(0.3284314f, 0.6405229f) }, new Vector3[] { new Vector2(0.5996732f, 0.7173203f), new Vector2(0.6323529f, 0.6388889f), new Vector2(0.6503268f, 0.5506536f), new Vector2(0.6486928f, 0.4444444f), new Vector2(0.625817f, 0.3431373f), new Vector2(0.5898693f, 0.2614379f) }, new Vector3[] { new Vector2(0.7042484f, 0.7843137f), new Vector2(0.7450981f, 0.6846405f), new Vector2(0.7696078f, 0.5686275f), new Vector2(0.7712418f, 0.4493464f), new Vector2(0.7434641f, 0.3218954f), new Vector2(0.6862745f, 0.1977124f) }, new Vector3[] { new Vector2(0.8088235f, 0.8464052f), new Vector2(0.8513072f, 0.753268f), new Vector2(0.8856209f, 0.6519608f), new Vector2(0.8986928f, 0.5490196f), new Vector2(0.8986928f, 0.4330065f), new Vector2(0.8790849f, 0.3284314f), new Vector2(0.8431373f, 0.2254902f), new Vector2(0.7924837f, 0.130719f) } }; } return icon_audioSpeaker; } + Vector3[][] Icon_microphone() { if (icon_microphone == null) { icon_microphone = new Vector3[][] { new Vector3[] { new Vector2(0.3349673f, 0.8169935f), new Vector2(0.3594771f, 0.872549f), new Vector2(0.3970588f, 0.9084967f), new Vector2(0.4477124f, 0.9379085f), new Vector2(0.501634f, 0.9411765f), new Vector2(0.5620915f, 0.9264706f), new Vector2(0.6029412f, 0.8970588f), new Vector2(0.6388889f, 0.8529412f), new Vector2(0.6552287f, 0.7957516f), new Vector2(0.6552287f, 0.4150327f), new Vector2(0.6454248f, 0.3676471f), new Vector2(0.622549f, 0.3300654f), new Vector2(0.5898693f, 0.2957516f), new Vector2(0.5457516f, 0.2712418f), new Vector2(0.495098f, 0.2679739f), new Vector2(0.4330065f, 0.2843137f), new Vector2(0.3807189f, 0.3186274f), new Vector2(0.3496732f, 0.3643791f), new Vector2(0.3333333f, 0.4330065f), new Vector2(0.3349673f, 0.8169935f) }, new Vector3[] { new Vector2(0.2352941f, 0.6029412f), new Vector2(0.2352941f, 0.3905229f), new Vector2(0.254902f, 0.3218954f), new Vector2(0.2990196f, 0.254902f), new Vector2(0.3660131f, 0.1960784f), new Vector2(0.4526144f, 0.1699346f), new Vector2(0.5653595f, 0.1699346f), new Vector2(0.6454248f, 0.2075163f), new Vector2(0.7058824f, 0.2647059f), new Vector2(0.7450981f, 0.3349673f), new Vector2(0.7679738f, 0.4183007f), new Vector2(0.7679738f, 0.6029412f) }, new Vector3[] { new Vector2(0.3316993f, 0.06045752f), new Vector2(0.6715686f, 0.06045752f) }, new Vector3[] { new Vector2(0.5f, 0.0620915f), new Vector2(0.5f, 0.1699346f) } }; } return icon_microphone; } + Vector3[][] Icon_wlan_wifi() { if (icon_wlan_wifi == null) { icon_wlan_wifi = new Vector3[][] { new Vector3[] { new Vector2(0.504f, 0.07238549f), new Vector2(0.4326913f, 0.1019525f), new Vector2(0.4045156f, 0.167f), new Vector2(0.4316477f, 0.2351781f), new Vector2(0.5022607f, 0.2654408f), new Vector2(0.5704389f, 0.2383087f), new Vector2(0.5979188f, 0.1666522f), new Vector2(0.570091f, 0.0988219f), new Vector2(0.504f, 0.07238549f) }, new Vector3[] { new Vector2(0.2785124f, 0.3636364f), new Vector2(0.3512397f, 0.4165289f), new Vector2(0.438843f, 0.4479339f), new Vector2(0.5330579f, 0.4479339f), new Vector2(0.6157025f, 0.4247934f), new Vector2(0.6884298f, 0.3818182f), new Vector2(0.7148761f, 0.3586777f) }, new Vector3[] { new Vector2(0.1561984f, 0.4809917f), new Vector2(0.2355372f, 0.5438017f), new Vector2(0.3297521f, 0.5933884f), new Vector2(0.4289256f, 0.6181818f), new Vector2(0.5181818f, 0.6231405f), new Vector2(0.6157025f, 0.6066115f), new Vector2(0.7016529f, 0.5752066f), new Vector2(0.7859504f, 0.5206612f), new Vector2(0.8421488f, 0.477686f) }, new Vector3[] { new Vector2(0.04214876f, 0.6099173f), new Vector2(0.1264463f, 0.6793389f), new Vector2(0.2140496f, 0.7305785f), new Vector2(0.3231405f, 0.7702479f), new Vector2(0.4256198f, 0.7900826f), new Vector2(0.5561984f, 0.7917355f), new Vector2(0.6669421f, 0.7702479f), new Vector2(0.7776859f, 0.7256199f), new Vector2(0.8801653f, 0.6661157f), new Vector2(0.9595041f, 0.5933884f) } }; } return icon_wlan_wifi; } + Vector3[][] Icon_share() { if (icon_share == null) { icon_share = new Vector3[][] { new Vector3[] { new Vector2(0.4428104f, 0.6176471f), new Vector2(0.3022876f, 0.6176471f), new Vector2(0.3022876f, 0.05392157f), new Vector2(0.6797386f, 0.05392157f), new Vector2(0.6797386f, 0.6192811f), new Vector2(0.5359477f, 0.6192811f) }, new Vector3[] { new Vector2(0.4918301f, 0.3366013f), new Vector2(0.4918301f, 0.7140523f), new Vector2(0.5081699f, 0.7777778f), new Vector2(0.5457516f, 0.8333333f), new Vector2(0.5849673f, 0.8643791f), new Vector2(0.6339869f, 0.877451f), new Vector2(0.7320262f, 0.877451f) }, new Vector3[] { new Vector2(0.6192811f, 0.9787582f), new Vector2(0.7303922f, 0.875817f), new Vector2(0.6160131f, 0.7761438f) } }; } return icon_share; } + Vector3[][] Icon_timeClock() { if (icon_timeClock == null) { icon_timeClock = new Vector3[][] { new Vector3[] { new Vector2(0.500192f, 0.03435445f), new Vector2(0.3129722f, 0.07179838f), new Vector2(0.1734083f, 0.1620043f), new Vector2(0.07299039f, 0.3032703f), new Vector2(0.02703643f, 0.499f), new Vector2(0.0610764f, 0.6828159f), new Vector2(0.1785143f, 0.8530157f), new Vector2(0.3197802f, 0.9432217f), new Vector2(0.507f, 0.9755597f), new Vector2(0.7095378f, 0.9296057f), new Vector2(0.8508038f, 0.8206778f), new Vector2(0.9410096f, 0.6743059f), new Vector2(0.9699436f, 0.499f), new Vector2(0.9273937f, 0.3049722f), new Vector2(0.8320818f, 0.1671104f), new Vector2(0.6840079f, 0.07350042f), new Vector2(0.500192f, 0.03435445f) }, new Vector3[] { new Vector2(0.4999412f, 0.08449066f), new Vector2(0.3333257f, 0.1178137f), new Vector2(0.2091215f, 0.1980921f), new Vector2(0.119755f, 0.3238111f), new Vector2(0.07885844f, 0.498f), new Vector2(0.1091522f, 0.6615862f), new Vector2(0.2136655f, 0.8130548f), new Vector2(0.3393845f, 0.8933332f), new Vector2(0.506f, 0.9221122f), new Vector2(0.6862476f, 0.8812157f), new Vector2(0.8119667f, 0.7842758f), new Vector2(0.892245f, 0.6540127f), new Vector2(0.9179947f, 0.498f), new Vector2(0.8801275f, 0.3253258f), new Vector2(0.795305f, 0.2026362f), new Vector2(0.6635273f, 0.1193285f), new Vector2(0.4999412f, 0.08449066f) }, new Vector3[] { new Vector2(0.49f, 0.4291129f), new Vector2(0.4576771f, 0.4425152f), new Vector2(0.4449055f, 0.472f), new Vector2(0.457204f, 0.5029039f), new Vector2(0.4892116f, 0.5166215f), new Vector2(0.5201156f, 0.5043229f), new Vector2(0.5325717f, 0.4718423f), new Vector2(0.5199579f, 0.4410961f), new Vector2(0.49f, 0.4291129f) }, new Vector3[] { new Vector2(0.4851562f, 0.8375f), new Vector2(0.4851562f, 0.4734375f), new Vector2(0.7929688f, 0.3453125f) }, new Vector3[] { new Vector2(0.07966616f, 0.4992413f), new Vector2(0.146434f, 0.4992413f) }, new Vector3[] { new Vector2(0.1418816f, 0.7086495f), new Vector2(0.1949924f, 0.6737481f) }, new Vector3[] { new Vector2(0.2936267f, 0.8634294f), new Vector2(0.3194234f, 0.8072838f) }, new Vector3[] { new Vector2(0.4908953f, 0.9210926f), new Vector2(0.4908953f, 0.8694993f) }, new Vector3[] { new Vector2(0.7063733f, 0.8634294f), new Vector2(0.6760243f, 0.8088012f) }, new Vector3[] { new Vector2(0.8566009f, 0.7086495f), new Vector2(0.8034902f, 0.6752656f) }, new Vector3[] { new Vector2(0.9172989f, 0.5022762f), new Vector2(0.8505311f, 0.5022762f) }, new Vector3[] { new Vector2(0.8566009f, 0.2943854f), new Vector2(0.8141123f, 0.3216995f) }, new Vector3[] { new Vector2(0.698786f, 0.1456753f), new Vector2(0.6699545f, 0.1972686f) }, new Vector3[] { new Vector2(0.4984826f, 0.08497724f), new Vector2(0.4984826f, 0.1471927f) }, new Vector3[] { new Vector2(0.2921093f, 0.1441578f), new Vector2(0.3270106f, 0.1972686f) }, new Vector3[] { new Vector2(0.1418816f, 0.2943854f), new Vector2(0.2025797f, 0.3292868f) } }; } return icon_timeClock; } + Vector3[][] Icon_telephone() { if (icon_telephone == null) { icon_telephone = new Vector3[][] { new Vector3[] { new Vector2(0.4526144f, 0.7369281f), new Vector2(0.3137255f, 0.6405229f), new Vector2(0.3251634f, 0.5784314f), new Vector2(0.5147059f, 0.3088235f), new Vector2(0.5735294f, 0.2843137f), new Vector2(0.7091503f, 0.377451f), new Vector2(0.8839869f, 0.2434641f), new Vector2(0.8333333f, 0.1437909f), new Vector2(0.7549019f, 0.08496732f), new Vector2(0.6486928f, 0.06372549f), new Vector2(0.5718954f, 0.07026144f), new Vector2(0.3954248f, 0.2124183f), new Vector2(0.2401961f, 0.4150327f), new Vector2(0.1830065f, 0.5212418f), new Vector2(0.122549f, 0.7418301f), new Vector2(0.1437909f, 0.8104575f), new Vector2(0.1879085f, 0.8709151f), new Vector2(0.2434641f, 0.9199346f), new Vector2(0.3071896f, 0.9460784f), new Vector2(0.3921569f, 0.9509804f), new Vector2(0.4526144f, 0.7369281f) }, new Vector3[] { new Vector2(0.2810458f, 0.9313725f), new Vector2(0.3660131f, 0.6830065f) }, new Vector3[] { new Vector2(0.624183f, 0.3186274f), new Vector2(0.8284314f, 0.1437909f) } }; } return icon_telephone; } + Vector3[][] Icon_doorOpen() { if (icon_doorOpen == null) { icon_doorOpen = new Vector3[][] { new Vector3[] { new Vector2(0.875817f, 0.1813726f), new Vector2(0.7107843f, 0.1813726f), new Vector2(0.7107843f, 0.8464052f), new Vector2(0.6503268f, 0.8464052f) }, new Vector3[] { new Vector2(0.7091503f, 0.8104575f), new Vector2(0.4869281f, 0.9362745f), new Vector2(0.4869281f, 0.06862745f), new Vector2(0.7107843f, 0.1830065f) }, new Vector3[] { new Vector2(0.5114379f, 0.5196078f), new Vector2(0.5114379f, 0.4803922f), new Vector2(0.5555556f, 0.503268f), new Vector2(0.5114379f, 0.5196078f) }, new Vector3[] { new Vector2(0.1094771f, 0.1813726f), new Vector2(0.2777778f, 0.1813726f), new Vector2(0.2777778f, 0.8169935f), new Vector2(0.4852941f, 0.8169935f) }, new Vector3[] { new Vector2(0.246732f, 0.1830065f), new Vector2(0.246732f, 0.8464052f), new Vector2(0.4852941f, 0.8464052f) } }; } return icon_doorOpen; } + Vector3[][] Icon_doorEnter() { if (icon_doorEnter == null) { icon_doorEnter = new Vector3[][] { new Vector3[] { new Vector2(0.9444444f, 0.1830065f), new Vector2(0.8594771f, 0.1830065f), new Vector2(0.8594771f, 0.8431373f), new Vector2(0.7973856f, 0.8431373f) }, new Vector3[] { new Vector2(0.8562092f, 0.8071895f), new Vector2(0.6307189f, 0.9346405f), new Vector2(0.6307189f, 0.06699347f), new Vector2(0.8594771f, 0.1846405f) }, new Vector3[] { new Vector2(0.6519608f, 0.5163399f), new Vector2(0.6519608f, 0.4820261f), new Vector2(0.6960784f, 0.5049019f), new Vector2(0.6519608f, 0.5163399f) }, new Vector3[] { new Vector2(0.6290849f, 0.8447713f), new Vector2(0.3888889f, 0.8447713f), new Vector2(0.3888889f, 0.6911765f) }, new Vector3[] { new Vector2(0.6290849f, 0.8169935f), new Vector2(0.4215686f, 0.8169935f), new Vector2(0.4215686f, 0.6911765f) }, new Vector3[] { new Vector2(0.253268f, 0.1813726f), new Vector2(0.4215686f, 0.1813726f), new Vector2(0.4215686f, 0.3088235f) }, new Vector3[] { new Vector2(0.3888889f, 0.1813726f), new Vector2(0.3888889f, 0.3071896f) }, new Vector3[] { new Vector2(0.08986928f, 0.503268f), new Vector2(0.4869281f, 0.503268f) }, new Vector3[] { new Vector2(0.3513072f, 0.6323529f), new Vector2(0.4869281f, 0.503268f), new Vector2(0.3447712f, 0.3611111f) } }; } return icon_doorEnter; } + Vector3[][] Icon_doorLeave() { if (icon_doorLeave == null) { icon_doorLeave = new Vector3[][] { new Vector3[] { new Vector2(0.9444444f, 0.1830065f), new Vector2(0.8594771f, 0.1830065f), new Vector2(0.8594771f, 0.8431373f), new Vector2(0.7973856f, 0.8431373f) }, new Vector3[] { new Vector2(0.8562092f, 0.8071895f), new Vector2(0.6307189f, 0.9346405f), new Vector2(0.6307189f, 0.06699347f), new Vector2(0.8594771f, 0.1846405f) }, new Vector3[] { new Vector2(0.6519608f, 0.5163399f), new Vector2(0.6519608f, 0.4820261f), new Vector2(0.6960784f, 0.5049019f), new Vector2(0.6519608f, 0.5163399f) }, new Vector3[] { new Vector2(0.6290849f, 0.8447713f), new Vector2(0.3888889f, 0.8447713f), new Vector2(0.3888889f, 0.5947713f) }, new Vector3[] { new Vector2(0.6290849f, 0.8169935f), new Vector2(0.4199346f, 0.8169935f), new Vector2(0.4199346f, 0.5947713f) }, new Vector3[] { new Vector2(0.25f, 0.1813726f), new Vector2(0.4215686f, 0.1813726f), new Vector2(0.4215686f, 0.4117647f) }, new Vector3[] { new Vector2(0.3872549f, 0.1830065f), new Vector2(0.3872549f, 0.4101307f) }, new Vector3[] { new Vector2(0.498366f, 0.501634f), new Vector2(0.1013072f, 0.501634f) }, new Vector3[] { new Vector2(0.2418301f, 0.6339869f), new Vector2(0.1013072f, 0.501634f), new Vector2(0.248366f, 0.3611111f) } }; } return icon_doorLeave; } + Vector3[][] Icon_locationPin() { if (icon_locationPin == null) { icon_locationPin = new Vector3[][] { new Vector3[] { new Vector2(0.497781f, 0.9146566f), new Vector2(0.4367599f, 0.9268609f), new Vector2(0.3912714f, 0.9562619f), new Vector2(0.3585419f, 1.002305f), new Vector2(0.343564f, 1.0661f), new Vector2(0.3546587f, 1.126012f), new Vector2(0.3929356f, 1.181485f), new Vector2(0.4389789f, 1.210886f), new Vector2(0.5f, 1.221427f), new Vector2(0.5660138f, 1.206449f), new Vector2(0.612057f, 1.170945f), new Vector2(0.6414581f, 1.123238f), new Vector2(0.6508887f, 1.0661f), new Vector2(0.6370202f, 1.00286f), new Vector2(0.6059549f, 0.9579262f), new Vector2(0.5576927f, 0.9274156f), new Vector2(0.497781f, 0.9146566f) }, new Vector3[] { new Vector2(0.2633884f, 0.9485698f), new Vector2(0.2338675f, 1.054099f), new Vector2(0.2437341f, 1.148963f), new Vector2(0.2899046f, 1.237074f), new Vector2(0.3781035f, 1.311479f), new Vector2(0.4810059f, 1.341857f), new Vector2(0.598626f, 1.326022f), new Vector2(0.6815119f, 1.277197f), new Vector2(0.7467375f, 1.189811f), new Vector2(0.7758869f, 1.074232f), new Vector2(0.7568836f, 0.9736289f), new Vector2(0.5f, 0.5f), new Vector2(0.2633884f, 0.9485698f) } }; } return icon_locationPin; } + Vector3[][] Icon_folder() { if (icon_folder == null) { icon_folder = new Vector3[][] { new Vector3[] { new Vector2(0.75f, 0.08006536f), new Vector2(0.09803922f, 0.08006536f), new Vector2(0.2369281f, 0.4689542f), new Vector2(0.8937908f, 0.4689542f), new Vector2(0.75f, 0.08006536f) }, new Vector3[] { new Vector2(0.0996732f, 0.08169935f), new Vector2(0.0996732f, 0.6650327f), new Vector2(0.3055556f, 0.6650327f), new Vector2(0.3333333f, 0.6372549f), new Vector2(0.3333333f, 0.5964052f), new Vector2(0.3594771f, 0.5718954f), new Vector2(0.748366f, 0.5718954f), new Vector2(0.748366f, 0.4689542f) } }; } return icon_folder; } + Vector3[][] Icon_saveToFolder() { if (icon_saveToFolder == null) { icon_saveToFolder = new Vector3[][] { new Vector3[] { new Vector2(0.75f, 0.08006536f), new Vector2(0.09803922f, 0.08006536f), new Vector2(0.2369281f, 0.4689542f), new Vector2(0.8937908f, 0.4689542f), new Vector2(0.75f, 0.08006536f) }, new Vector3[] { new Vector2(0.0996732f, 0.08169935f), new Vector2(0.0996732f, 0.6650327f), new Vector2(0.3055556f, 0.6650327f), new Vector2(0.3333333f, 0.6372549f), new Vector2(0.3333333f, 0.5964052f), new Vector2(0.3594771f, 0.5718954f), new Vector2(0.748366f, 0.5718954f), new Vector2(0.748366f, 0.4689542f) }, new Vector3[] { new Vector2(0.5441176f, 0.9689543f), new Vector2(0.5441176f, 0.6601307f) }, new Vector3[] { new Vector2(0.4297386f, 0.7794118f), new Vector2(0.5441176f, 0.6584967f), new Vector2(0.6650327f, 0.7826797f) } }; } return icon_saveToFolder; } + Vector3[][] Icon_loadFromFolder() { if (icon_loadFromFolder == null) { icon_loadFromFolder = new Vector3[][] { new Vector3[] { new Vector2(0.75f, 0.08006536f), new Vector2(0.09803922f, 0.08006536f), new Vector2(0.2369281f, 0.4689542f), new Vector2(0.8937908f, 0.4689542f), new Vector2(0.75f, 0.08006536f) }, new Vector3[] { new Vector2(0.0996732f, 0.08169935f), new Vector2(0.0996732f, 0.6650327f), new Vector2(0.3055556f, 0.6650327f), new Vector2(0.3333333f, 0.6372549f), new Vector2(0.3333333f, 0.5964052f), new Vector2(0.3594771f, 0.5718954f), new Vector2(0.748366f, 0.5718954f), new Vector2(0.748366f, 0.4689542f) }, new Vector3[] { new Vector2(0.5441176f, 0.9689543f), new Vector2(0.5441176f, 0.6601307f) }, new Vector3[] { new Vector2(0.4297386f, 0.8496732f), new Vector2(0.5441176f, 0.9673203f), new Vector2(0.6650327f, 0.8480392f) } }; } return icon_loadFromFolder; } + Vector3[][] Icon_optionsSettingsGear() { if (icon_optionsSettingsGear == null) { icon_optionsSettingsGear = new Vector3[][] { new Vector3[] { new Vector2(0.4970988f, 0.3151436f), new Vector2(0.422816f, 0.3300002f), new Vector2(0.3674416f, 0.365791f), new Vector2(0.327599f, 0.4218408f), new Vector2(0.3093659f, 0.4995f), new Vector2(0.3228719f, 0.5724322f), new Vector2(0.3694675f, 0.639962f), new Vector2(0.4255172f, 0.6757528f), new Vector2(0.4998f, 0.6885835f), new Vector2(0.5801604f, 0.6703504f), new Vector2(0.6362102f, 0.6271313f), new Vector2(0.672001f, 0.5690557f), new Vector2(0.6834811f, 0.4995f), new Vector2(0.6665986f, 0.422516f), new Vector2(0.6287819f, 0.3678169f), new Vector2(0.570031f, 0.3306755f), new Vector2(0.4970988f, 0.3151436f) }, new Vector3[] { new Vector2(0.5722689f, 0.8453782f), new Vector2(0.6798319f, 0.7882353f), new Vector2(0.7739496f, 0.8789916f), new Vector2(0.8764706f, 0.7697479f), new Vector2(0.7840336f, 0.6806723f), new Vector2(0.8277311f, 0.5731093f), new Vector2(0.9588235f, 0.5731093f), new Vector2(0.9588235f, 0.4285714f), new Vector2(0.8294117f, 0.4285714f), new Vector2(0.7840336f, 0.3176471f), new Vector2(0.8714285f, 0.2268908f), new Vector2(0.7672269f, 0.1260504f), new Vector2(0.6697479f, 0.2184874f), new Vector2(0.5705882f, 0.1663866f), new Vector2(0.5705882f, 0.03697479f), new Vector2(0.4226891f, 0.03697479f), new Vector2(0.4226891f, 0.1663866f), new Vector2(0.3151261f, 0.2151261f), new Vector2(0.2243697f, 0.1277311f), new Vector2(0.1235294f, 0.2285714f), new Vector2(0.202521f, 0.3126051f), new Vector2(0.1605042f, 0.4252101f), new Vector2(0.03445378f, 0.4252101f), new Vector2(0.03445378f, 0.5714286f), new Vector2(0.1588235f, 0.5714286f), new Vector2(0.207563f, 0.6890756f), new Vector2(0.1168067f, 0.7798319f), new Vector2(0.2226891f, 0.8840336f), new Vector2(0.3084034f, 0.7915967f), new Vector2(0.4210084f, 0.8403361f), new Vector2(0.4210084f, 0.9663866f), new Vector2(0.5705882f, 0.9663866f), new Vector2(0.5705882f, 0.8470588f) } }; } return icon_optionsSettingsGear; } + Vector3[][] Icon_adjustOptionsSettings() { if (icon_adjustOptionsSettings == null) { icon_adjustOptionsSettings = new Vector3[][] { new Vector3[] { new Vector2(0.2853949f, 0.7272727f), new Vector2(0.2853949f, 0.8643815f), new Vector2(0.3137109f, 0.9076006f), new Vector2(0.3599106f, 0.9359165f), new Vector2(0.4180328f, 0.9359165f), new Vector2(0.45231f, 0.9150522f), new Vector2(0.476155f, 0.8792846f), new Vector2(0.4880775f, 0.8420268f), new Vector2(0.4880775f, 0.7272727f), new Vector2(0.4701937f, 0.6929955f), new Vector2(0.4433681f, 0.6631893f), new Vector2(0.3897168f, 0.6438152f), new Vector2(0.3315946f, 0.6616989f), new Vector2(0.2943368f, 0.6959761f), new Vector2(0.2853949f, 0.7272727f) }, new Vector3[] { new Vector2(0.5551416f, 0.5707899f), new Vector2(0.5774963f, 0.609538f), new Vector2(0.6177347f, 0.6393443f), new Vector2(0.6609538f, 0.6467958f), new Vector2(0.7086438f, 0.6274217f), new Vector2(0.7339791f, 0.6020864f), new Vector2(0.7548435f, 0.557377f), new Vector2(0.7548435f, 0.4336811f), new Vector2(0.7354695f, 0.3994039f), new Vector2(0.7041728f, 0.3710879f), new Vector2(0.6564829f, 0.3532042f), new Vector2(0.6102831f, 0.366617f), new Vector2(0.5745156f, 0.390462f), new Vector2(0.552161f, 0.4441133f), new Vector2(0.552161f, 0.5707899f) }, new Vector3[] { new Vector2(0.185544f, 0.266766f), new Vector2(0.204918f, 0.3129657f), new Vector2(0.2421759f, 0.3412817f), new Vector2(0.2943368f, 0.3502235f), new Vector2(0.3405365f, 0.3323398f), new Vector2(0.3703428f, 0.3010432f), new Vector2(0.3852459f, 0.2578242f), new Vector2(0.3852459f, 0.1296572f), new Vector2(0.3614009f, 0.0923994f), new Vector2(0.3301043f, 0.07004471f), new Vector2(0.2794337f, 0.05961252f), new Vector2(0.2302534f, 0.07302534f), new Vector2(0.2004471f, 0.1043219f), new Vector2(0.181073f, 0.1564829f), new Vector2(0.181073f, 0.2697467f) }, new Vector3[] { new Vector2(0.3822653f, 0.8494784f), new Vector2(0.3822653f, 0.7272727f) }, new Vector3[] { new Vector2(0.647541f, 0.5424739f), new Vector2(0.647541f, 0.4351714f) }, new Vector3[] { new Vector2(0.280924f, 0.2503726f), new Vector2(0.280924f, 0.1385991f) }, new Vector3[] { new Vector2(0.2853949f, 0.7883756f), new Vector2(0.0633383f, 0.7883756f) }, new Vector3[] { new Vector2(0.4895678f, 0.7868853f), new Vector2(0.9411327f, 0.7868853f) }, new Vector3[] { new Vector2(0.552161f, 0.4992549f), new Vector2(0.0633383f, 0.4992549f) }, new Vector3[] { new Vector2(0.7578241f, 0.4977645f), new Vector2(0.9411327f, 0.4977645f) }, new Vector3[] { new Vector2(0.3852459f, 0.2041729f), new Vector2(0.9411327f, 0.2041729f) }, new Vector3[] { new Vector2(0.1795827f, 0.2056632f), new Vector2(0.0633383f, 0.2056632f) } }; } return icon_adjustOptionsSettings; } + Vector3[][] Icon_pen() { if (icon_pen == null) { icon_pen = new Vector3[][] { new Vector3[] { new Vector2(0.5f, 0.5f), new Vector2(0.6363636f, 0.7694215f), new Vector2(1.335537f, 1.468595f), new Vector2(1.385124f, 1.430578f), new Vector2(1.434711f, 1.379339f), new Vector2(1.456198f, 1.338017f), new Vector2(0.7619835f, 0.6388429f), new Vector2(0.5f, 0.5f) }, new Vector3[] { new Vector2(0.6347107f, 0.7694215f), new Vector2(0.6909091f, 0.7297521f), new Vector2(0.7338843f, 0.6818182f), new Vector2(0.7586777f, 0.6371901f) }, new Vector3[] { new Vector2(1.247934f, 1.379339f), new Vector2(1.295868f, 1.349587f), new Vector2(1.347107f, 1.298347f), new Vector2(1.370248f, 1.255372f) }, new Vector3[] { new Vector2(0.5586777f, 0.6190082f), new Vector2(0.6066115f, 0.5644628f) }, new Vector3[] { new Vector2(0.5471075f, 0.5975206f), new Vector2(0.5834711f, 0.5512397f) }, new Vector3[] { new Vector2(0.5355372f, 0.5743802f), new Vector2(0.5603306f, 0.5413223f) }, new Vector3[] { new Vector2(0.5190083f, 0.5479339f), new Vector2(0.5355372f, 0.5264463f) } }; } return icon_pen; } + Vector3[][] Icon_questionMark() { if (icon_questionMark == null) { icon_questionMark = new Vector3[][] { new Vector3[] { new Vector2(0.5004716f, 0.05543387f), new Vector2(0.3209394f, 0.09134027f), new Vector2(0.1871064f, 0.1778421f), new Vector2(0.09081188f, 0.3133073f), new Vector2(0.04674485f, 0.501f), new Vector2(0.0793871f, 0.677268f), new Vector2(0.1920027f, 0.840479f), new Vector2(0.3274679f, 0.9269809f), new Vector2(0.507f, 0.957991f), new Vector2(0.7012211f, 0.913924f), new Vector2(0.8366864f, 0.8094689f), new Vector2(0.9231882f, 0.6691074f), new Vector2(0.9509341f, 0.501f), new Vector2(0.9101313f, 0.3149394f), new Vector2(0.8187331f, 0.1827385f), new Vector2(0.6767395f, 0.09297243f), new Vector2(0.5004716f, 0.05543387f) }, new Vector3[] { new Vector2(0.5f, 0.2213354f), new Vector2(0.4595543f, 0.2381056f), new Vector2(0.4435733f, 0.275f), new Vector2(0.4589624f, 0.3136701f), new Vector2(0.4990135f, 0.3308348f), new Vector2(0.5376835f, 0.3154457f), new Vector2(0.55327f, 0.2748027f), new Vector2(0.5374863f, 0.23633f), new Vector2(0.5f, 0.2213354f) }, new Vector3[] { new Vector2(0.3801214f, 0.6843703f), new Vector2(0.4104704f, 0.6919575f), new Vector2(0.4332322f, 0.7405159f), new Vector2(0.4711684f, 0.7617602f), new Vector2(0.5531108f, 0.7602428f), new Vector2(0.5849772f, 0.7298938f), new Vector2(0.5925645f, 0.6737481f), new Vector2(0.560698f, 0.6312595f), new Vector2(0.5f, 0.5902883f), new Vector2(0.4590288f, 0.5204856f), new Vector2(0.4499241f, 0.4597875f), new Vector2(0.4514416f, 0.4097117f), new Vector2(0.483308f, 0.3884674f), new Vector2(0.5212443f, 0.4127466f), new Vector2(0.5227618f, 0.4749621f), new Vector2(0.547041f, 0.5295903f), new Vector2(0.6062216f, 0.569044f), new Vector2(0.6532625f, 0.6267071f), new Vector2(0.6729894f, 0.6980273f), new Vector2(0.6456752f, 0.7678301f), new Vector2(0.5925645f, 0.8239757f), new Vector2(0.5091047f, 0.8421851f), new Vector2(0.4271624f, 0.8270106f), new Vector2(0.3664643f, 0.7860395f), new Vector2(0.3467375f, 0.7329287f), new Vector2(0.3558422f, 0.6995448f), new Vector2(0.3801214f, 0.6843703f) } }; } return icon_questionMark; } + Vector3[][] Icon_exclamationMark() { if (icon_exclamationMark == null) { icon_exclamationMark = new Vector3[][] { new Vector3[] { new Vector2(0.5004716f, 0.05543387f), new Vector2(0.3209394f, 0.09134027f), new Vector2(0.1871064f, 0.1778421f), new Vector2(0.09081188f, 0.3133073f), new Vector2(0.04674485f, 0.501f), new Vector2(0.0793871f, 0.677268f), new Vector2(0.1920027f, 0.840479f), new Vector2(0.3274679f, 0.9269809f), new Vector2(0.507f, 0.957991f), new Vector2(0.7012211f, 0.913924f), new Vector2(0.8366864f, 0.8094689f), new Vector2(0.9231882f, 0.6691074f), new Vector2(0.9509341f, 0.501f), new Vector2(0.9101313f, 0.3149394f), new Vector2(0.8187331f, 0.1827385f), new Vector2(0.6767395f, 0.09297243f), new Vector2(0.5004716f, 0.05543387f) }, new Vector3[] { new Vector2(0.5f, 0.2213354f), new Vector2(0.4595543f, 0.2381056f), new Vector2(0.4435733f, 0.275f), new Vector2(0.4589624f, 0.3136701f), new Vector2(0.4990135f, 0.3308348f), new Vector2(0.5376835f, 0.3154457f), new Vector2(0.55327f, 0.2748027f), new Vector2(0.5374863f, 0.23633f), new Vector2(0.5f, 0.2213354f) }, new Vector3[] { new Vector2(0.547041f, 0.4339909f), new Vector2(0.5531108f, 0.8072838f), new Vector2(0.4377845f, 0.8072838f), new Vector2(0.4514416f, 0.4355083f), new Vector2(0.5455235f, 0.4355083f) } }; } return icon_exclamationMark; } + Vector3[][] Icon_shoppingCart() { if (icon_shoppingCart == null) { icon_shoppingCart = new Vector3[][] { new Vector3[] { new Vector2(0.328f, 0.0289638f), new Vector2(0.2725775f, 0.05194387f), new Vector2(0.2506789f, 0.1025f), new Vector2(0.2717665f, 0.1554893f), new Vector2(0.3266482f, 0.1790101f), new Vector2(0.3796375f, 0.1579225f), new Vector2(0.4009955f, 0.1022296f), new Vector2(0.3793672f, 0.04951068f), new Vector2(0.328f, 0.0289638f) }, new Vector3[] { new Vector2(0.8052f, 0.02983347f), new Vector2(0.7506872f, 0.05238551f), new Vector2(0.729148f, 0.102f), new Vector2(0.7498895f, 0.1540024f), new Vector2(0.8038704f, 0.177085f), new Vector2(0.8559899f, 0.1563902f), new Vector2(0.8769972f, 0.1017347f), new Vector2(0.855724f, 0.04999765f), new Vector2(0.8052f, 0.02983347f) }, new Vector3[] { new Vector2(0.07310925f, 0.8470588f), new Vector2(0.1773109f, 0.8470588f), new Vector2(0.2210084f, 0.789916f), new Vector2(0.3252101f, 0.3226891f), new Vector2(0.2663866f, 0.2184874f), new Vector2(0.8445378f, 0.2184874f) }, new Vector3[] { new Vector2(0.3252101f, 0.3243698f), new Vector2(0.797479f, 0.3243698f), new Vector2(0.920168f, 0.7159664f), new Vector2(0.2378151f, 0.7159664f) }, new Vector3[] { new Vector2(0.2831933f, 0.5126051f), new Vector2(0.8546218f, 0.5126051f) }, new Vector3[] { new Vector2(0.6344538f, 0.3260504f), new Vector2(0.6865546f, 0.7142857f) }, new Vector3[] { new Vector2(0.4798319f, 0.3243698f), new Vector2(0.4310924f, 0.7176471f) } }; } return icon_shoppingCart; } + Vector3[][] Icon_checkmarkChecked() { if (icon_checkmarkChecked == null) { icon_checkmarkChecked = new Vector3[][] { new Vector3[] { new Vector2(0.8383784f, 0.545056f), new Vector2(0.8328274f, 0.4063708f), new Vector2(0.7839646f, 0.2958893f), new Vector2(0.6939817f, 0.2076955f), new Vector2(0.5586894f, 0.1523994f), new Vector2(0.4228359f, 0.1558943f), new Vector2(0.2872558f, 0.2208181f), new Vector2(0.2063938f, 0.3119646f), new Vector2(0.1618434f, 0.4426985f), new Vector2(0.1717589f, 0.5933512f), new Vector2(0.2338696f, 0.7071881f), new Vector2(0.3286821f, 0.7886317f), new Vector2(0.45125f, 0.8293808f), new Vector2(0.5954049f, 0.8209394f), new Vector2(0.6697479f, 0.7915967f) }, new Vector3[] { new Vector2(0.505042f, 0.4252101f), new Vector2(0.5739496f, 0.5478992f), new Vector2(0.6563025f, 0.6571429f), new Vector2(0.7487395f, 0.7394958f), new Vector2(0.8193277f, 0.784874f), new Vector2(0.9067227f, 0.8319328f), new Vector2(0.9487395f, 0.8487395f), new Vector2(0.9638655f, 0.8252101f), new Vector2(0.8798319f, 0.7663866f), new Vector2(0.7605042f, 0.6605042f), new Vector2(0.6747899f, 0.5478992f), new Vector2(0.592437f, 0.4151261f), new Vector2(0.5386555f, 0.3058824f), new Vector2(0.5235294f, 0.2890756f), new Vector2(0.494958f, 0.282353f), new Vector2(0.4613445f, 0.3126051f), new Vector2(0.2932773f, 0.5882353f), new Vector2(0.3016807f, 0.6168067f), new Vector2(0.3201681f, 0.6420168f), new Vector2(0.3537815f, 0.6420168f), new Vector2(0.3789916f, 0.6184874f), new Vector2(0.505042f, 0.4252101f) } }; } return icon_checkmarkChecked; } + Vector3[][] Icon_checkmarkUnchecked() { if (icon_checkmarkUnchecked == null) { icon_checkmarkUnchecked = new Vector3[][] { new Vector3[] { new Vector2(0.8383784f, 0.545056f), new Vector2(0.8328274f, 0.4063708f), new Vector2(0.7839646f, 0.2958893f), new Vector2(0.6939817f, 0.2076955f), new Vector2(0.5586894f, 0.1523994f), new Vector2(0.4228359f, 0.1558943f), new Vector2(0.2872558f, 0.2208181f), new Vector2(0.2063938f, 0.3119646f), new Vector2(0.1618434f, 0.4426985f), new Vector2(0.1717589f, 0.5933512f), new Vector2(0.2338696f, 0.7071881f), new Vector2(0.3286821f, 0.7886317f), new Vector2(0.45125f, 0.8293808f), new Vector2(0.5954049f, 0.8209394f), new Vector2(0.7052462f, 0.7682168f), new Vector2(0.7893279f, 0.6725702f), new Vector2(0.8383784f, 0.545056f) } }; } return icon_checkmarkUnchecked; } + Vector3[][] Icon_battery() { if (icon_battery == null) { icon_battery = new Vector3[][] { new Vector3[] { new Vector2(0.8882353f, 0.6521009f), new Vector2(0.8882353f, 0.3512605f), new Vector2(0.8596638f, 0.3260504f), new Vector2(0.08487395f, 0.3260504f), new Vector2(0.05798319f, 0.3579832f), new Vector2(0.05798319f, 0.6487395f), new Vector2(0.08319328f, 0.6756303f), new Vector2(0.8680672f, 0.6756303f), new Vector2(0.8882353f, 0.6521009f) }, new Vector3[] { new Vector2(0.9084033f, 0.6605042f), new Vector2(0.9084033f, 0.3411765f), new Vector2(0.8680672f, 0.3042017f), new Vector2(0.07815126f, 0.3042017f), new Vector2(0.0394958f, 0.3529412f), new Vector2(0.0394958f, 0.6605042f), new Vector2(0.08151261f, 0.7008404f), new Vector2(0.8747899f, 0.7008404f), new Vector2(0.9084033f, 0.6605042f) }, new Vector3[] { new Vector2(0.4142857f, 0.6117647f), new Vector2(0.4142857f, 0.3714286f), new Vector2(0.3991597f, 0.3495798f), new Vector2(0.3621849f, 0.3495798f), new Vector2(0.3504202f, 0.3798319f), new Vector2(0.3504202f, 0.6100841f), new Vector2(0.3672269f, 0.6319328f), new Vector2(0.402521f, 0.6319328f), new Vector2(0.4142857f, 0.6117647f) }, new Vector3[] { new Vector2(0.3033614f, 0.6084034f), new Vector2(0.3033614f, 0.3731093f), new Vector2(0.2831933f, 0.3529412f), new Vector2(0.2529412f, 0.3529412f), new Vector2(0.2310924f, 0.3865546f), new Vector2(0.2310924f, 0.6067227f), new Vector2(0.2529412f, 0.6336135f), new Vector2(0.2865546f, 0.6336135f), new Vector2(0.3033614f, 0.6084034f) }, new Vector3[] { new Vector2(0.1890756f, 0.6033614f), new Vector2(0.1890756f, 0.3781513f), new Vector2(0.1722689f, 0.3579832f), new Vector2(0.1336135f, 0.3579832f), new Vector2(0.1168067f, 0.3798319f), new Vector2(0.1168067f, 0.6033614f), new Vector2(0.1352941f, 0.6302521f), new Vector2(0.1739496f, 0.6302521f), new Vector2(0.1890756f, 0.6033614f) }, new Vector3[] { new Vector2(0.9117647f, 0.5865546f), new Vector2(0.9638655f, 0.5546219f), new Vector2(0.9638655f, 0.4386555f), new Vector2(0.910084f, 0.4084034f) } }; } return icon_battery; } + Vector3[][] Icon_cloud() { if (icon_cloud == null) { icon_cloud = new Vector3[][] { new Vector3[] { new Vector2(0.8260504f, 0.2285714f), new Vector2(0.1806723f, 0.2285714f), new Vector2(0.1134454f, 0.2521009f), new Vector2(0.0512605f, 0.3159664f), new Vector2(0.03277311f, 0.394958f), new Vector2(0.0512605f, 0.4789916f), new Vector2(0.1016807f, 0.5394958f), new Vector2(0.1605042f, 0.5680673f), new Vector2(0.2109244f, 0.5697479f), new Vector2(0.197479f, 0.6672269f), new Vector2(0.2277311f, 0.7546219f), new Vector2(0.2915967f, 0.8134454f), new Vector2(0.3655462f, 0.8470588f), new Vector2(0.4563025f, 0.8403361f), new Vector2(0.5319328f, 0.8016807f), new Vector2(0.5756302f, 0.7478992f), new Vector2(0.5991597f, 0.7109244f), new Vector2(0.6529412f, 0.7462185f), new Vector2(0.7235294f, 0.7546219f), new Vector2(0.792437f, 0.7210084f), new Vector2(0.8394958f, 0.6537815f), new Vector2(0.8428571f, 0.5815126f), new Vector2(0.8260504f, 0.5260504f), new Vector2(0.894958f, 0.5042017f), new Vector2(0.9436975f, 0.4453782f), new Vector2(0.9655462f, 0.3714286f), new Vector2(0.9436975f, 0.3008403f), new Vector2(0.894958f, 0.2521009f), new Vector2(0.8260504f, 0.2285714f) } }; } return icon_cloud; } + Vector3[][] Icon_magnifier() { if (icon_magnifier == null) { icon_magnifier = new Vector3[][] { new Vector3[] { new Vector2(0.3296365f, 0.4222632f), new Vector2(0.228889f, 0.4424127f), new Vector2(0.1537864f, 0.4909546f), new Vector2(0.09974916f, 0.5669732f), new Vector2(0.07502025f, 0.6723f), new Vector2(0.09333797f, 0.7712157f), new Vector2(0.1565341f, 0.8628042f), new Vector2(0.2325526f, 0.9113462f), new Vector2(0.3333f, 0.928748f), new Vector2(0.4422903f, 0.9040191f), new Vector2(0.5183089f, 0.8454024f), new Vector2(0.5668508f, 0.7666363f), new Vector2(0.5824209f, 0.6723f), new Vector2(0.5595237f, 0.567889f), new Vector2(0.5082341f, 0.4937023f), new Vector2(0.4285521f, 0.4433286f), new Vector2(0.3296365f, 0.4222632f) }, new Vector3[] { new Vector2(0.9166667f, 0.1601307f), new Vector2(0.8937908f, 0.1062092f), new Vector2(0.8415033f, 0.07843138f), new Vector2(0.5441176f, 0.377451f), new Vector2(0.5620915f, 0.4395425f), new Vector2(0.6209151f, 0.4575163f), new Vector2(0.9166667f, 0.1601307f) }, new Vector3[] { new Vector2(0.5620915f, 0.4362745f), new Vector2(0.5049019f, 0.4934641f) }, new Vector3[] { new Vector2(0.2222222f, 0.5326797f), new Vector2(0.1797386f, 0.5800654f), new Vector2(0.1535948f, 0.6323529f), new Vector2(0.1454248f, 0.6879085f), new Vector2(0.1568628f, 0.740196f), new Vector2(0.1830065f, 0.7843137f), new Vector2(0.2156863f, 0.8202614f) } }; } return icon_magnifier; } + Vector3[][] Icon_magnifierPlus() { if (icon_magnifierPlus == null) { icon_magnifierPlus = new Vector3[][] { new Vector3[] { new Vector2(0.3296365f, 0.4222632f), new Vector2(0.228889f, 0.4424127f), new Vector2(0.1537864f, 0.4909546f), new Vector2(0.09974916f, 0.5669732f), new Vector2(0.07502025f, 0.6723f), new Vector2(0.09333797f, 0.7712157f), new Vector2(0.1565341f, 0.8628042f), new Vector2(0.2325526f, 0.9113462f), new Vector2(0.3333f, 0.928748f), new Vector2(0.4422903f, 0.9040191f), new Vector2(0.5183089f, 0.8454024f), new Vector2(0.5668508f, 0.7666363f), new Vector2(0.5824209f, 0.6723f), new Vector2(0.5595237f, 0.567889f), new Vector2(0.5082341f, 0.4937023f), new Vector2(0.4285521f, 0.4433286f), new Vector2(0.3296365f, 0.4222632f) }, new Vector3[] { new Vector2(0.9166667f, 0.1601307f), new Vector2(0.8937908f, 0.1062092f), new Vector2(0.8415033f, 0.07843138f), new Vector2(0.5441176f, 0.377451f), new Vector2(0.5620915f, 0.4395425f), new Vector2(0.6209151f, 0.4575163f), new Vector2(0.9166667f, 0.1601307f) }, new Vector3[] { new Vector2(0.5620915f, 0.4362745f), new Vector2(0.5049019f, 0.4934641f) }, new Vector3[] { new Vector2(0.1846405f, 0.6764706f), new Vector2(0.4754902f, 0.6764706f) }, new Vector3[] { new Vector2(0.3316993f, 0.8218954f), new Vector2(0.3316993f, 0.5294118f) } }; } return icon_magnifierPlus; } + Vector3[][] Icon_magnifierMinus() { if (icon_magnifierMinus == null) { icon_magnifierMinus = new Vector3[][] { new Vector3[] { new Vector2(0.3296365f, 0.4222632f), new Vector2(0.228889f, 0.4424127f), new Vector2(0.1537864f, 0.4909546f), new Vector2(0.09974916f, 0.5669732f), new Vector2(0.07502025f, 0.6723f), new Vector2(0.09333797f, 0.7712157f), new Vector2(0.1565341f, 0.8628042f), new Vector2(0.2325526f, 0.9113462f), new Vector2(0.3333f, 0.928748f), new Vector2(0.4422903f, 0.9040191f), new Vector2(0.5183089f, 0.8454024f), new Vector2(0.5668508f, 0.7666363f), new Vector2(0.5824209f, 0.6723f), new Vector2(0.5595237f, 0.567889f), new Vector2(0.5082341f, 0.4937023f), new Vector2(0.4285521f, 0.4433286f), new Vector2(0.3296365f, 0.4222632f) }, new Vector3[] { new Vector2(0.9166667f, 0.1601307f), new Vector2(0.8937908f, 0.1062092f), new Vector2(0.8415033f, 0.07843138f), new Vector2(0.5441176f, 0.377451f), new Vector2(0.5620915f, 0.4395425f), new Vector2(0.6209151f, 0.4575163f), new Vector2(0.9166667f, 0.1601307f) }, new Vector3[] { new Vector2(0.5620915f, 0.4362745f), new Vector2(0.5049019f, 0.4934641f) }, new Vector3[] { new Vector2(0.1846405f, 0.6764706f), new Vector2(0.4754902f, 0.6764706f) } }; } return icon_magnifierMinus; } + Vector3[][] Icon_timeHourglassCursor() { if (icon_timeHourglassCursor == null) { icon_timeHourglassCursor = new Vector3[][] { new Vector3[] { new Vector2(0.2075163f, 0.9493464f), new Vector2(0.7908497f, 0.9493464f), new Vector2(0.7908497f, 0.8709151f), new Vector2(0.2091503f, 0.8709151f), new Vector2(0.2075163f, 0.9493464f) }, new Vector3[] { new Vector2(0.2124183f, 0.1437909f), new Vector2(0.7941176f, 0.1437909f), new Vector2(0.7941176f, 0.06372549f), new Vector2(0.2124183f, 0.06372549f), new Vector2(0.2124183f, 0.1437909f) }, new Vector3[] { new Vector2(0.2679739f, 0.8660131f), new Vector2(0.2712418f, 0.7777778f), new Vector2(0.2957516f, 0.7107843f), new Vector2(0.3447712f, 0.6421568f), new Vector2(0.3986928f, 0.5767974f), new Vector2(0.4411765f, 0.5343137f), new Vector2(0.4444444f, 0.4869281f), new Vector2(0.3954248f, 0.4395425f), new Vector2(0.3366013f, 0.374183f), new Vector2(0.2957516f, 0.3022876f), new Vector2(0.2745098f, 0.2140523f), new Vector2(0.2745098f, 0.1470588f) }, new Vector3[] { new Vector2(0.7222222f, 0.8692811f), new Vector2(0.7205882f, 0.7924837f), new Vector2(0.6911765f, 0.7107843f), new Vector2(0.6405229f, 0.6339869f), new Vector2(0.5882353f, 0.5784314f), new Vector2(0.5473856f, 0.5310457f), new Vector2(0.5473856f, 0.4820261f), new Vector2(0.6078432f, 0.4297386f), new Vector2(0.6617647f, 0.372549f), new Vector2(0.7026144f, 0.3071896f), new Vector2(0.7222222f, 0.2271242f), new Vector2(0.7254902f, 0.1454248f) }, new Vector3[] { new Vector2(0.3316993f, 0.2712418f), new Vector2(0.6699346f, 0.2712418f), new Vector2(0.6830065f, 0.1813726f), new Vector2(0.3186274f, 0.1813726f), new Vector2(0.3316993f, 0.2712418f) }, new Vector3[] { new Vector2(0.3823529f, 0.6797386f), new Vector2(0.496732f, 0.5653595f), new Vector2(0.6013072f, 0.6813725f), new Vector2(0.3823529f, 0.6813725f) } }; } return icon_timeHourglassCursor; } + Vector3[][] Icon_cursorHand() { if (icon_cursorHand == null) { icon_cursorHand = new Vector3[][] { new Vector3[] { new Vector2(0.8135948f, -0.3888889f), new Vector2(0.413268f, -0.3888889f), new Vector2(0.3969281f, -0.2712418f), new Vector2(0.3364706f, -0.1699346f), new Vector2(0.2613072f, -0.0653595f), new Vector2(0.1926797f, -0.01307189f), new Vector2(0.2188235f, 0.04738557f), new Vector2(0.2694771f, 0.06699347f), new Vector2(0.3217647f, 0.05718952f), new Vector2(0.3805882f, 0.02287579f), new Vector2(0.4394118f, -0.02941179f), new Vector2(0.4394118f, 0.4754902f), new Vector2(0.4639216f, 0.5f), new Vector2(0.5015033f, 0.52f), new Vector2(0.535817f, 0.5f), new Vector2(0.5652288f, 0.4460784f), new Vector2(0.5652288f, 0.07516342f) }, new Vector3[] { new Vector2(0.8135948f, -0.3872549f), new Vector2(0.8201307f, -0.3088235f), new Vector2(0.8707843f, -0.1781046f), new Vector2(0.9279737f, -0.1176471f), new Vector2(0.9475816f, -0.04411769f), new Vector2(0.9475816f, 0.1519608f), new Vector2(0.913268f, 0.2075163f), new Vector2(0.8479085f, 0.2075163f), new Vector2(0.8103268f, 0.1519608f) }, new Vector3[] { new Vector2(0.5668627f, 0.2303922f), new Vector2(0.5979085f, 0.2777778f), new Vector2(0.6534641f, 0.2777778f), new Vector2(0.6910456f, 0.2156863f), new Vector2(0.6910456f, 0.03431368f) }, new Vector3[] { new Vector2(0.6926796f, 0.2156863f), new Vector2(0.7204576f, 0.2614379f), new Vector2(0.787451f, 0.259804f), new Vector2(0.8086928f, 0.2303922f), new Vector2(0.8086928f, -0.006535888f) } }; } return icon_cursorHand; } + Vector3[][] Icon_cursorPointer() { if (icon_cursorPointer == null) { icon_cursorPointer = new Vector3[][] { new Vector3[] { new Vector2(0.5f, 0.4950981f), new Vector2(1.078431f, -0.0767974f), new Vector2(0.8169935f, -0.124183f), new Vector2(0.9330065f, -0.375817f), new Vector2(0.8186275f, -0.4297386f), new Vector2(0.7075163f, -0.1633987f), new Vector2(0.5f, -0.3022876f), new Vector2(0.5f, 0.4950981f) } }; } return icon_cursorPointer; } + Vector3[][] Icon_trashcan() { if (icon_trashcan == null) { icon_trashcan = new Vector3[][] { new Vector3[] { new Vector2(0.1633987f, 0.7794118f), new Vector2(0.2647059f, 0.8186275f), new Vector2(0.3807189f, 0.8447713f), new Vector2(0.5343137f, 0.8562092f), new Vector2(0.6748366f, 0.8447713f), new Vector2(0.8071895f, 0.8186275f), new Vector2(0.9084967f, 0.7777778f), new Vector2(0.9084967f, 0.740196f), new Vector2(0.1633987f, 0.740196f), new Vector2(0.1633987f, 0.7794118f) }, new Vector3[] { new Vector2(0.2124183f, 0.7369281f), new Vector2(0.3104575f, 0.06699347f), new Vector2(0.759804f, 0.06699347f), new Vector2(0.8578432f, 0.7385621f) }, new Vector3[] { new Vector2(0.4215686f, 0.8480392f), new Vector2(0.4215686f, 0.9052287f), new Vector2(0.4575163f, 0.9379085f), new Vector2(0.6192811f, 0.9379085f), new Vector2(0.6519608f, 0.8970588f), new Vector2(0.6519608f, 0.8464052f) }, new Vector3[] { new Vector2(0.5359477f, 0.1699346f), new Vector2(0.5359477f, 0.6519608f) }, new Vector3[] { new Vector2(0.6552287f, 0.1699346f), new Vector2(0.6960784f, 0.6503268f) }, new Vector3[] { new Vector2(0.4150327f, 0.1715686f), new Vector2(0.374183f, 0.6470588f) } }; } return icon_trashcan; } + Vector3[][] Icon_switchOnOff() { if (icon_switchOnOff == null) { icon_switchOnOff = new Vector3[][] { new Vector3[] { new Vector2(0.7349027f, 0.7637997f), new Vector2(0.8504868f, 0.647216f), new Vector2(0.9067466f, 0.5158696f), new Vector2(0.9105699f, 0.3668895f), new Vector2(0.8493953f, 0.2052008f), new Vector2(0.736874f, 0.09041098f), new Vector2(0.5713946f, 0.02536854f), new Vector2(0.4273166f, 0.02883014f), new Vector2(0.2782348f, 0.095633f), new Vector2(0.1558084f, 0.2256407f), new Vector2(0.1073216f, 0.3711601f), new Vector2(0.1132343f, 0.5188804f), new Vector2(0.1767464f, 0.657829f), new Vector2(0.2663399f, 0.7630719f), new Vector2(0.3088235f, 0.7761438f), new Vector2(0.3366013f, 0.759804f), new Vector2(0.3529412f, 0.7369281f), new Vector2(0.3513072f, 0.7075163f), new Vector2(0.3251634f, 0.6732026f), new Vector2(0.2581699f, 0.6094771f), new Vector2(0.2091503f, 0.5049019f), new Vector2(0.2107843f, 0.374183f), new Vector2(0.2565359f, 0.2696078f), new Vector2(0.3284314f, 0.1911765f), new Vector2(0.4379085f, 0.1437909f), new Vector2(0.5588235f, 0.1405229f), new Vector2(0.6650327f, 0.1846405f), new Vector2(0.740196f, 0.253268f), new Vector2(0.7990196f, 0.374183f), new Vector2(0.7957516f, 0.5049019f), new Vector2(0.751634f, 0.6045752f), new Vector2(0.6633987f, 0.6830065f), new Vector2(0.6503268f, 0.7091503f), new Vector2(0.6470588f, 0.7434641f), new Vector2(0.6715686f, 0.7712418f), new Vector2(0.7075163f, 0.7777778f), new Vector2(0.7349027f, 0.7637997f) }, new Vector3[] { new Vector2(0.4526144f, 0.9232026f), new Vector2(0.4526144f, 0.6111111f), new Vector2(0.4640523f, 0.5784314f), new Vector2(0.5f, 0.5620915f), new Vector2(0.5375817f, 0.5718954f), new Vector2(0.5522876f, 0.5980392f), new Vector2(0.5555556f, 0.6307189f), new Vector2(0.5555556f, 0.9248366f), new Vector2(0.5359477f, 0.9558824f), new Vector2(0.5065359f, 0.9640523f), new Vector2(0.4640523f, 0.9558824f), new Vector2(0.4526144f, 0.9232026f) } }; } return icon_switchOnOff; } + Vector3[][] Icon_playButton() { if (icon_playButton == null) { icon_playButton = new Vector3[][] { new Vector3[] { new Vector2(0.4984218f, 0.05103594f), new Vector2(0.3175205f, 0.0872162f), new Vector2(0.1826668f, 0.1743777f), new Vector2(0.08563793f, 0.310876f), new Vector2(0.04123488f, 0.5f), new Vector2(0.07412603f, 0.6776122f), new Vector2(0.1876005f, 0.8420679f), new Vector2(0.3240987f, 0.9292295f), new Vector2(0.505f, 0.960476f), new Vector2(0.7007022f, 0.916073f), new Vector2(0.8372006f, 0.8108213f), new Vector2(0.9243621f, 0.6693895f), new Vector2(0.9523196f, 0.5f), new Vector2(0.9112056f, 0.3125206f), new Vector2(0.8191104f, 0.1793114f), new Vector2(0.676034f, 0.08886078f), new Vector2(0.4984218f, 0.05103594f) }, new Vector3[] { new Vector2(0.3594771f, 0.7434641f), new Vector2(0.3594771f, 0.2434641f), new Vector2(0.7565359f, 0.496732f), new Vector2(0.3594771f, 0.7434641f) } }; } return icon_playButton; } + Vector3[][] Icon_pauseButton() { if (icon_pauseButton == null) { icon_pauseButton = new Vector3[][] { new Vector3[] { new Vector2(0.4984218f, 0.05103594f), new Vector2(0.3175205f, 0.0872162f), new Vector2(0.1826668f, 0.1743777f), new Vector2(0.08563793f, 0.310876f), new Vector2(0.04123488f, 0.5f), new Vector2(0.07412603f, 0.6776122f), new Vector2(0.1876005f, 0.8420679f), new Vector2(0.3240987f, 0.9292295f), new Vector2(0.505f, 0.960476f), new Vector2(0.7007022f, 0.916073f), new Vector2(0.8372006f, 0.8108213f), new Vector2(0.9243621f, 0.6693895f), new Vector2(0.9523196f, 0.5f), new Vector2(0.9112056f, 0.3125206f), new Vector2(0.8191104f, 0.1793114f), new Vector2(0.676034f, 0.08886078f), new Vector2(0.4984218f, 0.05103594f) }, new Vector3[] { new Vector2(0.2761438f, 0.7254902f), new Vector2(0.4444444f, 0.7254902f), new Vector2(0.4444444f, 0.2794118f), new Vector2(0.2761438f, 0.2794118f), new Vector2(0.2761438f, 0.7254902f) }, new Vector3[] { new Vector2(0.5588235f, 0.7238562f), new Vector2(0.7173203f, 0.7238562f), new Vector2(0.7173203f, 0.2777778f), new Vector2(0.5588235f, 0.2777778f), new Vector2(0.5588235f, 0.7238562f) } }; } return icon_pauseButton; } + Vector3[][] Icon_stopButton() { if (icon_stopButton == null) { icon_stopButton = new Vector3[][] { new Vector3[] { new Vector2(0.4984218f, 0.05103594f), new Vector2(0.3175205f, 0.0872162f), new Vector2(0.1826668f, 0.1743777f), new Vector2(0.08563793f, 0.310876f), new Vector2(0.04123488f, 0.5f), new Vector2(0.07412603f, 0.6776122f), new Vector2(0.1876005f, 0.8420679f), new Vector2(0.3240987f, 0.9292295f), new Vector2(0.505f, 0.960476f), new Vector2(0.7007022f, 0.916073f), new Vector2(0.8372006f, 0.8108213f), new Vector2(0.9243621f, 0.6693895f), new Vector2(0.9523196f, 0.5f), new Vector2(0.9112056f, 0.3125206f), new Vector2(0.8191104f, 0.1793114f), new Vector2(0.676034f, 0.08886078f), new Vector2(0.4984218f, 0.05103594f) }, new Vector3[] { new Vector2(0.2761438f, 0.2777778f), new Vector2(0.2761438f, 0.7254902f), new Vector2(0.7156863f, 0.7254902f), new Vector2(0.7156863f, 0.2777778f), new Vector2(0.2761438f, 0.2777778f) } }; } return icon_stopButton; } + Vector3[][] Icon_playPauseButton() { if (icon_playPauseButton == null) { icon_playPauseButton = new Vector3[][] { new Vector3[] { new Vector2(0.4984218f, 0.05103594f), new Vector2(0.3175205f, 0.0872162f), new Vector2(0.1826668f, 0.1743777f), new Vector2(0.08563793f, 0.310876f), new Vector2(0.04123488f, 0.5f), new Vector2(0.07412603f, 0.6776122f), new Vector2(0.1876005f, 0.8420679f), new Vector2(0.3240987f, 0.9292295f), new Vector2(0.505f, 0.960476f), new Vector2(0.7007022f, 0.916073f), new Vector2(0.8372006f, 0.8108213f), new Vector2(0.9243621f, 0.6693895f), new Vector2(0.9523196f, 0.5f), new Vector2(0.9112056f, 0.3125206f), new Vector2(0.8191104f, 0.1793114f), new Vector2(0.676034f, 0.08886078f), new Vector2(0.4984218f, 0.05103594f) }, new Vector3[] { new Vector2(0.2189543f, 0.6830065f), new Vector2(0.2189543f, 0.3218954f), new Vector2(0.4689542f, 0.5049019f), new Vector2(0.2189543f, 0.6830065f) }, new Vector3[] { new Vector2(0.5457516f, 0.6830065f), new Vector2(0.6323529f, 0.6830065f), new Vector2(0.6323529f, 0.3235294f), new Vector2(0.5457516f, 0.3235294f), new Vector2(0.5457516f, 0.6846405f) }, new Vector3[] { new Vector2(0.6781046f, 0.6813725f), new Vector2(0.7630719f, 0.6813725f), new Vector2(0.7630719f, 0.3235294f), new Vector2(0.6781046f, 0.3235294f), new Vector2(0.6781046f, 0.6830065f) } }; } return icon_playPauseButton; } + Vector3[][] Icon_heart() { if (icon_heart == null) { icon_heart = new Vector3[][] { new Vector3[] { new Vector2(0.501634f, 0.129085f), new Vector2(0.1127451f, 0.5147059f), new Vector2(0.07026144f, 0.5898693f), new Vector2(0.05718954f, 0.6879085f), new Vector2(0.08333334f, 0.7728758f), new Vector2(0.1405229f, 0.8447713f), new Vector2(0.2107843f, 0.8872549f), new Vector2(0.3039216f, 0.9019608f), new Vector2(0.3823529f, 0.8839869f), new Vector2(0.4330065f, 0.8529412f), new Vector2(0.4738562f, 0.8120915f), new Vector2(0.501634f, 0.7679738f), new Vector2(0.5506536f, 0.8382353f), new Vector2(0.6029412f, 0.872549f), new Vector2(0.6764706f, 0.8986928f), new Vector2(0.7679738f, 0.8970588f), new Vector2(0.8431373f, 0.8611111f), new Vector2(0.9035948f, 0.8022876f), new Vector2(0.9428105f, 0.7271242f), new Vector2(0.9444444f, 0.6372549f), new Vector2(0.9215686f, 0.5588235f), new Vector2(0.8709151f, 0.4918301f), new Vector2(0.501634f, 0.129085f) } }; } return icon_heart; } + Vector3[][] Icon_coin() { if (icon_coin == null) { icon_coin = new Vector3[][] { new Vector3[] { new Vector2(0.4977612f, 0.1414546f), new Vector2(0.3536953f, 0.1702678f), new Vector2(0.2463007f, 0.2396813f), new Vector2(0.169029f, 0.3483857f), new Vector2(0.1336673f, 0.499f), new Vector2(0.1598611f, 0.6404466f), new Vector2(0.2502298f, 0.7714156f), new Vector2(0.358934f, 0.8408293f), new Vector2(0.503f, 0.8657134f), new Vector2(0.6588531f, 0.8303517f), new Vector2(0.7675575f, 0.7465315f), new Vector2(0.836971f, 0.6338982f), new Vector2(0.8592358f, 0.499f), new Vector2(0.8264935f, 0.3496954f), new Vector2(0.7531509f, 0.2436104f), new Vector2(0.6392078f, 0.1715775f), new Vector2(0.4977612f, 0.1414546f) }, new Vector3[] { new Vector2(0.4974829f, 0.05820844f), new Vector2(0.3182628f, 0.0940524f), new Vector2(0.1846624f, 0.1804039f), new Vector2(0.08853531f, 0.3156337f), new Vector2(0.04454491f, 0.503f), new Vector2(0.07713038f, 0.6789616f), new Vector2(0.1895502f, 0.8418889f), new Vector2(0.3247799f, 0.9282404f), new Vector2(0.504f, 0.9591966f), new Vector2(0.6978835f, 0.9152062f), new Vector2(0.8331133f, 0.8109328f), new Vector2(0.9194647f, 0.6708152f), new Vector2(0.9471624f, 0.503f), new Vector2(0.9064305f, 0.3172629f), new Vector2(0.8151912f, 0.1852918f), new Vector2(0.6734444f, 0.09568173f), new Vector2(0.4974829f, 0.05820844f) }, new Vector3[] { new Vector2(0.6226891f, 0.5983194f), new Vector2(0.5689076f, 0.6453782f), new Vector2(0.5184874f, 0.6605042f), new Vector2(0.4596639f, 0.6621849f), new Vector2(0.4193277f, 0.6336135f), new Vector2(0.4092437f, 0.594958f), new Vector2(0.4260504f, 0.5462185f), new Vector2(0.4596639f, 0.5142857f), new Vector2(0.5487395f, 0.4605042f), new Vector2(0.5756302f, 0.4268908f), new Vector2(0.5773109f, 0.3781513f), new Vector2(0.5537815f, 0.3445378f), new Vector2(0.515126f, 0.3243698f), new Vector2(0.4630252f, 0.3294118f), new Vector2(0.412605f, 0.3529412f), new Vector2(0.3773109f, 0.3932773f) }, new Vector3[] { new Vector2(0.5f, 0.3243698f), new Vector2(0.5f, 0.2184874f) }, new Vector3[] { new Vector2(0.494958f, 0.6638656f), new Vector2(0.494958f, 0.7731093f) } }; } return icon_coin; } + Vector3[][] Icon_coins() { if (icon_coins == null) { icon_coins = new Vector3[][] { new Vector3[] { new Vector2(0.0671406f, 0.3270142f), new Vector2(0.05608215f, 0.3649289f), new Vector2(0.0592417f, 0.4344392f), new Vector2(0.09873617f, 0.5371248f), new Vector2(0.1524487f, 0.6366509f), new Vector2(0.2093207f, 0.7172196f), new Vector2(0.2646129f, 0.7740916f), new Vector2(0.3167457f, 0.7977883f), new Vector2(0.3388626f, 0.8041074f), new Vector2(0.3546604f, 0.7883096f), new Vector2(0.3609795f, 0.7598736f), new Vector2(0.3562401f, 0.7109005f), new Vector2(0.3372828f, 0.6413902f), new Vector2(0.2835703f, 0.5229068f), new Vector2(0.2251185f, 0.4296998f), new Vector2(0.1619273f, 0.3649289f), new Vector2(0.1192733f, 0.3333333f), new Vector2(0.08135861f, 0.3206951f), new Vector2(0.0671406f, 0.3270142f) }, new Vector3[] { new Vector2(0.07503949f, 0.3238547f), new Vector2(0.157188f, 0.28594f), new Vector2(0.1777251f, 0.2890995f), new Vector2(0.2219589f, 0.3080569f), new Vector2(0.2740916f, 0.3522907f), new Vector2(0.3246445f, 0.4091627f), new Vector2(0.3736177f, 0.4818325f), new Vector2(0.4099526f, 0.5545024f), new Vector2(0.4320695f, 0.6240126f), new Vector2(0.4383886f, 0.685624f), new Vector2(0.4273302f, 0.7456556f), new Vector2(0.3404423f, 0.7993681f) }, new Vector3[] { new Vector2(0.4194313f, 0.586098f), new Vector2(0.471564f, 0.5703002f), new Vector2(0.5742496f, 0.5608215f), new Vector2(0.6753554f, 0.5624012f), new Vector2(0.7496051f, 0.5718799f), new Vector2(0.8080569f, 0.5892575f), new Vector2(0.8349131f, 0.6097946f), new Vector2(0.8412322f, 0.6350711f), new Vector2(0.8238547f, 0.6603476f), new Vector2(0.7827804f, 0.685624f), new Vector2(0.7053713f, 0.6982622f), new Vector2(0.6058452f, 0.7077409f), new Vector2(0.4889416f, 0.7014218f), new Vector2(0.4368089f, 0.6919431f) }, new Vector3[] { new Vector2(0.378357f, 0.4913112f), new Vector2(0.4241706f, 0.4707741f), new Vector2(0.4905213f, 0.4565561f), new Vector2(0.57109f, 0.4518167f), new Vector2(0.6627172f, 0.4533965f), new Vector2(0.7480253f, 0.4660348f), new Vector2(0.7954186f, 0.4834123f), new Vector2(0.8317536f, 0.5023696f), new Vector2(0.8412322f, 0.5276461f) }, new Vector3[] { new Vector2(0.8396524f, 0.6319115f), new Vector2(0.8396524f, 0.2906793f), new Vector2(0.8270142f, 0.2733018f), new Vector2(0.7985782f, 0.2527646f), new Vector2(0.7306477f, 0.2290679f), new Vector2(0.650079f, 0.2180095f), new Vector2(0.5505529f, 0.2164297f), new Vector2(0.457346f, 0.2274881f), new Vector2(0.3846762f, 0.257504f), new Vector2(0.3325434f, 0.300158f), new Vector2(0.3230648f, 0.3238547f), new Vector2(0.3230648f, 0.4075829f) }, new Vector3[] { new Vector2(0.3388626f, 0.4296998f), new Vector2(0.3467615f, 0.4060031f), new Vector2(0.3720379f, 0.3759874f), new Vector2(0.4273302f, 0.3507109f), new Vector2(0.514218f, 0.3333333f), new Vector2(0.6169037f, 0.3254344f), new Vector2(0.7053713f, 0.3333333f), new Vector2(0.7875198f, 0.3522907f), new Vector2(0.8175355f, 0.3680885f), new Vector2(0.8380727f, 0.3981043f) } }; } return icon_coins; } + Vector3[][] Icon_moneyBills() { if (icon_moneyBills == null) { icon_moneyBills = new Vector3[][] { new Vector3[] { new Vector2(0.2234043f, 0.5159575f), new Vector2(0.2624114f, 0.535461f), new Vector2(0.2925532f, 0.5638298f), new Vector2(0.3085106f, 0.5886525f), new Vector2(0.3173759f, 0.6223404f), new Vector2(0.8049645f, 0.6223404f), new Vector2(0.8173759f, 0.5797873f), new Vector2(0.8421986f, 0.5478724f), new Vector2(0.8705674f, 0.5248227f), new Vector2(0.9024823f, 0.5124114f), new Vector2(0.9024823f, 0.3812057f), new Vector2(0.8705674f, 0.3705674f), new Vector2(0.8421986f, 0.3492908f), new Vector2(0.819149f, 0.3191489f), new Vector2(0.8031915f, 0.2730497f), new Vector2(0.3244681f, 0.2730497f), new Vector2(0.3102837f, 0.3120568f), new Vector2(0.2836879f, 0.3510638f), new Vector2(0.2535461f, 0.3723404f), new Vector2(0.2198582f, 0.3847518f), new Vector2(0.2198582f, 0.5195035f) }, new Vector3[] { new Vector2(0.5696161f, 0.3376006f), new Vector2(0.5260596f, 0.346312f), new Vector2(0.4935902f, 0.3672983f), new Vector2(0.4702281f, 0.4001637f), new Vector2(0.4595369f, 0.4457f), new Vector2(0.4674563f, 0.4884646f), new Vector2(0.4947781f, 0.5280614f), new Vector2(0.5276435f, 0.5490477f), new Vector2(0.5712f, 0.5565711f), new Vector2(0.6183202f, 0.54588f), new Vector2(0.6511856f, 0.520538f), new Vector2(0.672172f, 0.4864847f), new Vector2(0.6789034f, 0.4457f), new Vector2(0.6690042f, 0.4005596f), new Vector2(0.64683f, 0.3684862f), new Vector2(0.6123807f, 0.3467079f), new Vector2(0.5696161f, 0.3376006f) }, new Vector3[] { new Vector2(0.9485816f, 0.6595744f), new Vector2(0.9485816f, 0.2340426f), new Vector2(0.1702128f, 0.2340426f), new Vector2(0.1702128f, 0.6595744f), new Vector2(0.9485816f, 0.6595744f) }, new Vector3[] { new Vector2(0.1702128f, 0.2358156f), new Vector2(0.09219858f, 0.6542553f), new Vector2(0.8368794f, 0.819149f), new Vector2(0.8652482f, 0.6613475f) }, new Vector3[] { new Vector2(0.1684397f, 0.2340426f), new Vector2(0.01241135f, 0.6347518f), new Vector2(0.7234042f, 0.9237589f), new Vector2(0.7641844f, 0.8067376f) } }; } return icon_moneyBills; } + Vector3[][] Icon_moneyBag() { if (icon_moneyBag == null) { icon_moneyBag = new Vector3[][] { new Vector3[] { new Vector2(0.4379432f, 0.7907801f), new Vector2(0.6099291f, 0.7907801f), new Vector2(0.7340425f, 0.6702127f), new Vector2(0.8475177f, 0.5177305f), new Vector2(0.9042553f, 0.4007092f), new Vector2(0.9202127f, 0.2429078f), new Vector2(0.8882979f, 0.1312057f), new Vector2(0.8351064f, 0.08687943f), new Vector2(0.7375886f, 0.07269503f), new Vector2(0.3031915f, 0.07269503f), new Vector2(0.2092199f, 0.08687943f), new Vector2(0.1507092f, 0.1294326f), new Vector2(0.1223404f, 0.2216312f), new Vector2(0.1187943f, 0.3280142f), new Vector2(0.1453901f, 0.4379432f), new Vector2(0.2198582f, 0.569149f), new Vector2(0.3138298f, 0.6897163f), new Vector2(0.3723404f, 0.7553192f), new Vector2(0.4379432f, 0.7907801f) }, new Vector3[] { new Vector2(0.4379432f, 0.8138298f), new Vector2(0.6010638f, 0.8138298f), new Vector2(0.6968085f, 0.9432624f), new Vector2(0.3546099f, 0.9432624f), new Vector2(0.4379432f, 0.8138298f) }, new Vector3[] { new Vector2(0.6099291f, 0.5f), new Vector2(0.5762411f, 0.5248227f), new Vector2(0.5336879f, 0.5425532f), new Vector2(0.4858156f, 0.5390071f), new Vector2(0.4485815f, 0.5195035f), new Vector2(0.4414894f, 0.4893617f), new Vector2(0.4521277f, 0.4574468f), new Vector2(0.4840426f, 0.4255319f), new Vector2(0.5656028f, 0.3812057f), new Vector2(0.5762411f, 0.356383f), new Vector2(0.5762411f, 0.320922f), new Vector2(0.5585107f, 0.2890071f), new Vector2(0.5230497f, 0.2765957f), new Vector2(0.4804965f, 0.2801418f), new Vector2(0.4503546f, 0.2925532f), new Vector2(0.4219858f, 0.3244681f) }, new Vector3[] { new Vector2(0.5124114f, 0.5425532f), new Vector2(0.5124114f, 0.643617f) }, new Vector3[] { new Vector2(0.5159575f, 0.2783688f), new Vector2(0.5159575f, 0.1737589f) } }; } return icon_moneyBag; } + Vector3[][] Icon_chestTreasureBox_closed() { if (icon_chestTreasureBox_closed == null) { icon_chestTreasureBox_closed = new Vector3[][] { new Vector3[] { new Vector2(0.320922f, 0.6489362f), new Vector2(0.320922f, 0.5177305f), new Vector2(0.4343972f, 0.4929078f), new Vector2(0.4343972f, 0.6294326f), new Vector2(0.320922f, 0.6489362f) }, new Vector3[] { new Vector2(0.6613475f, 0.07092199f), new Vector2(0.6613475f, 0.5319149f), new Vector2(0.6719858f, 0.6347518f), new Vector2(0.6968085f, 0.7234042f), new Vector2(0.7287234f, 0.7730497f), new Vector2(0.7677305f, 0.8156028f), new Vector2(0.7960993f, 0.8386525f), new Vector2(0.8297873f, 0.8386525f), new Vector2(0.8546099f, 0.8262411f), new Vector2(0.8812057f, 0.7907801f), new Vector2(0.9042553f, 0.7429078f), new Vector2(0.9166667f, 0.6897163f), new Vector2(0.9202127f, 0.6205674f), new Vector2(0.9202127f, 0.2553191f), new Vector2(0.6613475f, 0.07092199f) }, new Vector3[] { new Vector2(0.6613475f, 0.07092199f), new Vector2(0.08687943f, 0.2588652f), new Vector2(0.08687943f, 0.6595744f), new Vector2(0.09397163f, 0.7198582f), new Vector2(0.1152482f, 0.7748227f), new Vector2(0.1453901f, 0.8280142f), new Vector2(0.1719858f, 0.8634752f), new Vector2(0.2039007f, 0.8847518f), new Vector2(0.2393617f, 0.8989362f), new Vector2(0.2677305f, 0.9024823f), new Vector2(0.285461f, 0.8989362f), new Vector2(0.2960993f, 0.8847518f) }, new Vector3[] { new Vector2(0.4840426f, 0.1258865f), new Vector2(0.4840426f, 0.5886525f), new Vector2(0.5f, 0.6666667f), new Vector2(0.5283688f, 0.7340425f), new Vector2(0.5602837f, 0.7801418f), new Vector2(0.5992908f, 0.819149f), new Vector2(0.6471631f, 0.8492908f), new Vector2(0.6843972f, 0.858156f), new Vector2(0.7074468f, 0.8546099f), new Vector2(0.7216312f, 0.8439716f) }, new Vector3[] { new Vector2(0.248227f, 0.2056738f), new Vector2(0.248227f, 0.608156f), new Vector2(0.2606383f, 0.6826241f), new Vector2(0.2836879f, 0.7517731f), new Vector2(0.3138298f, 0.7996454f), new Vector2(0.3439716f, 0.8351064f), new Vector2(0.3794326f, 0.8670213f), new Vector2(0.4131206f, 0.8812057f), new Vector2(0.4414894f, 0.8829787f), new Vector2(0.4592199f, 0.8794326f), new Vector2(0.4680851f, 0.8687943f) }, new Vector3[] { new Vector2(0.2180851f, 0.893617f), new Vector2(0.7960993f, 0.8368794f) }, new Vector3[] { new Vector2(0.4379432f, 0.535461f), new Vector2(0.6648936f, 0.4840426f), new Vector2(0.9202127f, 0.6117021f) }, new Vector3[] { new Vector2(0.4361702f, 0.5762411f), new Vector2(0.6631206f, 0.5265958f), new Vector2(0.9184397f, 0.6507092f) }, new Vector3[] { new Vector2(0.320922f, 0.5975177f), new Vector2(0.08687943f, 0.6507092f) }, new Vector3[] { new Vector2(0.3191489f, 0.5585107f), new Vector2(0.08687943f, 0.6117021f) }, new Vector3[] { new Vector2(0.3776596f, 0.5975177f), new Vector2(0.3776596f, 0.5407801f) } }; } return icon_chestTreasureBox_closed; } + Vector3[][] Icon_lootbox() { if (icon_lootbox == null) { icon_lootbox = new Vector3[][] { new Vector3[] { new Vector2(0.2777778f, 0.8529412f), new Vector2(0.2777778f, 0.1748366f), new Vector2(0.3676471f, 0.1748366f), new Vector2(0.3676471f, 0.8513072f), new Vector2(0.2777778f, 0.8529412f) }, new Vector3[] { new Vector2(0.6372549f, 0.8464052f), new Vector2(0.6372549f, 0.1748366f), new Vector2(0.7254902f, 0.1748366f), new Vector2(0.7254902f, 0.8513072f), new Vector2(0.6372549f, 0.8464052f) }, new Vector3[] { new Vector2(0.4166667f, 0.5833333f), new Vector2(0.5849673f, 0.5833333f), new Vector2(0.5849673f, 0.4150327f), new Vector2(0.4166667f, 0.4150327f), new Vector2(0.4166667f, 0.5833333f) }, new Vector3[] { new Vector2(0.2794118f, 0.5294118f), new Vector2(0.0751634f, 0.5294118f), new Vector2(0.0751634f, 0.4722222f), new Vector2(0.2777778f, 0.4722222f) }, new Vector3[] { new Vector2(0.7254902f, 0.5294118f), new Vector2(0.9183006f, 0.5294118f), new Vector2(0.9183006f, 0.4705882f), new Vector2(0.7271242f, 0.4705882f) }, new Vector3[] { new Vector2(0.372549f, 0.8202614f), new Vector2(0.4035948f, 0.877451f), new Vector2(0.5947713f, 0.877451f), new Vector2(0.6372549f, 0.8055556f) }, new Vector3[] { new Vector2(0.3937908f, 0.7941176f), new Vector2(0.6029412f, 0.7941176f), new Vector2(0.5751634f, 0.8447713f), new Vector2(0.4232026f, 0.8447713f), new Vector2(0.3937908f, 0.7941176f) }, new Vector3[] { new Vector2(0.2761438f, 0.7892157f), new Vector2(0.1911765f, 0.7892157f), new Vector2(0.1127451f, 0.5310457f) }, new Vector3[] { new Vector2(0.2777778f, 0.2107843f), new Vector2(0.1911765f, 0.2107843f), new Vector2(0.1127451f, 0.4705882f) }, new Vector3[] { new Vector2(0.3692811f, 0.2124183f), new Vector2(0.6372549f, 0.2124183f) }, new Vector3[] { new Vector2(0.7271242f, 0.2173203f), new Vector2(0.8022876f, 0.2173203f), new Vector2(0.8823529f, 0.4673203f) }, new Vector3[] { new Vector2(0.7254902f, 0.7908497f), new Vector2(0.8006536f, 0.7908497f), new Vector2(0.8839869f, 0.5294118f) }, new Vector3[] { new Vector2(0.4542484f, 0.4624183f), new Vector2(0.5441176f, 0.4624183f) }, new Vector3[] { new Vector2(0.498366f, 0.4607843f), new Vector2(0.498366f, 0.5424837f) }, new Vector3[] { new Vector2(0.3676471f, 0.5294118f), new Vector2(0.4166667f, 0.5294118f) }, new Vector3[] { new Vector2(0.3676471f, 0.4705882f), new Vector2(0.4150327f, 0.4705882f) }, new Vector3[] { new Vector2(0.6372549f, 0.5261438f), new Vector2(0.5833333f, 0.5261438f) }, new Vector3[] { new Vector2(0.6372549f, 0.4689542f), new Vector2(0.5833333f, 0.4689542f) } }; } return icon_lootbox; } + Vector3[][] Icon_crown() { if (icon_crown == null) { icon_crown = new Vector3[][] { new Vector3[] { new Vector2(0.5028f, 0.117123f), new Vector2(0.4456886f, 0.1408033f), new Vector2(0.4231227f, 0.1929f), new Vector2(0.4448529f, 0.2475041f), new Vector2(0.501407f, 0.2717415f), new Vector2(0.5560111f, 0.2500114f), new Vector2(0.5780199f, 0.1926214f), new Vector2(0.5557325f, 0.138296f), new Vector2(0.5028f, 0.117123f) }, new Vector3[] { new Vector2(0.7322695f, 0.2748227f), new Vector2(0.7677305f, 0.2624114f), new Vector2(0.7943262f, 0.2216312f), new Vector2(0.7960993f, 0.1861702f), new Vector2(0.7801418f, 0.1507092f), new Vector2(0.7624114f, 0.1294326f), new Vector2(0.7287234f, 0.1205674f), new Vector2(0.6914893f, 0.1400709f), new Vector2(0.6719858f, 0.179078f), new Vector2(0.6737589f, 0.2251773f), new Vector2(0.6985816f, 0.2606383f), new Vector2(0.7322695f, 0.2748227f) }, new Vector3[] { new Vector2(0.2712766f, 0.2748227f), new Vector2(0.3049645f, 0.2606383f), new Vector2(0.3244681f, 0.2411347f), new Vector2(0.3368794f, 0.2074468f), new Vector2(0.3351064f, 0.1755319f), new Vector2(0.3173759f, 0.1471631f), new Vector2(0.2960993f, 0.1241135f), new Vector2(0.2641844f, 0.1187943f), new Vector2(0.2287234f, 0.1365248f), new Vector2(0.212766f, 0.1826241f), new Vector2(0.2163121f, 0.2304965f), new Vector2(0.2411347f, 0.2606383f), new Vector2(0.2712766f, 0.2748227f) }, new Vector3[] { new Vector2(0.1329787f, 0.3156028f), new Vector2(0.1329787f, 0.07978723f), new Vector2(0.8599291f, 0.07978723f), new Vector2(0.8599291f, 0.3156028f), new Vector2(0.1329787f, 0.3156028f), new Vector2(0.05496454f, 0.8634752f), new Vector2(0.3404255f, 0.5975177f), new Vector2(0.5f, 0.9007092f), new Vector2(0.6595744f, 0.5992908f), new Vector2(0.9379433f, 0.858156f), new Vector2(0.858156f, 0.3138298f) } }; } return icon_crown; } + Vector3[][] Icon_trophy() { if (icon_trophy == null) { icon_trophy = new Vector3[][] { new Vector3[] { new Vector2(0.2259259f, 0.9518518f), new Vector2(0.7740741f, 0.9518518f), new Vector2(0.7462963f, 0.7611111f), new Vector2(0.6981481f, 0.587037f), new Vector2(0.6462963f, 0.4925926f), new Vector2(0.6018519f, 0.4314815f), new Vector2(0.5537037f, 0.4f), new Vector2(0.5037037f, 0.387037f), new Vector2(0.4481482f, 0.3981481f), new Vector2(0.3981481f, 0.4296296f), new Vector2(0.3351852f, 0.5166667f), new Vector2(0.2796296f, 0.65f), new Vector2(0.2388889f, 0.7962963f), new Vector2(0.2259259f, 0.9518518f) }, new Vector3[] { new Vector2(0.7611111f, 0.8481482f), new Vector2(0.9f, 0.8481482f), new Vector2(0.8925926f, 0.7592593f), new Vector2(0.8574074f, 0.6740741f), new Vector2(0.8111111f, 0.6f), new Vector2(0.7666667f, 0.55f), new Vector2(0.712963f, 0.5277778f), new Vector2(0.6685185f, 0.5296296f) }, new Vector3[] { new Vector2(0.2333333f, 0.8444445f), new Vector2(0.09814814f, 0.8444445f), new Vector2(0.1055556f, 0.7574074f), new Vector2(0.1462963f, 0.6574074f), new Vector2(0.2018518f, 0.5796296f), new Vector2(0.2555556f, 0.5388889f), new Vector2(0.2907407f, 0.5296296f), new Vector2(0.3314815f, 0.5277778f) }, new Vector3[] { new Vector2(0.2722222f, 0.1425926f), new Vector2(0.7240741f, 0.1425926f), new Vector2(0.7240741f, 0.03888889f), new Vector2(0.2722222f, 0.03888889f), new Vector2(0.2722222f, 0.1462963f) }, new Vector3[] { new Vector2(0.3111111f, 0.1444445f), new Vector2(0.3537037f, 0.1611111f), new Vector2(0.3981481f, 0.212963f), new Vector2(0.4222222f, 0.2722222f), new Vector2(0.4425926f, 0.3425926f), new Vector2(0.45f, 0.3962963f) }, new Vector3[] { new Vector2(0.6851852f, 0.1425926f), new Vector2(0.6277778f, 0.1703704f), new Vector2(0.587037f, 0.2333333f), new Vector2(0.5574074f, 0.3148148f), new Vector2(0.5481482f, 0.3962963f) } }; } return icon_trophy; } + Vector3[][] Icon_awardMedal() { if (icon_awardMedal == null) { icon_awardMedal = new Vector3[][] { new Vector3[] { new Vector2(0.497568f, 0.4011138f), new Vector2(0.4086871f, 0.4188899f), new Vector2(0.3424304f, 0.4617144f), new Vector2(0.294758f, 0.5287791f), new Vector2(0.2729417f, 0.6217f), new Vector2(0.2891019f, 0.7089649f), new Vector2(0.3448544f, 0.7897657f), new Vector2(0.4119191f, 0.8325902f), new Vector2(0.5008f, 0.8479423f), new Vector2(0.5969529f, 0.8261261f), new Vector2(0.6640177f, 0.7744135f), new Vector2(0.7068421f, 0.7049249f), new Vector2(0.7205783f, 0.6217f), new Vector2(0.700378f, 0.5295871f), new Vector2(0.6551296f, 0.4641384f), new Vector2(0.5848328f, 0.419698f), new Vector2(0.497568f, 0.4011138f) }, new Vector3[] { new Vector2(0.4929577f, 0.2869718f), new Vector2(0.5721831f, 0.3626761f), new Vector2(0.681338f, 0.3433098f), new Vector2(0.6954225f, 0.4295775f), new Vector2(0.7887324f, 0.4542254f), new Vector2(0.7623239f, 0.5616197f), new Vector2(0.8327465f, 0.6302817f), new Vector2(0.7658451f, 0.7024648f), new Vector2(0.7922535f, 0.7957746f), new Vector2(0.693662f, 0.818662f), new Vector2(0.6637324f, 0.9242958f), new Vector2(0.5757042f, 0.8908451f), new Vector2(0.4964789f, 0.9665493f), new Vector2(0.4278169f, 0.8943662f), new Vector2(0.3309859f, 0.9172535f), new Vector2(0.3045775f, 0.8204225f), new Vector2(0.2112676f, 0.8045775f), new Vector2(0.2271127f, 0.6919014f), new Vector2(0.1619718f, 0.6232395f), new Vector2(0.2306338f, 0.540493f), new Vector2(0.2112676f, 0.4507042f), new Vector2(0.306338f, 0.4295775f), new Vector2(0.3274648f, 0.3327465f), new Vector2(0.4260563f, 0.3626761f), new Vector2(0.4929577f, 0.2869718f) }, new Vector3[] { new Vector2(0.3133803f, 0.3978873f), new Vector2(0.2341549f, 0.08626761f), new Vector2(0.3644366f, 0.1760563f), new Vector2(0.4295775f, 0.0334507f), new Vector2(0.4982394f, 0.290493f) }, new Vector3[] { new Vector2(0.4929577f, 0.2799296f), new Vector2(0.556338f, 0.03521127f), new Vector2(0.6285211f, 0.165493f), new Vector2(0.7658451f, 0.06514084f), new Vector2(0.6866197f, 0.3785211f) } }; } return icon_awardMedal; } + Vector3[][] Icon_sword() { if (icon_sword == null) { icon_sword = new Vector3[][] { new Vector3[] { new Vector2(0.2018518f, 0.4185185f), new Vector2(0.4185185f, 0.1981481f), new Vector2(0.3888889f, 0.1685185f), new Vector2(0.1740741f, 0.3833333f), new Vector2(0.2018518f, 0.4185185f) }, new Vector3[] { new Vector2(0.07037037f, 0.2092593f), new Vector2(0.2074074f, 0.07037037f), new Vector2(0.1685185f, 0.03518518f), new Vector2(0.03888889f, 0.1685185f), new Vector2(0.07037037f, 0.2092593f) }, new Vector3[] { new Vector2(0.2555556f, 0.3703704f), new Vector2(0.7407407f, 0.85f), new Vector2(0.9388889f, 0.9296296f), new Vector2(0.85f, 0.7314815f), new Vector2(0.3685185f, 0.2518519f) }, new Vector3[] { new Vector2(0.1092593f, 0.1740741f), new Vector2(0.2481481f, 0.3074074f) }, new Vector3[] { new Vector2(0.1759259f, 0.1055556f), new Vector2(0.3166667f, 0.2407407f) }, new Vector3[] { new Vector2(0.3111111f, 0.3111111f), new Vector2(0.8333333f, 0.8314815f) } }; } return icon_sword; } + Vector3[][] Icon_shield() { if (icon_shield == null) { icon_shield = new Vector3[][] { new Vector3[] { new Vector2(0.2592593f, 0.8981481f), new Vector2(0.7333333f, 0.8981481f), new Vector2(0.7407407f, 0.8407407f), new Vector2(0.7703704f, 0.7925926f), new Vector2(0.8092592f, 0.7629629f), new Vector2(0.8592592f, 0.7425926f), new Vector2(0.9055555f, 0.7370371f), new Vector2(0.887037f, 0.4462963f), new Vector2(0.8611111f, 0.337037f), new Vector2(0.7981482f, 0.2259259f), new Vector2(0.6907408f, 0.1240741f), new Vector2(0.5f, 0.04629629f), new Vector2(0.3203704f, 0.1166667f), new Vector2(0.1944444f, 0.2277778f), new Vector2(0.1351852f, 0.3407407f), new Vector2(0.1074074f, 0.5222222f), new Vector2(0.09259259f, 0.7444444f), new Vector2(0.1351852f, 0.7518519f), new Vector2(0.1833333f, 0.7740741f), new Vector2(0.2277778f, 0.8092592f), new Vector2(0.2481481f, 0.85f), new Vector2(0.2592593f, 0.8981481f) }, new Vector3[] { new Vector2(0.3555556f, 0.7851852f), new Vector2(0.6462963f, 0.7851852f), new Vector2(0.6574074f, 0.7296296f), new Vector2(0.6907408f, 0.6888889f), new Vector2(0.7333333f, 0.6592593f), new Vector2(0.7796296f, 0.6425926f), new Vector2(0.7703704f, 0.5f), new Vector2(0.7444444f, 0.3740741f), new Vector2(0.7074074f, 0.3018518f), new Vector2(0.6277778f, 0.237037f), new Vector2(0.5f, 0.1703704f), new Vector2(0.3796296f, 0.2203704f), new Vector2(0.2833333f, 0.3111111f), new Vector2(0.2388889f, 0.4111111f), new Vector2(0.2185185f, 0.5277778f), new Vector2(0.2111111f, 0.6537037f), new Vector2(0.2555556f, 0.6611111f), new Vector2(0.3018518f, 0.6888889f), new Vector2(0.3333333f, 0.7277778f), new Vector2(0.3555556f, 0.7851852f) }, new Vector3[] { new Vector2(0.4981481f, 0.1703704f), new Vector2(0.4981481f, 0.7833334f) } }; } return icon_shield; } + Vector3[][] Icon_gun() { if (icon_gun == null) { icon_gun = new Vector3[][] { new Vector3[] { new Vector2(0.4185185f, 0.5166667f), new Vector2(0.637037f, 0.5166667f), new Vector2(0.6648148f, 0.5685185f), new Vector2(0.9055555f, 0.5685185f), new Vector2(0.9055555f, 0.6333333f), new Vector2(0.9388889f, 0.6333333f), new Vector2(0.9388889f, 0.7333333f), new Vector2(0.9f, 0.7333333f), new Vector2(0.8666667f, 0.7703704f), new Vector2(0.8314815f, 0.7333333f), new Vector2(0.2648148f, 0.7333333f), new Vector2(0.2277778f, 0.7722222f), new Vector2(0.1888889f, 0.7296296f), new Vector2(0.06666667f, 0.7296296f), new Vector2(0.06666667f, 0.6796296f), new Vector2(0.1166667f, 0.6351852f), new Vector2(0.1111111f, 0.5796296f), new Vector2(0.06851852f, 0.5796296f), new Vector2(0.06851852f, 0.5462963f), new Vector2(0.1f, 0.5388889f), new Vector2(0.1092593f, 0.5018519f), new Vector2(0.1055556f, 0.412963f), new Vector2(0.05925926f, 0.2888889f), new Vector2(0.05925926f, 0.2037037f), new Vector2(0.3111111f, 0.2037037f), new Vector2(0.4185185f, 0.5166667f) }, new Vector3[] { new Vector2(0.3851852f, 0.4166667f), new Vector2(0.5092593f, 0.4166667f), new Vector2(0.5444444f, 0.4370371f), new Vector2(0.5703704f, 0.4740741f), new Vector2(0.5759259f, 0.5166667f) }, new Vector3[] { new Vector2(0.4462963f, 0.5148148f), new Vector2(0.4518518f, 0.4722222f), new Vector2(0.4796296f, 0.4481482f) }, new Vector3[] { new Vector2(0.8351852f, 0.6444445f), new Vector2(0.4462963f, 0.6444445f) } }; } return icon_gun; } + Vector3[][] Icon_bullet() { if (icon_bullet == null) { icon_bullet = new Vector3[][] { new Vector3[] { new Vector2(0.1148148f, 0.6574074f), new Vector2(0.1148148f, 0.3518519f), new Vector2(0.04814815f, 0.3518519f), new Vector2(0.04814815f, 0.6555555f), new Vector2(0.1148148f, 0.6555555f) }, new Vector3[] { new Vector2(0.1148148f, 0.6333333f), new Vector2(0.6888889f, 0.6333333f), new Vector2(0.6888889f, 0.3740741f), new Vector2(0.112963f, 0.3740741f) }, new Vector3[] { new Vector2(0.6907408f, 0.6055555f), new Vector2(0.7851852f, 0.6074074f), new Vector2(0.8481482f, 0.5925926f), new Vector2(0.9185185f, 0.5592592f), new Vector2(0.9481481f, 0.5222222f), new Vector2(0.9574074f, 0.5018519f), new Vector2(0.9407408f, 0.4703704f), new Vector2(0.8944445f, 0.4388889f), new Vector2(0.8314815f, 0.4111111f), new Vector2(0.7518519f, 0.3944444f), new Vector2(0.6888889f, 0.3944444f) } }; } return icon_bullet; } + Vector3[][] Icon_rocket() { if (icon_rocket == null) { icon_rocket = new Vector3[][] { new Vector3[] { new Vector2(0.4743178f, 0.2744783f), new Vector2(0.4390048f, 0.2487962f), new Vector2(0.4213483f, 0.2182986f), new Vector2(0.4197432f, 0.1573034f), new Vector2(0.453451f, 0.08507223f), new Vector2(0.5f, 0.006420546f), new Vector2(0.5481541f, 0.09470305f), new Vector2(0.5786517f, 0.1621188f), new Vector2(0.5786517f, 0.200642f), new Vector2(0.5658106f, 0.2359551f), new Vector2(0.5433387f, 0.2600321f), new Vector2(0.5176565f, 0.2744783f), new Vector2(0.5385233f, 0.247191f), new Vector2(0.5401284f, 0.2166934f), new Vector2(0.5272873f, 0.176565f), new Vector2(0.4983949f, 0.141252f), new Vector2(0.4662921f, 0.1861958f), new Vector2(0.4550562f, 0.2166934f), new Vector2(0.4566613f, 0.2455859f), new Vector2(0.4759229f, 0.2728732f) }, new Vector3[] { new Vector2(0.503f, 0.6394702f), new Vector2(0.4668765f, 0.6544483f), new Vector2(0.4526033f, 0.6874f), new Vector2(0.4663479f, 0.7219376f), new Vector2(0.5021189f, 0.7372681f), new Vector2(0.5366566f, 0.7235235f), new Vector2(0.5505773f, 0.6872238f), new Vector2(0.5364804f, 0.6528624f), new Vector2(0.503f, 0.6394702f) }, new Vector3[] { new Vector2(0.5016052f, 0.9919743f), new Vector2(0.581862f, 0.8057785f), new Vector2(0.5722311f, 0.3434992f), new Vector2(0.4245586f, 0.3434992f), new Vector2(0.4085072f, 0.8057785f), new Vector2(0.5016052f, 0.9919743f) }, new Vector3[] { new Vector2(0.4566613f, 0.3451043f), new Vector2(0.4325843f, 0.2728732f), new Vector2(0.5690209f, 0.2728732f), new Vector2(0.5433387f, 0.3451043f) }, new Vector3[] { new Vector2(0.5738363f, 0.4125201f), new Vector2(0.6813804f, 0.3515249f), new Vector2(0.6813804f, 0.4654896f), new Vector2(0.5770466f, 0.5922953f) }, new Vector3[] { new Vector2(0.4213483f, 0.4173355f), new Vector2(0.3202247f, 0.3547352f), new Vector2(0.3202247f, 0.4670947f), new Vector2(0.418138f, 0.5842696f) }, new Vector3[] { new Vector2(0.4085072f, 0.8073837f), new Vector2(0.581862f, 0.8073837f) } }; } return icon_rocket; } + Vector3[][] Icon_crosshair() { if (icon_crosshair == null) { icon_crosshair = new Vector3[][] { new Vector3[] { new Vector2(0.4964707f, 0.1216253f), new Vector2(0.3444149f, 0.1520364f), new Vector2(0.2310643f, 0.2252997f), new Vector2(0.1495071f, 0.3400327f), new Vector2(0.1121843f, 0.499f), new Vector2(0.1398308f, 0.6482912f), new Vector2(0.2352112f, 0.7865236f), new Vector2(0.3499442f, 0.8597869f), new Vector2(0.502f, 0.8860511f), new Vector2(0.6664966f, 0.8487283f), new Vector2(0.7812297f, 0.7602595f), new Vector2(0.8544929f, 0.6413796f), new Vector2(0.8779925f, 0.499f), new Vector2(0.8434343f, 0.341415f), new Vector2(0.7660241f, 0.2294466f), new Vector2(0.6457618f, 0.1534187f), new Vector2(0.4964707f, 0.1216253f) }, new Vector3[] { new Vector2(0.501f, 0.4098177f), new Vector2(0.4330317f, 0.4379997f), new Vector2(0.4061759f, 0.5f), new Vector2(0.4320371f, 0.5649843f), new Vector2(0.4993422f, 0.5938294f), new Vector2(0.5643265f, 0.5679682f), new Vector2(0.5905192f, 0.4996684f), new Vector2(0.563995f, 0.4350157f), new Vector2(0.501f, 0.4098177f) }, new Vector3[] { new Vector2(0.02407407f, 0.5055556f), new Vector2(0.2259259f, 0.5055556f) }, new Vector3[] { new Vector2(0.3481481f, 0.5018519f), new Vector2(0.65f, 0.5018519f) }, new Vector3[] { new Vector2(0.7666667f, 0.5018519f), new Vector2(0.9685185f, 0.5018519f) }, new Vector3[] { new Vector2(0.5f, 0.9777778f), new Vector2(0.5f, 0.7777778f) }, new Vector3[] { new Vector2(0.5f, 0.6518518f), new Vector2(0.5f, 0.3444445f) }, new Vector3[] { new Vector2(0.4981481f, 0.2296296f), new Vector2(0.4981481f, 0.02962963f) } }; } return icon_crosshair; } + Vector3[][] Icon_arrow() { if (icon_arrow == null) { icon_arrow = new Vector3[][] { new Vector3[] { new Vector2(0.7814815f, 0.5629629f), new Vector2(0.7814815f, 0.4388889f), new Vector2(0.9611111f, 0.5018519f), new Vector2(0.7814815f, 0.5629629f) }, new Vector3[] { new Vector2(0.9537037f, 0.5018519f), new Vector2(0.1055556f, 0.5018519f), new Vector2(0.04814815f, 0.5666667f), new Vector2(0.2592593f, 0.5666667f), new Vector2(0.3222222f, 0.5037037f), new Vector2(0.2518519f, 0.4222222f), new Vector2(0.04259259f, 0.4222222f), new Vector2(0.1037037f, 0.5018519f) } }; } return icon_arrow; } + Vector3[][] Icon_arrowBow() { if (icon_arrowBow == null) { icon_arrowBow = new Vector3[][] { new Vector3[] { new Vector2(0.8759259f, 0.4259259f), new Vector2(0.8759259f, 0.5740741f), new Vector2(0.9574074f, 0.5037037f), new Vector2(0.8759259f, 0.4259259f) }, new Vector3[] { new Vector2(0.95f, 0.5037037f), new Vector2(0.08148148f, 0.5037037f), new Vector2(0.03888889f, 0.5648148f), new Vector2(0.1944444f, 0.5648148f), new Vector2(0.2388889f, 0.5037037f), new Vector2(0.187037f, 0.4259259f), new Vector2(0.03148148f, 0.4259259f), new Vector2(0.08148148f, 0.5018519f) }, new Vector3[] { new Vector2(0.4611111f, 0.9703704f), new Vector2(0.5740741f, 0.9259259f), new Vector2(0.6703704f, 0.8555555f), new Vector2(0.7481481f, 0.7611111f), new Vector2(0.8018519f, 0.6537037f), new Vector2(0.8240741f, 0.5462963f), new Vector2(0.8203704f, 0.4240741f), new Vector2(0.7888889f, 0.3185185f), new Vector2(0.7351852f, 0.2240741f), new Vector2(0.6574074f, 0.137037f), new Vector2(0.5740741f, 0.07777778f), new Vector2(0.462963f, 0.04074074f) }, new Vector3[] { new Vector2(0.5222222f, 0.06111111f), new Vector2(0.337037f, 0.5055556f), new Vector2(0.5148148f, 0.9481481f) } }; } return icon_arrowBow; } + Vector3[][] Icon_bomb() { if (icon_bomb == null) { icon_bomb = new Vector3[][] { new Vector3[] { new Vector2(0.3073632f, 0.06078675f), new Vector2(0.2073505f, 0.08078927f), new Vector2(0.1327956f, 0.1289772f), new Vector2(0.07915244f, 0.2044413f), new Vector2(0.05460387f, 0.309f), new Vector2(0.072788f, 0.4071943f), new Vector2(0.1355232f, 0.4981149f), new Vector2(0.2109873f, 0.5463028f), new Vector2(0.311f, 0.5635777f), new Vector2(0.4191955f, 0.5390291f), new Vector2(0.4946597f, 0.48084f), new Vector2(0.5428475f, 0.4026483f), new Vector2(0.5583041f, 0.309f), new Vector2(0.5355739f, 0.2053505f), new Vector2(0.4846584f, 0.1317048f), new Vector2(0.4055574f, 0.08169849f), new Vector2(0.3073632f, 0.06078675f) }, new Vector3[] { new Vector2(0.2944444f, 0.5629629f), new Vector2(0.3333333f, 0.6796296f), new Vector2(0.4907407f, 0.6277778f), new Vector2(0.4518518f, 0.5166667f) }, new Vector3[] { new Vector2(0.412963f, 0.6537037f), new Vector2(0.4407407f, 0.7370371f), new Vector2(0.4851852f, 0.7925926f), new Vector2(0.5518519f, 0.8129629f), new Vector2(0.6222222f, 0.7888889f), new Vector2(0.6666667f, 0.7407407f), new Vector2(0.7185185f, 0.7277778f), new Vector2(0.7722222f, 0.7407407f), new Vector2(0.8203704f, 0.7814815f) }, new Vector3[] { new Vector2(0.7629629f, 0.7759259f), new Vector2(0.7018518f, 0.8166667f), new Vector2(0.7777778f, 0.8148148f), new Vector2(0.7907407f, 0.9055555f), new Vector2(0.8351852f, 0.837037f), new Vector2(0.9296296f, 0.8685185f), new Vector2(0.8722222f, 0.7925926f), new Vector2(0.9296296f, 0.7333333f), new Vector2(0.8462963f, 0.7444444f), new Vector2(0.8314815f, 0.6537037f), new Vector2(0.8f, 0.7425926f) } }; } return icon_bomb; } + Vector3[][] Icon_shovel() { if (icon_shovel == null) { icon_shovel = new Vector3[][] { new Vector3[] { new Vector2(0.2185185f, 0.4685185f), new Vector2(0.4722222f, 0.2074074f), new Vector2(0.3777778f, 0.1185185f), new Vector2(0.287037f, 0.06666667f), new Vector2(0.2092593f, 0.04259259f), new Vector2(0.1407407f, 0.05185185f), new Vector2(0.08518519f, 0.07222223f), new Vector2(0.06111111f, 0.1185185f), new Vector2(0.05f, 0.1907407f), new Vector2(0.06851852f, 0.2648148f), new Vector2(0.1166667f, 0.3611111f), new Vector2(0.2185185f, 0.4685185f) }, new Vector3[] { new Vector2(0.3203704f, 0.3685185f), new Vector2(0.7944444f, 0.8481482f), new Vector2(0.7259259f, 0.9185185f), new Vector2(0.7759259f, 0.9703704f), new Vector2(0.9740741f, 0.7759259f), new Vector2(0.9240741f, 0.7203704f), new Vector2(0.8537037f, 0.7907407f), new Vector2(0.3740741f, 0.3092593f) } }; } return icon_shovel; } + Vector3[][] Icon_hammer() { if (icon_hammer == null) { icon_hammer = new Vector3[][] { new Vector3[] { new Vector2(0.6055555f, 0.9703704f), new Vector2(0.7685185f, 0.8407407f), new Vector2(0.85f, 0.7592593f), new Vector2(0.962963f, 0.6055555f), new Vector2(0.8425926f, 0.4814815f), new Vector2(0.6907408f, 0.5981482f), new Vector2(0.6037037f, 0.6814815f), new Vector2(0.4777778f, 0.8425926f), new Vector2(0.6055555f, 0.9703704f) }, new Vector3[] { new Vector2(0.6037037f, 0.6796296f), new Vector2(0.04629629f, 0.1092593f), new Vector2(0.1148148f, 0.02777778f), new Vector2(0.6851852f, 0.6f) }, new Vector3[] { new Vector2(0.7703704f, 0.8444445f), new Vector2(0.7981482f, 0.8740741f), new Vector2(0.8740741f, 0.7962963f), new Vector2(0.8481482f, 0.7629629f) } }; } return icon_hammer; } + Vector3[][] Icon_axe() { if (icon_axe == null) { icon_axe = new Vector3[][] { new Vector3[] { new Vector2(0.5802568f, 0.6420546f), new Vector2(0.5176565f, 0.6741573f), new Vector2(0.4550562f, 0.6902087f), new Vector2(0.3988764f, 0.6886035f), new Vector2(0.3699839f, 0.6725522f), new Vector2(0.3715891f, 0.7399679f), new Vector2(0.3892456f, 0.8025682f), new Vector2(0.4197432f, 0.8571429f), new Vector2(0.4630819f, 0.9036918f), new Vector2(0.5160514f, 0.9325843f), new Vector2(0.5802568f, 0.9518459f), new Vector2(0.6492777f, 0.9518459f), new Vector2(0.6348315f, 0.8988764f), new Vector2(0.6380417f, 0.8378812f), new Vector2(0.6556982f, 0.7961476f), new Vector2(0.6845907f, 0.7512038f) }, new Vector3[] { new Vector2(0.6364366f, 0.5874799f), new Vector2(0.6669342f, 0.5361156f), new Vector2(0.6813804f, 0.4654896f), new Vector2(0.6813804f, 0.423756f), new Vector2(0.6701444f, 0.3756019f), new Vector2(0.7279294f, 0.3756019f), new Vector2(0.7905297f, 0.3900481f), new Vector2(0.85313f, 0.423756f), new Vector2(0.9028893f, 0.4751204f), new Vector2(0.9333869f, 0.5248796f), new Vector2(0.9446228f, 0.5858748f), new Vector2(0.9430177f, 0.6532905f), new Vector2(0.8980739f, 0.6404495f), new Vector2(0.8338684f, 0.6436597f), new Vector2(0.7841092f, 0.6613162f), new Vector2(0.7375602f, 0.6886035f) }, new Vector3[] { new Vector2(0.03451043f, 0.1107544f), new Vector2(0.1067416f, 0.03852328f), new Vector2(0.3025682f, 0.2343499f), new Vector2(0.2287319f, 0.3097913f), new Vector2(0.03611557f, 0.1139647f) }, new Vector3[] { new Vector2(0.2367576f, 0.3033708f), new Vector2(0.711878f, 0.7736757f), new Vector2(0.7680578f, 0.7158908f), new Vector2(0.2961477f, 0.2439807f) } }; } return icon_axe; } + Vector3[][] Icon_magnet() { if (icon_magnet == null) { icon_magnet = new Vector3[][] { new Vector3[] { new Vector2(0.3555556f, 0.8203704f), new Vector2(0.4518518f, 0.7185185f), new Vector2(0.2240741f, 0.4962963f), new Vector2(0.1833333f, 0.4240741f), new Vector2(0.1722222f, 0.3222222f), new Vector2(0.2148148f, 0.2333333f), new Vector2(0.2981482f, 0.1888889f), new Vector2(0.3981481f, 0.1833333f), new Vector2(0.4796296f, 0.2351852f), new Vector2(0.7092593f, 0.4648148f), new Vector2(0.8074074f, 0.362963f), new Vector2(0.5777778f, 0.137037f), new Vector2(0.487037f, 0.07222223f), new Vector2(0.362963f, 0.04074074f), new Vector2(0.25f, 0.06111111f), new Vector2(0.1574074f, 0.1055556f), new Vector2(0.07037037f, 0.2111111f), new Vector2(0.03333334f, 0.3314815f), new Vector2(0.04074074f, 0.45f), new Vector2(0.08518519f, 0.5351852f), new Vector2(0.1333333f, 0.6f), new Vector2(0.3555556f, 0.8222222f) }, new Vector3[] { new Vector2(0.2685185f, 0.7314815f), new Vector2(0.3648148f, 0.6333333f) }, new Vector3[] { new Vector2(0.6240741f, 0.3777778f), new Vector2(0.7203704f, 0.2777778f) }, new Vector3[] { new Vector2(0.1314815f, 0.1407407f), new Vector2(0.2203704f, 0.2296296f) }, new Vector3[] { new Vector2(0.8666667f, 0.4092593f), new Vector2(0.9592593f, 0.4462963f) }, new Vector3[] { new Vector2(0.8129629f, 0.4703704f), new Vector2(0.887037f, 0.5462963f) }, new Vector3[] { new Vector2(0.7537037f, 0.5148148f), new Vector2(0.7888889f, 0.6166667f) }, new Vector3[] { new Vector2(0.5259259f, 0.9f), new Vector2(0.4444444f, 0.8222222f) }, new Vector3[] { new Vector2(0.3888889f, 0.8722222f), new Vector2(0.4296296f, 0.9722222f) }, new Vector3[] { new Vector2(0.5018519f, 0.7685185f), new Vector2(0.6018519f, 0.8055556f) } }; } return icon_magnet; } + Vector3[][] Icon_compass() { if (icon_compass == null) { icon_compass = new Vector3[][] { new Vector3[] { new Vector2(0.4999586f, 0.07192704f), new Vector2(0.3613212f, 0.09965453f), new Vector2(0.2579732f, 0.1664526f), new Vector2(0.1836131f, 0.2710609f), new Vector2(0.1495839f, 0.416f), new Vector2(0.1747907f, 0.5521169f), new Vector2(0.2617542f, 0.6781509f), new Vector2(0.3663625f, 0.744949f), new Vector2(0.505f, 0.7688954f), new Vector2(0.6549805f, 0.7348663f), new Vector2(0.7595888f, 0.6542044f), new Vector2(0.8263869f, 0.5458152f), new Vector2(0.8478127f, 0.416f), new Vector2(0.8163041f, 0.2723212f), new Vector2(0.745725f, 0.1702336f), new Vector2(0.6360754f, 0.1009149f), new Vector2(0.4999586f, 0.07192704f) }, new Vector3[] { new Vector2(0.499521f, 0.03553063f), new Vector2(0.3460974f, 0.06621531f), new Vector2(0.2317271f, 0.1401376f), new Vector2(0.1494363f, 0.2559027f), new Vector2(0.1117778f, 0.4163f), new Vector2(0.139673f, 0.5669341f), new Vector2(0.2359114f, 0.7064101f), new Vector2(0.3516764f, 0.7803323f), new Vector2(0.5051f, 0.8068328f), new Vector2(0.6710764f, 0.7691742f), new Vector2(0.7868415f, 0.6799096f), new Vector2(0.8607638f, 0.5599603f), new Vector2(0.8844747f, 0.4163f), new Vector2(0.8496057f, 0.2572975f), new Vector2(0.7714991f, 0.1443219f), new Vector2(0.650155f, 0.06761009f), new Vector2(0.499521f, 0.03553063f) }, new Vector3[] { new Vector2(0.4994f, 0.3544254f), new Vector2(0.4518622f, 0.3741362f), new Vector2(0.4330789f, 0.4175f), new Vector2(0.4511665f, 0.4629508f), new Vector2(0.4982405f, 0.4831254f), new Vector2(0.5436913f, 0.4650378f), new Vector2(0.5620108f, 0.4172681f), new Vector2(0.5434595f, 0.3720492f), new Vector2(0.4994f, 0.3544254f) }, new Vector3[] { new Vector2(0.5021f, 0.8412322f), new Vector2(0.4540825f, 0.8610972f), new Vector2(0.4351098f, 0.9048f), new Vector2(0.4533798f, 0.9506062f), new Vector2(0.5009288f, 0.9709385f), new Vector2(0.5468382f, 0.9527096f), new Vector2(0.5653425f, 0.9045663f), new Vector2(0.546604f, 0.8589938f), new Vector2(0.5021f, 0.8412322f) }, new Vector3[] { new Vector2(0.2737643f, 0.1939164f), new Vector2(0.4258555f, 0.4923954f), new Vector2(0.7224334f, 0.6425856f), new Vector2(0.5665399f, 0.3441065f), new Vector2(0.2737643f, 0.1939164f) }, new Vector3[] { new Vector2(0.148289f, 0.4163498f), new Vector2(0.2072243f, 0.4163498f) }, new Vector3[] { new Vector2(0.8460076f, 0.4163498f), new Vector2(0.7832699f, 0.4163498f) }, new Vector3[] { new Vector2(0.5038023f, 0.769962f), new Vector2(0.5038023f, 0.7072243f) }, new Vector3[] { new Vector2(0.5f, 0.07224335f), new Vector2(0.5f, 0.134981f) }, new Vector3[] { new Vector2(0.5038023f, 0.8079848f), new Vector2(0.5038023f, 0.8460076f) } }; } return icon_compass; } + Vector3[][] Icon_fuelStation() { if (icon_fuelStation == null) { icon_fuelStation = new Vector3[][] { new Vector3[] { new Vector2(0.6825095f, 0.6197718f), new Vector2(0.7167301f, 0.6159696f), new Vector2(0.7604563f, 0.5988593f), new Vector2(0.7832699f, 0.5570342f), new Vector2(0.7965779f, 0.4885932f), new Vector2(0.7965779f, 0.3897339f), new Vector2(0.7851711f, 0.2984791f), new Vector2(0.7851711f, 0.2205323f), new Vector2(0.7984791f, 0.1996198f), new Vector2(0.8288974f, 0.1920152f), new Vector2(0.8555133f, 0.2091255f), new Vector2(0.8802282f, 0.3117871f), new Vector2(0.8954372f, 0.4448669f), new Vector2(0.8954372f, 0.595057f), new Vector2(0.8764259f, 0.6958175f), new Vector2(0.9144487f, 0.7034221f), new Vector2(0.9372624f, 0.6178707f), new Vector2(0.9391635f, 0.5475285f), new Vector2(0.9372624f, 0.391635f), new Vector2(0.9144487f, 0.2490494f), new Vector2(0.9011407f, 0.1939164f), new Vector2(0.8821293f, 0.1634981f), new Vector2(0.8536122f, 0.1444867f), new Vector2(0.8098859f, 0.1444867f), new Vector2(0.7680609f, 0.1634981f), new Vector2(0.7395437f, 0.2148289f), new Vector2(0.7376426f, 0.2718631f), new Vector2(0.7509506f, 0.3707224f), new Vector2(0.7528517f, 0.4486692f), new Vector2(0.7471483f, 0.5152091f), new Vector2(0.7376426f, 0.5475285f), new Vector2(0.7110266f, 0.5665399f), new Vector2(0.6844106f, 0.5722433f) }, new Vector3[] { new Vector2(0.9144487f, 0.7034221f), new Vector2(0.9239544f, 0.7319391f), new Vector2(0.904943f, 0.8079848f), new Vector2(0.7870722f, 0.878327f), new Vector2(0.7756654f, 0.8555133f), new Vector2(0.8593156f, 0.8079848f), new Vector2(0.8193916f, 0.7794677f), new Vector2(0.8346007f, 0.7091255f), new Vector2(0.8764259f, 0.6939163f) }, new Vector3[] { new Vector2(0.1444867f, 0.121673f), new Vector2(0.1444867f, 0.9068441f), new Vector2(0.1596958f, 0.9353612f), new Vector2(0.1958175f, 0.9562737f), new Vector2(0.634981f, 0.9562737f), new Vector2(0.6634981f, 0.9391635f), new Vector2(0.6806084f, 0.9011407f), new Vector2(0.6806084f, 0.121673f) }, new Vector3[] { new Vector2(0.07794677f, 0.121673f), new Vector2(0.7528517f, 0.121673f), new Vector2(0.7528517f, 0.03231939f), new Vector2(0.07794677f, 0.03231939f), new Vector2(0.07794677f, 0.121673f) }, new Vector3[] { new Vector2(0.21673f, 0.8878327f), new Vector2(0.6102661f, 0.8878327f), new Vector2(0.6102661f, 0.5874525f), new Vector2(0.21673f, 0.5874525f), new Vector2(0.21673f, 0.8878327f) }, new Vector3[] { new Vector2(0.8745247f, 0.7851711f), new Vector2(0.8935362f, 0.7319391f), new Vector2(0.8593156f, 0.7281369f), new Vector2(0.8498099f, 0.7718631f), new Vector2(0.8745247f, 0.7851711f) } }; } return icon_fuelStation; } + Vector3[][] Icon_fuelCan() { if (icon_fuelCan == null) { icon_fuelCan = new Vector3[][] { new Vector3[] { new Vector2(0.1178707f, 0.6634981f), new Vector2(0.1178707f, 0.1444867f), new Vector2(0.1254753f, 0.09695818f), new Vector2(0.1387833f, 0.07984791f), new Vector2(0.1596958f, 0.06273764f), new Vector2(0.2015209f, 0.04752852f), new Vector2(0.8117871f, 0.04752852f), new Vector2(0.8403042f, 0.0608365f), new Vector2(0.8593156f, 0.08174905f), new Vector2(0.8745247f, 0.1064639f), new Vector2(0.8802282f, 0.1444867f), new Vector2(0.8802282f, 0.851711f), new Vector2(0.8707224f, 0.8954372f), new Vector2(0.8479087f, 0.9277567f), new Vector2(0.8117871f, 0.9562737f), new Vector2(0.7604563f, 0.9657795f), new Vector2(0.4125475f, 0.9657795f), new Vector2(0.1178707f, 0.6634981f) }, new Vector3[] { new Vector2(0.4619772f, 0.7756654f), new Vector2(0.7585551f, 0.7756654f), new Vector2(0.7870722f, 0.7908745f), new Vector2(0.8041825f, 0.8326996f), new Vector2(0.7889734f, 0.8726236f), new Vector2(0.7547529f, 0.891635f), new Vector2(0.4657795f, 0.891635f), new Vector2(0.4372624f, 0.8707224f), new Vector2(0.4220532f, 0.8346007f), new Vector2(0.4353612f, 0.7965779f), new Vector2(0.4619772f, 0.7756654f) }, new Vector3[] { new Vector2(0.1178707f, 0.7642586f), new Vector2(0.1178707f, 0.8422053f), new Vector2(0.230038f, 0.9543726f), new Vector2(0.3098859f, 0.9543726f), new Vector2(0.1178707f, 0.7642586f) }, new Vector3[] { new Vector2(0.1577947f, 0.8041825f), new Vector2(0.2034221f, 0.756654f) }, new Vector3[] { new Vector2(0.2680608f, 0.9125475f), new Vector2(0.3117871f, 0.865019f) }, new Vector3[] { new Vector2(0.2661597f, 0.6444867f), new Vector2(0.7756654f, 0.1330798f) }, new Vector3[] { new Vector2(0.256654f, 0.1387833f), new Vector2(0.7813688f, 0.6634981f) } }; } return icon_fuelCan; } + Vector3[][] Icon_lockLocked() { if (icon_lockLocked == null) { icon_lockLocked = new Vector3[][] { new Vector3[] { new Vector2(0.2163121f, 0.4982269f), new Vector2(0.2163121f, 0.06028369f), new Vector2(0.2411347f, 0.03723404f), new Vector2(0.7517731f, 0.03723404f), new Vector2(0.7783688f, 0.07092199f), new Vector2(0.7783688f, 0.5f), new Vector2(0.7517731f, 0.5301418f), new Vector2(0.2429078f, 0.5301418f), new Vector2(0.2163121f, 0.4982269f) }, new Vector3[] { new Vector2(0.5301418f, 0.1702128f), new Vector2(0.5301418f, 0.2641844f), new Vector2(0.5567376f, 0.2801418f), new Vector2(0.5797873f, 0.3120568f), new Vector2(0.5851064f, 0.3510638f), new Vector2(0.570922f, 0.391844f), new Vector2(0.5425532f, 0.4202128f), new Vector2(0.5f, 0.4343972f), new Vector2(0.4592199f, 0.4202128f), new Vector2(0.4237589f, 0.393617f), new Vector2(0.4113475f, 0.358156f), new Vector2(0.4131206f, 0.3280142f), new Vector2(0.4219858f, 0.3014185f), new Vector2(0.4414894f, 0.2801418f), new Vector2(0.464539f, 0.2659574f), new Vector2(0.464539f, 0.1702128f), new Vector2(0.4751773f, 0.1560284f), new Vector2(0.4964539f, 0.1453901f), new Vector2(0.5177305f, 0.1578014f), new Vector2(0.5301418f, 0.1702128f) }, new Vector3[] { new Vector2(0.7180851f, 0.5336879f), new Vector2(0.7180851f, 0.6365248f), new Vector2(0.6950355f, 0.7021276f), new Vector2(0.6489362f, 0.7588652f), new Vector2(0.572695f, 0.8102837f), new Vector2(0.5053192f, 0.8244681f), new Vector2(0.4255319f, 0.8067376f), new Vector2(0.3510638f, 0.7695035f), new Vector2(0.3102837f, 0.7109929f), new Vector2(0.287234f, 0.6471631f), new Vector2(0.2801418f, 0.6046099f), new Vector2(0.2801418f, 0.5283688f) }, new Vector3[] { new Vector2(0.6347518f, 0.5319149f), new Vector2(0.6347518f, 0.6187943f), new Vector2(0.6170213f, 0.6684397f), new Vector2(0.5744681f, 0.7163121f), new Vector2(0.5301418f, 0.7340425f), new Vector2(0.4751773f, 0.7340425f), new Vector2(0.4202128f, 0.7092199f), new Vector2(0.3847518f, 0.6737589f), new Vector2(0.3652482f, 0.6276596f), new Vector2(0.3599291f, 0.5851064f), new Vector2(0.3599291f, 0.5301418f) } }; } return icon_lockLocked; } + Vector3[][] Icon_lockUnlocked() { if (icon_lockUnlocked == null) { icon_lockUnlocked = new Vector3[][] { new Vector3[] { new Vector2(0.2163121f, 0.4982269f), new Vector2(0.2163121f, 0.06028369f), new Vector2(0.2411347f, 0.03723404f), new Vector2(0.7517731f, 0.03723404f), new Vector2(0.7783688f, 0.07092199f), new Vector2(0.7783688f, 0.5f), new Vector2(0.7517731f, 0.5301418f), new Vector2(0.2429078f, 0.5301418f), new Vector2(0.2163121f, 0.4982269f) }, new Vector3[] { new Vector2(0.5301418f, 0.1702128f), new Vector2(0.5301418f, 0.2641844f), new Vector2(0.5567376f, 0.2801418f), new Vector2(0.5797873f, 0.3120568f), new Vector2(0.5851064f, 0.3510638f), new Vector2(0.570922f, 0.391844f), new Vector2(0.5425532f, 0.4202128f), new Vector2(0.5f, 0.4343972f), new Vector2(0.4592199f, 0.4202128f), new Vector2(0.4237589f, 0.393617f), new Vector2(0.4113475f, 0.358156f), new Vector2(0.4131206f, 0.3280142f), new Vector2(0.4219858f, 0.3014185f), new Vector2(0.4414894f, 0.2801418f), new Vector2(0.464539f, 0.2659574f), new Vector2(0.464539f, 0.1702128f), new Vector2(0.4751773f, 0.1560284f), new Vector2(0.4964539f, 0.1453901f), new Vector2(0.5177305f, 0.1578014f), new Vector2(0.5301418f, 0.1702128f) }, new Vector3[] { new Vector2(0.7180851f, 0.5336879f), new Vector2(0.7180851f, 0.7819149f), new Vector2(0.6950355f, 0.8457447f), new Vector2(0.6542553f, 0.9078014f), new Vector2(0.5833333f, 0.9521276f), new Vector2(0.5f, 0.9716312f), new Vector2(0.4237589f, 0.9592199f), new Vector2(0.356383f, 0.9202127f), new Vector2(0.3085106f, 0.8687943f), new Vector2(0.285461f, 0.8085107f), new Vector2(0.2765957f, 0.7446808f), new Vector2(0.2765957f, 0.714539f), new Vector2(0.2907801f, 0.7021276f), new Vector2(0.3173759f, 0.6897163f), new Vector2(0.3439716f, 0.7056738f), new Vector2(0.3617021f, 0.7287234f), new Vector2(0.3617021f, 0.7641844f), new Vector2(0.3723404f, 0.8138298f), new Vector2(0.4113475f, 0.8546099f), new Vector2(0.462766f, 0.8812057f), new Vector2(0.5141844f, 0.8812057f), new Vector2(0.570922f, 0.8670213f), new Vector2(0.6028369f, 0.8368794f), new Vector2(0.6258865f, 0.7960993f), new Vector2(0.6329787f, 0.7482269f), new Vector2(0.6329787f, 0.5319149f) } }; } return icon_lockUnlocked; } + Vector3[][] Icon_key() { if (icon_key == null) { icon_key = new Vector3[][] { new Vector3[] { new Vector2(0.4222038f, 0.4164213f), new Vector2(0.3742242f, 0.3486996f), new Vector2(0.3137213f, 0.3092331f), new Vector2(0.2398659f, 0.2943415f), new Vector2(0.1540156f, 0.3107094f), new Vector2(0.08704364f, 0.3567354f), new Vector2(0.04022795f, 0.4334701f), new Vector2(0.02939141f, 0.5055193f), new Vector2(0.04966111f, 0.5855823f), new Vector2(0.1037292f, 0.6578816f), new Vector2(0.1719675f, 0.6947129f), new Vector2(0.2460442f, 0.7046463f), new Vector2(0.3207743f, 0.685132f), new Vector2(0.3902963f, 0.6339207f), new Vector2(0.4237589f, 0.5780142f), new Vector2(0.4893617f, 0.6471631f), new Vector2(0.4893617f, 0.569149f), new Vector2(0.9219858f, 0.569149f), new Vector2(0.9663121f, 0.5053192f), new Vector2(0.8758865f, 0.4042553f), new Vector2(0.822695f, 0.462766f), new Vector2(0.7712766f, 0.4095745f), new Vector2(0.7163121f, 0.4680851f), new Vector2(0.6613475f, 0.4095745f), new Vector2(0.6010638f, 0.4698582f), new Vector2(0.5425532f, 0.4113475f), new Vector2(0.4911348f, 0.4663121f), new Vector2(0.4911348f, 0.358156f), new Vector2(0.4222038f, 0.4164213f) }, new Vector3[] { new Vector2(0.8971631f, 0.5141844f), new Vector2(0.4326241f, 0.5141844f) }, new Vector3[] { new Vector2(0.128f, 0.4449929f), new Vector2(0.08827589f, 0.4614639f), new Vector2(0.07258002f, 0.4977f), new Vector2(0.08769456f, 0.5356802f), new Vector2(0.1270311f, 0.5525387f), new Vector2(0.1650113f, 0.5374241f), new Vector2(0.1803196f, 0.4975062f), new Vector2(0.1648175f, 0.4597199f), new Vector2(0.128f, 0.4449929f) } }; } return icon_key; } + Vector3[][] Icon_gemDiamond() { if (icon_gemDiamond == null) { icon_gemDiamond = new Vector3[][] { new Vector3[] { new Vector2(0.07222223f, 0.6092592f), new Vector2(0.9185185f, 0.6092592f), new Vector2(0.7759259f, 0.8555555f), new Vector2(0.2222222f, 0.8555555f), new Vector2(0.07592592f, 0.6074074f), new Vector2(0.5f, 0.08703703f), new Vector2(0.9185185f, 0.6111111f) }, new Vector3[] { new Vector2(0.4148148f, 0.8555555f), new Vector2(0.3f, 0.6092592f), new Vector2(0.5f, 0.08703703f), new Vector2(0.6981481f, 0.6111111f), new Vector2(0.587037f, 0.8537037f) } }; } return icon_gemDiamond; } + Vector3[][] Icon_gold() { if (icon_gold == null) { icon_gold = new Vector3[][] { new Vector3[] { new Vector2(0.2407407f, 0.2740741f), new Vector2(0.4722222f, 0.212963f), new Vector2(0.7481481f, 0.4962963f), new Vector2(0.6962963f, 0.6185185f), new Vector2(0.5537037f, 0.6574074f), new Vector2(0.2833333f, 0.3777778f), new Vector2(0.2407407f, 0.2740741f) }, new Vector3[] { new Vector2(0.2796296f, 0.3777778f), new Vector2(0.4277778f, 0.3351852f), new Vector2(0.6944444f, 0.6185185f) }, new Vector3[] { new Vector2(0.4407407f, 0.5425926f), new Vector2(0.4203704f, 0.5537037f), new Vector2(0.1388889f, 0.2703704f), new Vector2(0.287037f, 0.2351852f), new Vector2(0.3277778f, 0.1074074f), new Vector2(0.09444445f, 0.1648148f), new Vector2(0.1407407f, 0.2740741f) }, new Vector3[] { new Vector2(0.7240741f, 0.4722222f), new Vector2(0.8351852f, 0.4407407f), new Vector2(0.8814815f, 0.3166667f), new Vector2(0.6111111f, 0.03888889f), new Vector2(0.3740741f, 0.09814814f), new Vector2(0.4222222f, 0.2018518f), new Vector2(0.5703704f, 0.162963f), new Vector2(0.8333333f, 0.4407407f) }, new Vector3[] { new Vector2(0.6111111f, 0.04259259f), new Vector2(0.5685185f, 0.162963f) }, new Vector3[] { new Vector2(0.3240741f, 0.1092593f), new Vector2(0.4407407f, 0.2203704f) }, new Vector3[] { new Vector2(0.4277778f, 0.3351852f), new Vector2(0.4722222f, 0.2148148f) }, new Vector3[] { new Vector2(0.8185185f, 0.612963f), new Vector2(0.9537037f, 0.7203704f) }, new Vector3[] { new Vector2(0.6907408f, 0.7166666f), new Vector2(0.7722222f, 0.8777778f) }, new Vector3[] { new Vector2(0.5037037f, 0.7592593f), new Vector2(0.5037037f, 0.9370371f) }, new Vector3[] { new Vector2(0.3481481f, 0.7166666f), new Vector2(0.2648148f, 0.8814815f) }, new Vector3[] { new Vector2(0.2111111f, 0.6018519f), new Vector2(0.06296296f, 0.7074074f) }, new Vector3[] { new Vector2(0.2851852f, 0.237037f), new Vector2(0.3092593f, 0.2574074f) } }; } return icon_gold; } + Vector3[][] Icon_potion() { if (icon_potion == null) { icon_potion = new Vector3[][] { new Vector3[] { new Vector2(0.4185185f, 0.8092592f), new Vector2(0.4351852f, 0.7666667f), new Vector2(0.4296296f, 0.7074074f), new Vector2(0.412963f, 0.6481481f), new Vector2(0.3666667f, 0.5907407f), new Vector2(0.3111111f, 0.5518519f), new Vector2(0.2574074f, 0.4962963f), new Vector2(0.2111111f, 0.4185185f), new Vector2(0.1944444f, 0.3092593f), new Vector2(0.2111111f, 0.2148148f), new Vector2(0.2537037f, 0.1351852f), new Vector2(0.3129629f, 0.07592592f), new Vector2(0.3648148f, 0.04259259f), new Vector2(0.6222222f, 0.04259259f), new Vector2(0.6944444f, 0.08888889f), new Vector2(0.7555556f, 0.1592593f), new Vector2(0.7925926f, 0.2425926f), new Vector2(0.7944444f, 0.3425926f), new Vector2(0.7703704f, 0.4481482f), new Vector2(0.7185185f, 0.5203704f), new Vector2(0.6518518f, 0.5740741f), new Vector2(0.5925926f, 0.6296296f), new Vector2(0.5611111f, 0.6981481f), new Vector2(0.5592592f, 0.7611111f), new Vector2(0.5777778f, 0.8111111f) }, new Vector3[] { new Vector2(0.237037f, 0.3018518f), new Vector2(0.3055556f, 0.35f), new Vector2(0.3833333f, 0.3703704f), new Vector2(0.4611111f, 0.3666667f), new Vector2(0.5351852f, 0.3333333f), new Vector2(0.5925926f, 0.3f), new Vector2(0.6537037f, 0.2777778f), new Vector2(0.7074074f, 0.2888889f), new Vector2(0.7592593f, 0.3222222f), new Vector2(0.7518519f, 0.2481481f), new Vector2(0.7259259f, 0.1851852f), new Vector2(0.6870371f, 0.1314815f), new Vector2(0.65f, 0.1f), new Vector2(0.6055555f, 0.07592592f), new Vector2(0.3814815f, 0.07592592f), new Vector2(0.3314815f, 0.1092593f), new Vector2(0.2796296f, 0.162963f), new Vector2(0.2444444f, 0.2296296f), new Vector2(0.237037f, 0.3018518f) }, new Vector3[] { new Vector2(0.2425926f, 0.25f), new Vector2(0.2925926f, 0.2888889f), new Vector2(0.3666667f, 0.3148148f), new Vector2(0.4425926f, 0.3203704f), new Vector2(0.5111111f, 0.2944444f), new Vector2(0.5537037f, 0.2611111f), new Vector2(0.6055555f, 0.2333333f), new Vector2(0.6592593f, 0.2277778f), new Vector2(0.7074074f, 0.237037f), new Vector2(0.75f, 0.2666667f) }, new Vector3[] { new Vector2(0.6555555f, 0.5111111f), new Vector2(0.6925926f, 0.4648148f), new Vector2(0.7f, 0.4240741f), new Vector2(0.6888889f, 0.3907408f), new Vector2(0.6574074f, 0.3703704f), new Vector2(0.6111111f, 0.3888889f), new Vector2(0.5666667f, 0.4333333f), new Vector2(0.5518519f, 0.4777778f), new Vector2(0.5648148f, 0.5203704f), new Vector2(0.5888889f, 0.537037f), new Vector2(0.6277778f, 0.5259259f), new Vector2(0.6555555f, 0.5111111f) }, new Vector3[] { new Vector2(0.387037f, 0.8111111f), new Vector2(0.6037037f, 0.8111111f), new Vector2(0.6037037f, 0.8796296f), new Vector2(0.387037f, 0.8796296f), new Vector2(0.387037f, 0.8111111f) }, new Vector3[] { new Vector2(0.4388889f, 0.8796296f), new Vector2(0.4388889f, 0.9481481f), new Vector2(0.5611111f, 0.9481481f), new Vector2(0.5611111f, 0.8796296f) } }; } return icon_potion; } + Vector3[][] Icon_presentGift() { if (icon_presentGift == null) { icon_presentGift = new Vector3[][] { new Vector3[] { new Vector2(0.5f, 0.05f), new Vector2(0.5f, 0.7555556f), new Vector2(0.4574074f, 0.8351852f), new Vector2(0.3851852f, 0.9222222f), new Vector2(0.3222222f, 0.9611111f), new Vector2(0.2777778f, 0.9703704f), new Vector2(0.2333333f, 0.9518518f), new Vector2(0.2166667f, 0.9037037f), new Vector2(0.25f, 0.8444445f), new Vector2(0.3222222f, 0.7962963f), new Vector2(0.4203704f, 0.7648148f), new Vector2(0.5018519f, 0.7518519f), new Vector2(0.6111111f, 0.7722222f), new Vector2(0.6981481f, 0.8055556f), new Vector2(0.7592593f, 0.862963f), new Vector2(0.7796296f, 0.9055555f), new Vector2(0.7685185f, 0.95f), new Vector2(0.7333333f, 0.9666666f), new Vector2(0.6722222f, 0.9611111f), new Vector2(0.6f, 0.9074074f), new Vector2(0.5407407f, 0.8388889f), new Vector2(0.5f, 0.7555556f) }, new Vector3[] { new Vector2(0.04444445f, 0.6074074f), new Vector2(0.04444445f, 0.7592593f), new Vector2(0.9481481f, 0.7592593f), new Vector2(0.9481481f, 0.6074074f), new Vector2(0.04444445f, 0.6074074f) }, new Vector3[] { new Vector2(0.0962963f, 0.6055555f), new Vector2(0.0962963f, 0.04629629f), new Vector2(0.9037037f, 0.04629629f), new Vector2(0.9037037f, 0.6074074f) } }; } return icon_presentGift; } + Vector3[][] Icon_death() { if (icon_death == null) { icon_death = new Vector3[][] { new Vector3[] { new Vector2(0.1985816f, 0.2198582f), new Vector2(0.7606383f, 0.4840426f), new Vector2(0.7606383f, 0.535461f), new Vector2(0.7836879f, 0.5762411f), new Vector2(0.8067376f, 0.5868794f), new Vector2(0.8404256f, 0.5868794f), new Vector2(0.858156f, 0.570922f), new Vector2(0.8758865f, 0.5496454f), new Vector2(0.8723404f, 0.5212766f), new Vector2(0.8617021f, 0.4946809f), new Vector2(0.9060284f, 0.4787234f), new Vector2(0.9219858f, 0.4539007f), new Vector2(0.9219858f, 0.4202128f), new Vector2(0.9007092f, 0.3882979f), new Vector2(0.858156f, 0.3794326f), new Vector2(0.8031915f, 0.4113475f), new Vector2(0.2340426f, 0.1507092f), new Vector2(0.2358156f, 0.1187943f), new Vector2(0.2287234f, 0.08687943f), new Vector2(0.2074468f, 0.05673759f), new Vector2(0.1666667f, 0.04609929f), new Vector2(0.1329787f, 0.06914894f), new Vector2(0.1223404f, 0.09751773f), new Vector2(0.1365248f, 0.141844f), new Vector2(0.09397163f, 0.1542553f), new Vector2(0.06914894f, 0.1879433f), new Vector2(0.07624114f, 0.2287234f), new Vector2(0.1046099f, 0.248227f), new Vector2(0.143617f, 0.25f), new Vector2(0.1985816f, 0.2198582f) }, new Vector3[] { new Vector2(0.5957447f, 0.3138298f), new Vector2(0.8031915f, 0.2163121f), new Vector2(0.8333333f, 0.2375887f), new Vector2(0.8776596f, 0.25f), new Vector2(0.9148936f, 0.2358156f), new Vector2(0.927305f, 0.2039007f), new Vector2(0.9202127f, 0.1702128f), new Vector2(0.8989362f, 0.1471631f), new Vector2(0.858156f, 0.1453901f), new Vector2(0.8687943f, 0.1099291f), new Vector2(0.8634752f, 0.07624114f), new Vector2(0.8368794f, 0.04964539f), new Vector2(0.7978724f, 0.05141844f), new Vector2(0.7677305f, 0.08865248f), new Vector2(0.7588652f, 0.1507092f), new Vector2(0.4982269f, 0.2695035f) }, new Vector3[] { new Vector2(0.4929078f, 0.3599291f), new Vector2(0.2358156f, 0.4840426f), new Vector2(0.2304965f, 0.5301418f), new Vector2(0.2109929f, 0.572695f), new Vector2(0.1719858f, 0.5815603f), new Vector2(0.1329787f, 0.5673759f), new Vector2(0.1223404f, 0.5390071f), new Vector2(0.1382979f, 0.4858156f), new Vector2(0.1028369f, 0.4751773f), new Vector2(0.07978723f, 0.4485815f), new Vector2(0.07978723f, 0.4113475f), new Vector2(0.1099291f, 0.3829787f), new Vector2(0.1507092f, 0.3882979f), new Vector2(0.1932624f, 0.4184397f), new Vector2(0.4024823f, 0.3173759f) }, new Vector3[] { new Vector2(0.4024823f, 0.5656028f), new Vector2(0.391844f, 0.4804965f), new Vector2(0.6187943f, 0.4804965f), new Vector2(0.6046099f, 0.569149f), new Vector2(0.6666667f, 0.606383f), new Vector2(0.7021276f, 0.679078f), new Vector2(0.714539f, 0.7641844f), new Vector2(0.7021276f, 0.8528369f), new Vector2(0.6489362f, 0.9202127f), new Vector2(0.5762411f, 0.9485816f), new Vector2(0.4219858f, 0.9485816f), new Vector2(0.356383f, 0.9113475f), new Vector2(0.3138298f, 0.858156f), new Vector2(0.2925532f, 0.8067376f), new Vector2(0.285461f, 0.7322695f), new Vector2(0.3031915f, 0.6666667f), new Vector2(0.3368794f, 0.6187943f), new Vector2(0.4024823f, 0.5656028f) }, new Vector3[] { new Vector2(0.4132f, 0.6499658f), new Vector2(0.3675014f, 0.668914f), new Vector2(0.3494449f, 0.7106f), new Vector2(0.3668326f, 0.7542924f), new Vector2(0.4120854f, 0.7736864f), new Vector2(0.4557777f, 0.7562986f), new Vector2(0.4733884f, 0.7103771f), new Vector2(0.4555548f, 0.6669077f), new Vector2(0.4132f, 0.6499658f) }, new Vector3[] { new Vector2(0.5919f, 0.6495658f), new Vector2(0.5460985f, 0.668514f), new Vector2(0.5280012f, 0.7102f), new Vector2(0.5454282f, 0.7538924f), new Vector2(0.5907829f, 0.7732864f), new Vector2(0.6345736f, 0.7558986f), new Vector2(0.652224f, 0.7099771f), new Vector2(0.6343502f, 0.6665077f), new Vector2(0.5919f, 0.6495658f) }, new Vector3[] { new Vector2(0.4663121f, 0.5673759f), new Vector2(0.4769503f, 0.6152482f), new Vector2(0.5124114f, 0.6453901f), new Vector2(0.5443262f, 0.6099291f), new Vector2(0.5514184f, 0.5638298f), new Vector2(0.5088652f, 0.5868794f), new Vector2(0.4663121f, 0.5673759f) } }; } return icon_death; } + Vector3[][] Icon_map() { if (icon_map == null) { icon_map = new Vector3[][] { new Vector3[] { new Vector2(0.3574074f, 0.7777778f), new Vector2(0.3574074f, 0.1185185f) }, new Vector3[] { new Vector2(0.65f, 0.8611111f), new Vector2(0.65f, 0.2f) }, new Vector3[] { new Vector2(0.9314815f, 0.7777778f), new Vector2(0.9314815f, 0.1222222f), new Vector2(0.65f, 0.1981481f), new Vector2(0.3592592f, 0.1185185f), new Vector2(0.06481481f, 0.1962963f), new Vector2(0.06481481f, 0.8537037f), new Vector2(0.3555556f, 0.7740741f), new Vector2(0.65f, 0.8592592f), new Vector2(0.9314815f, 0.7777778f) }, new Vector3[] { new Vector2(0.4481482f, 0.662963f), new Vector2(0.5796296f, 0.5222222f) }, new Vector3[] { new Vector2(0.4703704f, 0.4925926f), new Vector2(0.5740741f, 0.6888889f) }, new Vector3[] { new Vector2(0.5185185f, 0.4574074f), new Vector2(0.5166667f, 0.3981481f) }, new Vector3[] { new Vector2(0.4944444f, 0.3537037f), new Vector2(0.4925926f, 0.2907407f) }, new Vector3[] { new Vector2(0.537037f, 0.2611111f), new Vector2(0.5888889f, 0.2481481f) }, new Vector3[] { new Vector2(0.6351852f, 0.262963f), new Vector2(0.6518518f, 0.2777778f), new Vector2(0.6870371f, 0.2759259f) }, new Vector3[] { new Vector2(0.7407407f, 0.287037f), new Vector2(0.7907407f, 0.3074074f) }, new Vector3[] { new Vector2(0.8277778f, 0.3425926f), new Vector2(0.8555555f, 0.3814815f) } }; } return icon_map; } + Vector3[][] Icon_mushroom() { if (icon_mushroom == null) { icon_mushroom = new Vector3[][] { new Vector3[] { new Vector2(0.6781701f, 0.3980738f), new Vector2(0.3009631f, 0.3980738f), new Vector2(0.1886035f, 0.4060995f), new Vector2(0.08747993f, 0.4333868f), new Vector2(0.04574639f, 0.4831461f), new Vector2(0.04574639f, 0.5489566f), new Vector2(0.07463884f, 0.6677368f), new Vector2(0.1372392f, 0.7736757f), new Vector2(0.2351525f, 0.8555377f), new Vector2(0.3443018f, 0.9133226f), new Vector2(0.4422151f, 0.9373997f), new Vector2(0.5385233f, 0.9373997f), new Vector2(0.6332263f, 0.9165329f), new Vector2(0.7182986f, 0.8764045f), new Vector2(0.7953451f, 0.8218299f), new Vector2(0.8739968f, 0.7447833f), new Vector2(0.9141252f, 0.6693419f), new Vector2(0.9430177f, 0.5698234f), new Vector2(0.9414125f, 0.4815409f), new Vector2(0.9093098f, 0.4382023f), new Vector2(0.8467095f, 0.4125201f), new Vector2(0.6781701f, 0.3980738f) }, new Vector3[] { new Vector2(0.3218299f, 0.3980738f), new Vector2(0.3378812f, 0.3483146f), new Vector2(0.3394864f, 0.2728732f), new Vector2(0.3202247f, 0.1829856f), new Vector2(0.3025682f, 0.1187801f), new Vector2(0.3057785f, 0.07865169f), new Vector2(0.3218299f, 0.05136437f), new Vector2(0.3619583f, 0.03691814f), new Vector2(0.6396469f, 0.03691814f), new Vector2(0.6701444f, 0.05617978f), new Vector2(0.6878009f, 0.08507223f), new Vector2(0.6845907f, 0.1348315f), new Vector2(0.6573034f, 0.2327448f), new Vector2(0.6540931f, 0.3354735f), new Vector2(0.6749599f, 0.3964687f) } }; } return icon_mushroom; } + Vector3[][] Icon_star() { if (icon_star == null) { icon_star = new Vector3[][] { new Vector3[] { new Vector2(0.04814815f, 0.6037037f), new Vector2(0.3944444f, 0.6037037f), new Vector2(0.5018519f, 0.9240741f), new Vector2(0.6018519f, 0.6018519f), new Vector2(0.9481481f, 0.6018519f), new Vector2(0.662963f, 0.4092593f), new Vector2(0.7759259f, 0.05925926f), new Vector2(0.4962963f, 0.2851852f), new Vector2(0.2111111f, 0.08148148f), new Vector2(0.3222222f, 0.4018519f), new Vector2(0.04814815f, 0.6037037f) } }; } return icon_star; } + Vector3[][] Icon_pill() { if (icon_pill == null) { icon_pill = new Vector3[][] { new Vector3[] { new Vector2(0.1444445f, 0.4296296f), new Vector2(0.5851852f, 0.8685185f), new Vector2(0.6481481f, 0.9092593f), new Vector2(0.7240741f, 0.9296296f), new Vector2(0.7814815f, 0.9203704f), new Vector2(0.8407407f, 0.8925926f), new Vector2(0.8962963f, 0.8481482f), new Vector2(0.9203704f, 0.7962963f), new Vector2(0.9388889f, 0.7222222f), new Vector2(0.9296296f, 0.6537037f), new Vector2(0.9055555f, 0.6037037f), new Vector2(0.8685185f, 0.5592592f), new Vector2(0.4462963f, 0.1351852f), new Vector2(0.3851852f, 0.09259259f), new Vector2(0.3203704f, 0.07037037f), new Vector2(0.25f, 0.07407407f), new Vector2(0.1907407f, 0.09444445f), new Vector2(0.1314815f, 0.1444445f), new Vector2(0.08703703f, 0.2166667f), new Vector2(0.08148148f, 0.2962963f), new Vector2(0.1018519f, 0.3740741f), new Vector2(0.1444445f, 0.4296296f) }, new Vector3[] { new Vector2(0.3444445f, 0.6333333f), new Vector2(0.3740741f, 0.6407408f), new Vector2(0.4111111f, 0.6277778f), new Vector2(0.4574074f, 0.6018519f), new Vector2(0.5092593f, 0.5629629f), new Vector2(0.5777778f, 0.5f), new Vector2(0.6277778f, 0.4370371f), new Vector2(0.65f, 0.3944444f), new Vector2(0.6574074f, 0.3685185f), new Vector2(0.6518518f, 0.3444445f) }, new Vector3[] { new Vector2(0.3074074f, 0.5314815f), new Vector2(0.3574074f, 0.487037f), new Vector2(0.2037037f, 0.3462963f), new Vector2(0.1740741f, 0.2962963f), new Vector2(0.162963f, 0.2537037f), new Vector2(0.1592593f, 0.2111111f), new Vector2(0.1648148f, 0.1777778f), new Vector2(0.1814815f, 0.1462963f), new Vector2(0.1351852f, 0.2111111f), new Vector2(0.1222222f, 0.2592593f), new Vector2(0.1277778f, 0.3185185f), new Vector2(0.1407407f, 0.3592592f), new Vector2(0.1666667f, 0.4f), new Vector2(0.3074074f, 0.5314815f) } }; } return icon_pill; } + Vector3[][] Icon_health() { if (icon_health == null) { icon_health = new Vector3[][] { new Vector3[] { new Vector2(0.08518519f, 0.6351852f), new Vector2(0.3574074f, 0.6351852f), new Vector2(0.3574074f, 0.9111111f), new Vector2(0.6277778f, 0.9111111f), new Vector2(0.6277778f, 0.6351852f), new Vector2(0.9074074f, 0.6351852f), new Vector2(0.9074074f, 0.3592592f), new Vector2(0.6277778f, 0.3592592f), new Vector2(0.6277778f, 0.08703703f), new Vector2(0.3574074f, 0.08703703f), new Vector2(0.3574074f, 0.3592592f), new Vector2(0.08518519f, 0.3592592f), new Vector2(0.08518519f, 0.6351852f) } }; } return icon_health; } + Vector3[][] Icon_foodPlate() { if (icon_foodPlate == null) { icon_foodPlate = new Vector3[][] { new Vector3[] { new Vector2(0.5105195f, 0.2482073f), new Vector2(0.4093063f, 0.2684499f), new Vector2(0.3338565f, 0.3172163f), new Vector2(0.2795694f, 0.3935862f), new Vector2(0.2547262f, 0.4994f), new Vector2(0.2731286f, 0.598773f), new Vector2(0.3366168f, 0.6907849f), new Vector2(0.4129868f, 0.7395513f), new Vector2(0.5142f, 0.7570336f), new Vector2(0.6236942f, 0.7321904f), new Vector2(0.7000642f, 0.6733027f), new Vector2(0.7488306f, 0.5941724f), new Vector2(0.7644726f, 0.4994f), new Vector2(0.7414696f, 0.3945064f), new Vector2(0.6899428f, 0.3199766f), new Vector2(0.6098924f, 0.26937f), new Vector2(0.5105195f, 0.2482073f) }, new Vector3[] { new Vector2(0.5093555f, 0.19074f), new Vector2(0.3843826f, 0.2157346f), new Vector2(0.291221f, 0.2759488f), new Vector2(0.2241901f, 0.3702465f), new Vector2(0.1935149f, 0.5009f), new Vector2(0.2162373f, 0.6236007f), new Vector2(0.2946293f, 0.7372124f), new Vector2(0.3889271f, 0.7974266f), new Vector2(0.5139f, 0.8190128f), new Vector2(0.6490979f, 0.7883376f), new Vector2(0.7433957f, 0.7156261f), new Vector2(0.8036098f, 0.6179201f), new Vector2(0.8229239f, 0.5009f), new Vector2(0.7945209f, 0.3713827f), new Vector2(0.7308984f, 0.2793571f), new Vector2(0.6320561f, 0.2168707f), new Vector2(0.5093555f, 0.19074f) }, new Vector3[] { new Vector2(0.9011407f, 0.4980989f), new Vector2(0.891635f, 0.1882129f), new Vector2(0.9372624f, 0.1882129f), new Vector2(0.9372624f, 0.8022814f), new Vector2(0.9277567f, 0.8212928f), new Vector2(0.9087452f, 0.8212928f), new Vector2(0.8878327f, 0.7946768f), new Vector2(0.8764259f, 0.743346f), new Vector2(0.8593156f, 0.539924f), new Vector2(0.8669202f, 0.5190114f), new Vector2(0.8821293f, 0.5019011f), new Vector2(0.9030418f, 0.4923954f), new Vector2(0.9353612f, 0.4923954f) }, new Vector3[] { new Vector2(0.04942966f, 0.8136882f), new Vector2(0.04942966f, 0.6539924f), new Vector2(0.08555133f, 0.6292776f), new Vector2(0.08555133f, 0.1901141f), new Vector2(0.121673f, 0.1901141f), new Vector2(0.121673f, 0.6311787f), new Vector2(0.1634981f, 0.6653993f), new Vector2(0.1634981f, 0.8155894f) }, new Vector3[] { new Vector2(0.04752852f, 0.6920152f), new Vector2(0.161597f, 0.6920152f) }, new Vector3[] { new Vector2(0.08365019f, 0.6939163f), new Vector2(0.08365019f, 0.8136882f) }, new Vector3[] { new Vector2(0.1235741f, 0.6920152f), new Vector2(0.1235741f, 0.8136882f) } }; } return icon_foodPlate; } + Vector3[][] Icon_foodMeat() { if (icon_foodMeat == null) { icon_foodMeat = new Vector3[][] { new Vector3[] { new Vector2(0.5209125f, 0.9315589f), new Vector2(0.4942966f, 0.8897339f), new Vector2(0.4942966f, 0.8231939f), new Vector2(0.526616f, 0.7376426f), new Vector2(0.608365f, 0.6330798f), new Vector2(0.730038f, 0.5361217f), new Vector2(0.8022814f, 0.4980989f), new Vector2(0.8688213f, 0.4885932f), new Vector2(0.8954372f, 0.4961977f), new Vector2(0.9239544f, 0.5114068f), new Vector2(0.9448669f, 0.5513308f), new Vector2(0.9429658f, 0.6102661f), new Vector2(0.9125475f, 0.6920152f), new Vector2(0.8479087f, 0.7813688f), new Vector2(0.7642586f, 0.8612167f), new Vector2(0.6787072f, 0.9163498f), new Vector2(0.6026616f, 0.9429658f), new Vector2(0.5513308f, 0.9448669f), new Vector2(0.5209125f, 0.9315589f) }, new Vector3[] { new Vector2(0.6197718f, 0.8117871f), new Vector2(0.6520913f, 0.8231939f), new Vector2(0.7053232f, 0.8098859f), new Vector2(0.7661597f, 0.7623574f), new Vector2(0.8212928f, 0.6787072f), new Vector2(0.8231939f, 0.6577947f), new Vector2(0.8155894f, 0.6235741f), new Vector2(0.7870722f, 0.608365f), new Vector2(0.7547529f, 0.6178707f), new Vector2(0.6920152f, 0.648289f), new Vector2(0.6444867f, 0.6996198f), new Vector2(0.6159696f, 0.7604563f), new Vector2(0.6121673f, 0.7927757f), new Vector2(0.6197718f, 0.8117871f) }, new Vector3[] { new Vector2(0.5209125f, 0.9296578f), new Vector2(0.4467681f, 0.8403042f), new Vector2(0.3707224f, 0.7167301f), new Vector2(0.3288973f, 0.6026616f), new Vector2(0.3174905f, 0.5f), new Vector2(0.3288973f, 0.4353612f), new Vector2(0.3536122f, 0.3802281f), new Vector2(0.4011407f, 0.3403042f), new Vector2(0.4752852f, 0.3174905f), new Vector2(0.5684411f, 0.3136882f), new Vector2(0.6882129f, 0.3498099f), new Vector2(0.8117871f, 0.4182509f), new Vector2(0.9239544f, 0.5095057f) }, new Vector3[] { new Vector2(0.338403f, 0.4106464f), new Vector2(0.1692015f, 0.2357415f), new Vector2(0.1254753f, 0.2547528f), new Vector2(0.07794677f, 0.243346f), new Vector2(0.05323194f, 0.2034221f), new Vector2(0.0608365f, 0.1558935f), new Vector2(0.09885932f, 0.1292776f), new Vector2(0.1463878f, 0.134981f), new Vector2(0.1425855f, 0.08174905f), new Vector2(0.1692015f, 0.05323194f), new Vector2(0.2129278f, 0.03612167f), new Vector2(0.2604563f, 0.06653992f), new Vector2(0.2680608f, 0.1159696f), new Vector2(0.2509506f, 0.1577947f), new Vector2(0.4239544f, 0.3326996f) } }; } return icon_foodMeat; } + Vector3[][] Icon_flag() { if (icon_flag == null) { icon_flag = new Vector3[][] { new Vector3[] { new Vector2(0.2314815f, 0.03518518f), new Vector2(0.2314815f, 0.9555556f), new Vector2(0.287037f, 0.9555556f), new Vector2(0.287037f, 0.03518518f) }, new Vector3[] { new Vector2(0.287037f, 0.9222222f), new Vector2(0.3259259f, 0.8759259f), new Vector2(0.3981481f, 0.8444445f), new Vector2(0.4722222f, 0.8314815f), new Vector2(0.5388889f, 0.8425926f), new Vector2(0.5907407f, 0.8759259f), new Vector2(0.6462963f, 0.9055555f), new Vector2(0.7018518f, 0.9203704f), new Vector2(0.7685185f, 0.9222222f), new Vector2(0.8222222f, 0.8907408f), new Vector2(0.8222222f, 0.5722222f), new Vector2(0.7759259f, 0.5925926f), new Vector2(0.7111111f, 0.6018519f), new Vector2(0.6425926f, 0.5851852f), new Vector2(0.5851852f, 0.5555556f), new Vector2(0.5333334f, 0.5166667f), new Vector2(0.4814815f, 0.5074074f), new Vector2(0.4203704f, 0.5129629f), new Vector2(0.3574074f, 0.5333334f), new Vector2(0.3129629f, 0.5592592f), new Vector2(0.287037f, 0.5925926f) }, new Vector3[] { new Vector2(0.1537037f, 0.03148148f), new Vector2(0.3592592f, 0.03148148f) } }; } return icon_flag; } + Vector3[][] Icon_flagChequered() { if (icon_flagChequered == null) { icon_flagChequered = new Vector3[][] { new Vector3[] { new Vector2(0.3444445f, 0.9444444f), new Vector2(0.3796296f, 0.8777778f), new Vector2(0.4148148f, 0.8388889f), new Vector2(0.4740741f, 0.8055556f), new Vector2(0.5388889f, 0.8f), new Vector2(0.6092592f, 0.8074074f), new Vector2(0.6777778f, 0.8277778f), new Vector2(0.7296296f, 0.837037f), new Vector2(0.7925926f, 0.8351852f), new Vector2(0.862963f, 0.8092592f), new Vector2(0.9166667f, 0.7759259f), new Vector2(0.9407408f, 0.7333333f), new Vector2(0.8055556f, 0.2777778f), new Vector2(0.7666667f, 0.3314815f), new Vector2(0.7f, 0.3703704f), new Vector2(0.612963f, 0.3777778f), new Vector2(0.5388889f, 0.3666667f), new Vector2(0.4592593f, 0.3425926f), new Vector2(0.3925926f, 0.3407407f), new Vector2(0.3222222f, 0.3574074f), new Vector2(0.2611111f, 0.3962963f), new Vector2(0.2296296f, 0.4407407f), new Vector2(0.2092593f, 0.4833333f) }, new Vector3[] { new Vector2(0.3129629f, 0.8314815f), new Vector2(0.3388889f, 0.7759259f), new Vector2(0.3962963f, 0.7166666f), new Vector2(0.4685185f, 0.6907408f), new Vector2(0.5555556f, 0.6925926f), new Vector2(0.6351852f, 0.7148148f), new Vector2(0.7111111f, 0.7259259f), new Vector2(0.7814815f, 0.7185185f), new Vector2(0.8462963f, 0.6888889f), new Vector2(0.8851852f, 0.6592593f), new Vector2(0.9074074f, 0.6222222f) }, new Vector3[] { new Vector2(0.2759259f, 0.7074074f), new Vector2(0.3092593f, 0.6462963f), new Vector2(0.3611111f, 0.5962963f), new Vector2(0.4370371f, 0.5648148f), new Vector2(0.5203704f, 0.5666667f), new Vector2(0.5981482f, 0.5888889f), new Vector2(0.6833333f, 0.6018519f), new Vector2(0.7518519f, 0.6f), new Vector2(0.8074074f, 0.5703704f), new Vector2(0.8481482f, 0.5444444f), new Vector2(0.8722222f, 0.5074074f) }, new Vector3[] { new Vector2(0.2425926f, 0.5888889f), new Vector2(0.2759259f, 0.5240741f), new Vector2(0.3185185f, 0.4814815f), new Vector2(0.3907408f, 0.45f), new Vector2(0.4666667f, 0.4518518f), new Vector2(0.55f, 0.4703704f), new Vector2(0.6351852f, 0.487037f), new Vector2(0.7074074f, 0.4833333f), new Vector2(0.7777778f, 0.4537037f), new Vector2(0.8148148f, 0.4185185f), new Vector2(0.8351852f, 0.3814815f) }, new Vector3[] { new Vector2(0.3518519f, 0.9555556f), new Vector2(0.08518519f, 0.03518518f), new Vector2(0.03333334f, 0.0537037f), new Vector2(0.3055556f, 0.9722222f), new Vector2(0.3518519f, 0.9555556f) }, new Vector3[] { new Vector2(0.4333333f, 0.8259259f), new Vector2(0.2888889f, 0.3777778f) }, new Vector3[] { new Vector2(0.5481482f, 0.8018519f), new Vector2(0.412963f, 0.3407407f) }, new Vector3[] { new Vector2(0.7018518f, 0.8333333f), new Vector2(0.5611111f, 0.3722222f) }, new Vector3[] { new Vector2(0.8314815f, 0.8203704f), new Vector2(0.7f, 0.3703704f) }, new Vector3[] { new Vector2(0.3148148f, 0.8185185f), new Vector2(0.3611111f, 0.9092593f), new Vector2(0.3333333f, 0.7851852f), new Vector2(0.3907408f, 0.8703704f), new Vector2(0.3648148f, 0.7481481f), new Vector2(0.412963f, 0.8444445f), new Vector2(0.3944444f, 0.7203704f) }, new Vector3[] { new Vector2(0.5407407f, 0.6981481f), new Vector2(0.5722222f, 0.8018519f), new Vector2(0.5685185f, 0.7f), new Vector2(0.6092592f, 0.8111111f), new Vector2(0.6092592f, 0.7111111f), new Vector2(0.6407408f, 0.8166667f), new Vector2(0.6388889f, 0.7148148f), new Vector2(0.6777778f, 0.8240741f) }, new Vector3[] { new Vector2(0.8222222f, 0.7092593f), new Vector2(0.8574074f, 0.8166667f), new Vector2(0.8425926f, 0.6888889f), new Vector2(0.8888889f, 0.7925926f), new Vector2(0.8740741f, 0.6703704f), new Vector2(0.9240741f, 0.7574074f), new Vector2(0.9f, 0.637037f) }, new Vector3[] { new Vector2(0.3759259f, 0.5888889f), new Vector2(0.4203704f, 0.7055556f), new Vector2(0.4055555f, 0.5777778f), new Vector2(0.4537037f, 0.6944444f), new Vector2(0.4333333f, 0.5666667f), new Vector2(0.487037f, 0.6925926f), new Vector2(0.462963f, 0.5685185f) }, new Vector3[] { new Vector2(0.6481481f, 0.6037037f), new Vector2(0.6925926f, 0.7240741f), new Vector2(0.6777778f, 0.6018519f), new Vector2(0.7240741f, 0.7222222f), new Vector2(0.7148148f, 0.6f), new Vector2(0.7592593f, 0.7259259f), new Vector2(0.7518519f, 0.5962963f) }, new Vector3[] { new Vector2(0.2537037f, 0.5629629f), new Vector2(0.2925926f, 0.6740741f), new Vector2(0.2685185f, 0.5351852f), new Vector2(0.3074074f, 0.6462963f), new Vector2(0.2888889f, 0.5129629f), new Vector2(0.3296296f, 0.6259259f), new Vector2(0.3074074f, 0.4981481f), new Vector2(0.3481481f, 0.6055555f) }, new Vector3[] { new Vector2(0.462963f, 0.4518518f), new Vector2(0.5018519f, 0.5666667f), new Vector2(0.4981481f, 0.4611111f), new Vector2(0.5333334f, 0.5722222f), new Vector2(0.5314815f, 0.4648148f), new Vector2(0.5722222f, 0.5833333f), new Vector2(0.5648148f, 0.4777778f), new Vector2(0.6018519f, 0.5907407f) }, new Vector3[] { new Vector2(0.75f, 0.4685185f), new Vector2(0.787037f, 0.5814815f), new Vector2(0.7740741f, 0.4592593f), new Vector2(0.8129629f, 0.5685185f), new Vector2(0.7981482f, 0.4388889f), new Vector2(0.8388889f, 0.5481482f), new Vector2(0.8240741f, 0.4092593f), new Vector2(0.8574074f, 0.5203704f) }, new Vector3[] { new Vector2(0.3055556f, 0.3685185f), new Vector2(0.3462963f, 0.4722222f), new Vector2(0.3277778f, 0.3574074f), new Vector2(0.3759259f, 0.4574074f), new Vector2(0.3592592f, 0.3462963f), new Vector2(0.4018519f, 0.4518518f), new Vector2(0.3925926f, 0.3407407f), new Vector2(0.4259259f, 0.4462963f) }, new Vector3[] { new Vector2(0.5814815f, 0.3740741f), new Vector2(0.6259259f, 0.4851852f), new Vector2(0.6148148f, 0.3759259f), new Vector2(0.6555555f, 0.4851852f), new Vector2(0.6444445f, 0.3777778f), new Vector2(0.6925926f, 0.487037f), new Vector2(0.6851852f, 0.3796296f) } }; } return icon_flagChequered; } + Vector3[][] Icon_ball() { if (icon_ball == null) { icon_ball = new Vector3[][] { new Vector3[] { new Vector2(0.4986212f, 0.06564754f), new Vector2(0.3232045f, 0.1007309f), new Vector2(0.1924393f, 0.1852499f), new Vector2(0.09835207f, 0.3176098f), new Vector2(0.05529523f, 0.501f), new Vector2(0.0871892f, 0.6732274f), new Vector2(0.1972233f, 0.8326972f), new Vector2(0.3295832f, 0.9172162f), new Vector2(0.505f, 0.9475154f), new Vector2(0.694769f, 0.9044585f), new Vector2(0.827129f, 0.8023978f), new Vector2(0.9116479f, 0.6652539f), new Vector2(0.9387578f, 0.501f), new Vector2(0.8988903f, 0.3192045f), new Vector2(0.8095872f, 0.190034f), new Vector2(0.6708485f, 0.1023256f), new Vector2(0.4986212f, 0.06564754f) }, new Vector3[] { new Vector2(0.112963f, 0.7092593f), new Vector2(0.3981481f, 0.4462963f), new Vector2(0.4796296f, 0.4481482f), new Vector2(0.6222222f, 0.4925926f), new Vector2(0.7296296f, 0.5574074f), new Vector2(0.7907407f, 0.6166667f), new Vector2(0.8296296f, 0.6796296f), new Vector2(0.8074074f, 0.7685185f), new Vector2(0.7851852f, 0.8129629f), new Vector2(0.7148148f, 0.8925926f) }, new Vector3[] { new Vector2(0.412963f, 0.08333334f), new Vector2(0.3796296f, 0.1648148f), new Vector2(0.362963f, 0.2685185f), new Vector2(0.3685185f, 0.3777778f), new Vector2(0.3925926f, 0.45f) }, new Vector3[] { new Vector2(0.2240741f, 0.1648148f), new Vector2(0.2074074f, 0.2518519f), new Vector2(0.2074074f, 0.3722222f), new Vector2(0.2240741f, 0.4555556f), new Vector2(0.2555556f, 0.5185185f), new Vector2(0.2814815f, 0.5555556f) }, new Vector3[] { new Vector2(0.06851852f, 0.4351852f), new Vector2(0.07592592f, 0.5351852f), new Vector2(0.1074074f, 0.612963f), new Vector2(0.1314815f, 0.6555555f), new Vector2(0.1574074f, 0.6703704f) }, new Vector3[] { new Vector2(0.8296296f, 0.6777778f), new Vector2(0.8740741f, 0.6425926f), new Vector2(0.9111111f, 0.5703704f), new Vector2(0.9277778f, 0.4592593f) }, new Vector3[] { new Vector2(0.3925926f, 0.1333333f), new Vector2(0.4370371f, 0.1148148f), new Vector2(0.5111111f, 0.1037037f), new Vector2(0.6037037f, 0.1148148f), new Vector2(0.6925926f, 0.15f), new Vector2(0.7777778f, 0.1962963f), new Vector2(0.8666667f, 0.2722222f) }, new Vector3[] { new Vector2(0.3666667f, 0.2481481f), new Vector2(0.4796296f, 0.2518519f), new Vector2(0.6185185f, 0.2907407f), new Vector2(0.7537037f, 0.3462963f), new Vector2(0.8388889f, 0.3981481f), new Vector2(0.887037f, 0.4555556f), new Vector2(0.9185185f, 0.5259259f) }, new Vector3[] { new Vector2(0.1888889f, 0.8277778f), new Vector2(0.237037f, 0.8351852f), new Vector2(0.2981482f, 0.8074074f), new Vector2(0.3907408f, 0.7259259f), new Vector2(0.4685185f, 0.6277778f), new Vector2(0.5277778f, 0.5407407f), new Vector2(0.5518519f, 0.4703704f) }, new Vector3[] { new Vector2(0.3888889f, 0.9296296f), new Vector2(0.4648148f, 0.9166667f), new Vector2(0.5407407f, 0.8685185f), new Vector2(0.6037037f, 0.8f), new Vector2(0.6611111f, 0.7203704f), new Vector2(0.7092593f, 0.612963f), new Vector2(0.7166666f, 0.5462963f) } }; } return icon_ball; } + Vector3[][] Icon_dice() { if (icon_dice == null) { icon_dice = new Vector3[][] { new Vector3[] { new Vector2(0.09814814f, 0.712963f), new Vector2(0.4111111f, 0.9648148f), new Vector2(0.9055555f, 0.8018519f), new Vector2(0.9055555f, 0.2944444f), new Vector2(0.5851852f, 0.04259259f), new Vector2(0.5851852f, 0.5537037f), new Vector2(0.09814814f, 0.7148148f), new Vector2(0.09814814f, 0.2074074f), new Vector2(0.5851852f, 0.04259259f) }, new Vector3[] { new Vector2(0.7703704f, 0.4148148f), new Vector2(0.7740741f, 0.4592593f), new Vector2(0.7611111f, 0.4833333f), new Vector2(0.7370371f, 0.4759259f), new Vector2(0.7166666f, 0.45f), new Vector2(0.7166666f, 0.3944444f), new Vector2(0.7314815f, 0.3685185f), new Vector2(0.7518519f, 0.3833333f), new Vector2(0.7703704f, 0.4148148f) }, new Vector3[] { new Vector2(0.4388889f, 0.2888889f), new Vector2(0.4722222f, 0.2611111f), new Vector2(0.4833333f, 0.2259259f), new Vector2(0.4722222f, 0.2018518f), new Vector2(0.4370371f, 0.1981481f), new Vector2(0.4111111f, 0.2222222f), new Vector2(0.3962963f, 0.2555556f), new Vector2(0.3981481f, 0.2833333f), new Vector2(0.4166667f, 0.2925926f), new Vector2(0.4388889f, 0.2888889f) }, new Vector3[] { new Vector2(0.237037f, 0.35f), new Vector2(0.2611111f, 0.3203704f), new Vector2(0.2611111f, 0.2888889f), new Vector2(0.2462963f, 0.2666667f), new Vector2(0.212963f, 0.2722222f), new Vector2(0.1814815f, 0.3037037f), new Vector2(0.1759259f, 0.3462963f), new Vector2(0.1907407f, 0.3703704f), new Vector2(0.2203704f, 0.3648148f), new Vector2(0.237037f, 0.35f) }, new Vector3[] { new Vector2(0.2203704f, 0.5851852f), new Vector2(0.2518519f, 0.5629629f), new Vector2(0.2666667f, 0.5222222f), new Vector2(0.2555556f, 0.4962963f), new Vector2(0.2314815f, 0.4796296f), new Vector2(0.2018518f, 0.4888889f), new Vector2(0.1796296f, 0.5259259f), new Vector2(0.1796296f, 0.5611111f), new Vector2(0.1925926f, 0.5888889f), new Vector2(0.2203704f, 0.5851852f) }, new Vector3[] { new Vector2(0.45f, 0.5092593f), new Vector2(0.4685185f, 0.4851852f), new Vector2(0.4777778f, 0.4351852f), new Vector2(0.4592593f, 0.4185185f), new Vector2(0.4277778f, 0.4277778f), new Vector2(0.4018519f, 0.462963f), new Vector2(0.4018519f, 0.5037037f), new Vector2(0.412963f, 0.5277778f), new Vector2(0.4333333f, 0.5277778f), new Vector2(0.45f, 0.5092593f) }, new Vector3[] { new Vector2(0.4388889f, 0.8740741f), new Vector2(0.4777778f, 0.8722222f), new Vector2(0.5018519f, 0.8592592f), new Vector2(0.5092593f, 0.8388889f), new Vector2(0.4925926f, 0.8203704f), new Vector2(0.4574074f, 0.8111111f), new Vector2(0.4203704f, 0.8129629f), new Vector2(0.3944444f, 0.837037f), new Vector2(0.3962963f, 0.8611111f), new Vector2(0.4388889f, 0.8740741f) }, new Vector3[] { new Vector2(0.5092593f, 0.7055556f), new Vector2(0.5518519f, 0.7055556f), new Vector2(0.5814815f, 0.6796296f), new Vector2(0.5740741f, 0.6555555f), new Vector2(0.5296296f, 0.6462963f), new Vector2(0.4851852f, 0.6555555f), new Vector2(0.4648148f, 0.6740741f), new Vector2(0.4685185f, 0.6981481f), new Vector2(0.5092593f, 0.7055556f) }, new Vector3[] { new Vector2(0.5833333f, 0.5518519f), new Vector2(0.9055555f, 0.8037037f) } }; } return icon_dice; } + Vector3[][] Icon_joystick() { if (icon_joystick == null) { icon_joystick = new Vector3[][] { new Vector3[] { new Vector2(0.4995688f, 0.61307f), new Vector2(0.4327105f, 0.6264416f), new Vector2(0.3828707f, 0.6586551f), new Vector2(0.3470104f, 0.7091027f), new Vector2(0.3305997f, 0.779f), new Vector2(0.3427557f, 0.8446427f), new Vector2(0.3846941f, 0.9054229f), new Vector2(0.4351417f, 0.9376364f), new Vector2(0.502f, 0.9491847f), new Vector2(0.5743284f, 0.932774f), new Vector2(0.6247761f, 0.8938746f), new Vector2(0.6569896f, 0.8416036f), new Vector2(0.6673223f, 0.779f), new Vector2(0.6521271f, 0.7097105f), new Vector2(0.6180903f, 0.6604785f), new Vector2(0.5652114f, 0.6270494f), new Vector2(0.4995688f, 0.61307f) }, new Vector3[] { new Vector2(0.04259259f, 0.04814815f), new Vector2(0.04259259f, 0.2611111f), new Vector2(0.9481481f, 0.2611111f), new Vector2(0.9481481f, 0.04814815f), new Vector2(0.04259259f, 0.04814815f) }, new Vector3[] { new Vector2(0.3185185f, 0.2611111f), new Vector2(0.4166667f, 0.3592592f), new Vector2(0.5851852f, 0.3592592f), new Vector2(0.6740741f, 0.2611111f) }, new Vector3[] { new Vector2(0.7666667f, 0.2611111f), new Vector2(0.7666667f, 0.2944444f), new Vector2(0.8759259f, 0.2944444f), new Vector2(0.8759259f, 0.2611111f) }, new Vector3[] { new Vector2(0.1333333f, 0.04814815f), new Vector2(0.1333333f, 0.02222222f), new Vector2(0.2518519f, 0.02222222f), new Vector2(0.2518519f, 0.04814815f) }, new Vector3[] { new Vector2(0.7481481f, 0.04629629f), new Vector2(0.7481481f, 0.02222222f), new Vector2(0.8537037f, 0.02222222f), new Vector2(0.8537037f, 0.04814815f) }, new Vector3[] { new Vector2(0.4537037f, 0.3592592f), new Vector2(0.4537037f, 0.6203704f) }, new Vector3[] { new Vector2(0.5462963f, 0.3611111f), new Vector2(0.5462963f, 0.6240741f) } }; } return icon_joystick; } + Vector3[][] Icon_gamepad() { if (icon_gamepad == null) { icon_gamepad = new Vector3[][] { new Vector3[] { new Vector2(0.2018518f, 0.6925926f), new Vector2(0.7944444f, 0.6925926f), new Vector2(0.862963f, 0.6722222f), new Vector2(0.9240741f, 0.6166667f), new Vector2(0.9648148f, 0.5407407f), new Vector2(0.9666666f, 0.4462963f), new Vector2(0.9407408f, 0.3814815f), new Vector2(0.8962963f, 0.3277778f), new Vector2(0.8203704f, 0.2925926f), new Vector2(0.7388889f, 0.287037f), new Vector2(0.6685185f, 0.3111111f), new Vector2(0.6222222f, 0.3425926f), new Vector2(0.5962963f, 0.3814815f), new Vector2(0.4092593f, 0.3814815f), new Vector2(0.3648148f, 0.3333333f), new Vector2(0.2851852f, 0.2888889f), new Vector2(0.1981481f, 0.2851852f), new Vector2(0.1240741f, 0.3148148f), new Vector2(0.06481481f, 0.3666667f), new Vector2(0.02962963f, 0.4518518f), new Vector2(0.03703704f, 0.5462963f), new Vector2(0.07407407f, 0.6203704f), new Vector2(0.1351852f, 0.6740741f), new Vector2(0.2018518f, 0.6925926f) }, new Vector3[] { new Vector2(0.8331f, 0.4997008f), new Vector2(0.7961705f, 0.515013f), new Vector2(0.7815788f, 0.5487f), new Vector2(0.7956301f, 0.5840082f), new Vector2(0.8321993f, 0.5996807f), new Vector2(0.8675075f, 0.5856295f), new Vector2(0.8817389f, 0.5485198f), new Vector2(0.8673274f, 0.5133917f), new Vector2(0.8331f, 0.4997008f) }, new Vector3[] { new Vector2(0.71f, 0.377711f), new Vector2(0.6730704f, 0.3929888f), new Vector2(0.6584788f, 0.4266f), new Vector2(0.6725301f, 0.4618289f), new Vector2(0.7090992f, 0.4774662f), new Vector2(0.7444075f, 0.4634465f), new Vector2(0.7586389f, 0.4264203f), new Vector2(0.7442273f, 0.3913712f), new Vector2(0.71f, 0.377711f) }, new Vector3[] { new Vector2(0.2740741f, 0.6055555f), new Vector2(0.2740741f, 0.5425926f), new Vector2(0.3425926f, 0.5425926f), new Vector2(0.3425926f, 0.4833333f), new Vector2(0.2722222f, 0.4833333f), new Vector2(0.2722222f, 0.412963f), new Vector2(0.2185185f, 0.412963f), new Vector2(0.2185185f, 0.4833333f), new Vector2(0.1518518f, 0.4833333f), new Vector2(0.1518518f, 0.5425926f), new Vector2(0.2166667f, 0.5425926f), new Vector2(0.2166667f, 0.6037037f), new Vector2(0.2722222f, 0.6037037f) } }; } return icon_gamepad; } + Vector3[][] Icon_jigsawPuzzle() { if (icon_jigsawPuzzle == null) { icon_jigsawPuzzle = new Vector3[][] { new Vector3[] { new Vector2(0.7259259f, 0.5777778f), new Vector2(0.7388889f, 0.5462963f), new Vector2(0.7629629f, 0.537037f), new Vector2(0.7888889f, 0.55f), new Vector2(0.8037037f, 0.5722222f), new Vector2(0.837037f, 0.5981482f), new Vector2(0.8888889f, 0.5944445f), new Vector2(0.9296296f, 0.5574074f), new Vector2(0.9462963f, 0.5f), new Vector2(0.9351852f, 0.4388889f), new Vector2(0.9074074f, 0.4055555f), new Vector2(0.8759259f, 0.3851852f), new Vector2(0.8277778f, 0.4f), new Vector2(0.7962963f, 0.4222222f), new Vector2(0.7555556f, 0.4259259f), new Vector2(0.7333333f, 0.4f), new Vector2(0.7277778f, 0.3611111f), new Vector2(0.7277778f, 0.08888889f), new Vector2(0.4925926f, 0.08888889f), new Vector2(0.4462963f, 0.1055556f), new Vector2(0.4388889f, 0.1333333f), new Vector2(0.4592593f, 0.1648148f), new Vector2(0.4851852f, 0.1833333f), new Vector2(0.4907407f, 0.2259259f), new Vector2(0.4740741f, 0.2703704f), new Vector2(0.4370371f, 0.3f), new Vector2(0.3759259f, 0.3185185f), new Vector2(0.3259259f, 0.2962963f), new Vector2(0.2888889f, 0.25f), new Vector2(0.2796296f, 0.2074074f), new Vector2(0.2981482f, 0.1648148f), new Vector2(0.3333333f, 0.1240741f), new Vector2(0.3314815f, 0.112963f), new Vector2(0.2851852f, 0.09259259f), new Vector2(0.03703704f, 0.09259259f), new Vector2(0.03703704f, 0.4037037f), new Vector2(0.05185185f, 0.4314815f), new Vector2(0.07962963f, 0.4388889f), new Vector2(0.1f, 0.4185185f), new Vector2(0.1277778f, 0.3981481f), new Vector2(0.1685185f, 0.387037f), new Vector2(0.2166667f, 0.4018519f), new Vector2(0.2462963f, 0.4481482f), new Vector2(0.2555556f, 0.5055556f), new Vector2(0.2407407f, 0.5574074f), new Vector2(0.1981481f, 0.5962963f), new Vector2(0.1388889f, 0.5981482f), new Vector2(0.1092593f, 0.5666667f), new Vector2(0.07222223f, 0.5518519f), new Vector2(0.04814815f, 0.5740741f), new Vector2(0.03888889f, 0.6314815f), new Vector2(0.03888889f, 0.912963f), new Vector2(0.3111111f, 0.912963f), new Vector2(0.3425926f, 0.8981481f), new Vector2(0.3481481f, 0.8703704f), new Vector2(0.3296296f, 0.8259259f), new Vector2(0.2925926f, 0.7925926f), new Vector2(0.2888889f, 0.7462963f), new Vector2(0.3166667f, 0.7f), new Vector2(0.362963f, 0.6703704f), new Vector2(0.4148148f, 0.6740741f), new Vector2(0.4759259f, 0.7074074f), new Vector2(0.4925926f, 0.7462963f), new Vector2(0.4888889f, 0.8037037f), new Vector2(0.4685185f, 0.8425926f), new Vector2(0.45f, 0.8703704f), new Vector2(0.4518518f, 0.9074074f), new Vector2(0.4981481f, 0.912963f), new Vector2(0.7259259f, 0.912963f), new Vector2(0.7259259f, 0.5759259f) } }; } return icon_jigsawPuzzle; } + Vector3[][] Icon_fish() { if (icon_fish == null) { icon_fish = new Vector3[][] { new Vector3[] { new Vector2(0.9518518f, 0.4981481f), new Vector2(0.8740741f, 0.4074074f), new Vector2(0.7407407f, 0.3296296f), new Vector2(0.6148148f, 0.2925926f), new Vector2(0.487037f, 0.2962963f), new Vector2(0.3703704f, 0.3277778f), new Vector2(0.2814815f, 0.3722222f), new Vector2(0.2333333f, 0.4148148f), new Vector2(0.1574074f, 0.3555556f), new Vector2(0.04444445f, 0.3037037f), new Vector2(0.137037f, 0.4981481f), new Vector2(0.04814815f, 0.6851852f), new Vector2(0.1555556f, 0.6388889f), new Vector2(0.2314815f, 0.5759259f), new Vector2(0.3407407f, 0.6518518f), new Vector2(0.4814815f, 0.6944444f), new Vector2(0.6296296f, 0.6944444f), new Vector2(0.7462963f, 0.6592593f), new Vector2(0.8481482f, 0.6018519f), new Vector2(0.9111111f, 0.5444444f), new Vector2(0.9518518f, 0.4981481f) }, new Vector3[] { new Vector2(0.778f, 0.5082673f), new Vector2(0.7495618f, 0.5200588f), new Vector2(0.7383252f, 0.546f), new Vector2(0.7491456f, 0.5731897f), new Vector2(0.7773064f, 0.5852587f), new Vector2(0.8044961f, 0.5744382f), new Vector2(0.8154553f, 0.5458613f), new Vector2(0.8043574f, 0.5188103f), new Vector2(0.778f, 0.5082673f) }, new Vector3[] { new Vector2(0.7166666f, 0.6666667f), new Vector2(0.6740741f, 0.5851852f), new Vector2(0.662963f, 0.5055556f), new Vector2(0.6722222f, 0.4240741f), new Vector2(0.6962963f, 0.3703704f), new Vector2(0.7240741f, 0.3240741f) } }; } return icon_fish; } + Vector3[][] Icon_car() { if (icon_car == null) { icon_car = new Vector3[][] { new Vector3[] { new Vector2(0.2527f, 0.2096296f), new Vector2(0.1857204f, 0.2374016f), new Vector2(0.1592553f, 0.2985f), new Vector2(0.1847402f, 0.362539f), new Vector2(0.2510664f, 0.3909645f), new Vector2(0.3151053f, 0.3654796f), new Vector2(0.340917f, 0.2981733f), new Vector2(0.3147786f, 0.234461f), new Vector2(0.2527f, 0.2096296f) }, new Vector3[] { new Vector2(0.6998f, 0.2065166f), new Vector2(0.6313001f, 0.2348552f), new Vector2(0.6042343f, 0.2972f), new Vector2(0.6302977f, 0.3625454f), new Vector2(0.6981293f, 0.3915507f), new Vector2(0.7636219f, 0.3655459f), new Vector2(0.7900194f, 0.2968666f), new Vector2(0.7632877f, 0.2318546f), new Vector2(0.6998f, 0.2065166f) }, new Vector3[] { new Vector2(0.3909091f, 0.3057851f), new Vector2(0.5495868f, 0.3057851f), new Vector2(0.5694215f, 0.3752066f), new Vector2(0.6140496f, 0.4247934f), new Vector2(0.6867769f, 0.4446281f), new Vector2(0.7545455f, 0.4297521f), new Vector2(0.8024793f, 0.3867769f), new Vector2(0.8256198f, 0.3371901f), new Vector2(0.8305785f, 0.3008265f), new Vector2(0.9545454f, 0.3008265f), new Vector2(0.9198347f, 0.4909091f), new Vector2(0.9016529f, 0.5157025f), new Vector2(0.8669422f, 0.5322314f), new Vector2(0.716529f, 0.5322314f), new Vector2(0.5826446f, 0.7256199f), new Vector2(0.2090909f, 0.7256199f), new Vector2(0.161157f, 0.5338843f), new Vector2(0.06033058f, 0.5338843f), new Vector2(0.06033058f, 0.3057851f), new Vector2(0.1099174f, 0.3057851f), new Vector2(0.1165289f, 0.3652893f), new Vector2(0.1545455f, 0.4181818f), new Vector2(0.2090909f, 0.446281f), new Vector2(0.2702479f, 0.4512397f), new Vector2(0.3198347f, 0.4363636f), new Vector2(0.3628099f, 0.3950413f), new Vector2(0.3909091f, 0.3487603f), new Vector2(0.3909091f, 0.3057851f) }, new Vector3[] { new Vector2(0.6454545f, 0.5338843f), new Vector2(0.392562f, 0.5338843f), new Vector2(0.392562f, 0.6876033f), new Vector2(0.5413223f, 0.6876033f), new Vector2(0.6454545f, 0.5338843f) }, new Vector3[] { new Vector2(0.2520661f, 0.6892562f), new Vector2(0.3429752f, 0.6892562f), new Vector2(0.3429752f, 0.5355372f), new Vector2(0.222314f, 0.5355372f), new Vector2(0.2520661f, 0.6892562f) } }; } return icon_car; } + Vector3[][] Icon_tree() { if (icon_tree == null) { icon_tree = new Vector3[][] { new Vector3[] { new Vector2(0.5703704f, 0.3814815f), new Vector2(0.4537037f, 0.3814815f), new Vector2(0.3462963f, 0.3722222f), new Vector2(0.2925926f, 0.387037f), new Vector2(0.2333333f, 0.4314815f), new Vector2(0.2074074f, 0.4944444f), new Vector2(0.2148148f, 0.5592592f), new Vector2(0.1648148f, 0.5944445f), new Vector2(0.1407407f, 0.6555555f), new Vector2(0.1537037f, 0.7111111f), new Vector2(0.187037f, 0.75f), new Vector2(0.2166667f, 0.7592593f), new Vector2(0.2314815f, 0.8296296f), new Vector2(0.2685185f, 0.8777778f), new Vector2(0.3277778f, 0.9037037f), new Vector2(0.362963f, 0.9074074f), new Vector2(0.3981481f, 0.8962963f), new Vector2(0.4277778f, 0.9388889f), new Vector2(0.4833333f, 0.9611111f), new Vector2(0.5518519f, 0.9648148f), new Vector2(0.6018519f, 0.9425926f), new Vector2(0.6351852f, 0.9055555f), new Vector2(0.6481481f, 0.8759259f), new Vector2(0.712963f, 0.8888889f), new Vector2(0.7685185f, 0.8611111f), new Vector2(0.8111111f, 0.8018519f), new Vector2(0.8240741f, 0.7370371f), new Vector2(0.8055556f, 0.6796296f), new Vector2(0.8388889f, 0.662963f), new Vector2(0.8592592f, 0.6074074f), new Vector2(0.85f, 0.5537037f), new Vector2(0.8185185f, 0.5222222f), new Vector2(0.7759259f, 0.5055556f), new Vector2(0.7648148f, 0.4518518f), new Vector2(0.7296296f, 0.4037037f), new Vector2(0.6851852f, 0.3740741f), new Vector2(0.6314815f, 0.3648148f), new Vector2(0.5703704f, 0.3814815f) }, new Vector3[] { new Vector2(0.5703704f, 0.3777778f), new Vector2(0.5703704f, 0.1574074f), new Vector2(0.587037f, 0.03888889f), new Vector2(0.6277778f, 0.02222222f), new Vector2(0.3925926f, 0.02222222f), new Vector2(0.4444444f, 0.05f), new Vector2(0.4555556f, 0.1925926f), new Vector2(0.4555556f, 0.3814815f) } }; } return icon_tree; } + Vector3[][] Icon_palm() { if (icon_palm == null) { icon_palm = new Vector3[][] { new Vector3[] { new Vector2(0.5537037f, 0.6518518f), new Vector2(0.5185185f, 0.6722222f), new Vector2(0.4388889f, 0.65f), new Vector2(0.3611111f, 0.5981482f), new Vector2(0.3129629f, 0.5425926f), new Vector2(0.2962963f, 0.4851852f), new Vector2(0.2962963f, 0.45f), new Vector2(0.262963f, 0.5074074f), new Vector2(0.2555556f, 0.5574074f), new Vector2(0.2740741f, 0.6240741f), new Vector2(0.3296296f, 0.6944444f), new Vector2(0.3833333f, 0.7370371f), new Vector2(0.4444444f, 0.7611111f), new Vector2(0.3740741f, 0.7981482f), new Vector2(0.2833333f, 0.8018519f), new Vector2(0.2462963f, 0.7851852f), new Vector2(0.2851852f, 0.8444445f), new Vector2(0.337037f, 0.8666667f), new Vector2(0.4166667f, 0.8740741f), new Vector2(0.4851852f, 0.8592592f), new Vector2(0.5240741f, 0.8407407f), new Vector2(0.4925926f, 0.9092593f), new Vector2(0.4555556f, 0.9462963f), new Vector2(0.4203704f, 0.9537037f), new Vector2(0.4555556f, 0.9740741f), new Vector2(0.5037037f, 0.9685185f), new Vector2(0.5666667f, 0.9203704f), new Vector2(0.5944445f, 0.8648148f), new Vector2(0.662963f, 0.9f), new Vector2(0.7240741f, 0.9074074f), new Vector2(0.7759259f, 0.8981481f), new Vector2(0.8092592f, 0.8685185f), new Vector2(0.8296296f, 0.8111111f), new Vector2(0.7759259f, 0.8388889f), new Vector2(0.7185185f, 0.8388889f), new Vector2(0.6518518f, 0.8055556f), new Vector2(0.7425926f, 0.7888889f), new Vector2(0.8092592f, 0.7407407f), new Vector2(0.8537037f, 0.6759259f), new Vector2(0.8648148f, 0.6092592f), new Vector2(0.85f, 0.5555556f), new Vector2(0.8203704f, 0.6222222f), new Vector2(0.7703704f, 0.6648148f), new Vector2(0.7092593f, 0.6907408f), new Vector2(0.6666667f, 0.6944444f), new Vector2(0.7333333f, 0.5981482f), new Vector2(0.7611111f, 0.4962963f), new Vector2(0.7481481f, 0.4314815f), new Vector2(0.7018518f, 0.3777778f), new Vector2(0.6462963f, 0.3518519f), new Vector2(0.6777778f, 0.4277778f), new Vector2(0.6759259f, 0.5018519f), new Vector2(0.6425926f, 0.5796296f), new Vector2(0.5925926f, 0.6425926f), new Vector2(0.5537037f, 0.6518518f) }, new Vector3[] { new Vector2(0.2759259f, 0.04629629f), new Vector2(0.5351852f, 0.04629629f) }, new Vector3[] { new Vector2(0.3388889f, 0.05185185f), new Vector2(0.3740741f, 0.2203704f), new Vector2(0.4592593f, 0.5f), new Vector2(0.5203704f, 0.6648148f) }, new Vector3[] { new Vector2(0.4685185f, 0.04814815f), new Vector2(0.4574074f, 0.1259259f), new Vector2(0.4648148f, 0.2685185f), new Vector2(0.487037f, 0.4407407f), new Vector2(0.5240741f, 0.5814815f), new Vector2(0.5481482f, 0.6537037f) } }; } return icon_palm; } + Vector3[][] Icon_leaf() { if (icon_leaf == null) { icon_leaf = new Vector3[][] { new Vector3[] { new Vector2(0.7814815f, 0.6740741f), new Vector2(0.7055556f, 0.5462963f), new Vector2(0.6148148f, 0.4166667f), new Vector2(0.5148148f, 0.3092593f), new Vector2(0.3962963f, 0.2259259f), new Vector2(0.2611111f, 0.162963f), new Vector2(0.1611111f, 0.1425926f), new Vector2(0.08148148f, 0.1351852f), new Vector2(0.08148148f, 0.06111111f), new Vector2(0.1703704f, 0.06666667f), new Vector2(0.3f, 0.09814814f), new Vector2(0.4148148f, 0.162963f), new Vector2(0.5240741f, 0.262963f), new Vector2(0.6296296f, 0.3759259f), new Vector2(0.7037037f, 0.4925926f), new Vector2(0.7796296f, 0.6333333f) }, new Vector3[] { new Vector2(0.3092593f, 0.187037f), new Vector2(0.2185185f, 0.2611111f), new Vector2(0.1777778f, 0.3851852f), new Vector2(0.1981481f, 0.5074074f), new Vector2(0.2537037f, 0.6185185f), new Vector2(0.3259259f, 0.6962963f), new Vector2(0.4425926f, 0.7574074f), new Vector2(0.5907407f, 0.8055556f), new Vector2(0.7166666f, 0.8537037f), new Vector2(0.8129629f, 0.8981481f), new Vector2(0.8833333f, 0.9388889f), new Vector2(0.9055555f, 0.8259259f), new Vector2(0.9259259f, 0.6685185f), new Vector2(0.9222222f, 0.5074074f), new Vector2(0.9018518f, 0.3611111f), new Vector2(0.8555555f, 0.2407407f), new Vector2(0.7944444f, 0.1592593f), new Vector2(0.7018518f, 0.1092593f), new Vector2(0.6111111f, 0.09259259f), new Vector2(0.5148148f, 0.0962963f), new Vector2(0.3833333f, 0.1444445f) } }; } return icon_leaf; } + Vector3[][] Icon_nukeNuclearWarning() { if (icon_nukeNuclearWarning == null) { icon_nukeNuclearWarning = new Vector3[][] { new Vector3[] { new Vector2(0.4140071f, 0.356383f), new Vector2(0.4512411f, 0.3368794f), new Vector2(0.4920213f, 0.3333333f), new Vector2(0.5398936f, 0.3386525f), new Vector2(0.5789007f, 0.3528369f), new Vector2(0.7207447f, 0.09042553f), new Vector2(0.6533688f, 0.05851064f), new Vector2(0.5877659f, 0.04255319f), new Vector2(0.518617f, 0.03191489f), new Vector2(0.4423759f, 0.03191489f), new Vector2(0.3590426f, 0.04787234f), new Vector2(0.3076241f, 0.06914894f), new Vector2(0.266844f, 0.09397163f), new Vector2(0.4140071f, 0.356383f) }, new Vector3[] { new Vector2(0.6673725f, 0.4973365f), new Vector2(0.665646f, 0.5393339f), new Vector2(0.6483269f, 0.5764235f), new Vector2(0.6197842f, 0.6152227f), new Vector2(0.5879967f, 0.6419116f), new Vector2(0.7443296f, 0.8959578f), new Vector2(0.8056566f, 0.853566f), new Vector2(0.8522776f, 0.804731f), new Vector2(0.8960651f, 0.7501655f), new Vector2(0.9341856f, 0.6841387f), new Vector2(0.9620328f, 0.6039912f), new Vector2(0.9693159f, 0.5488232f), new Vector2(0.9682089f, 0.5010952f), new Vector2(0.6673725f, 0.4973365f) }, new Vector3[] { new Vector2(0.4186204f, 0.6462805f), new Vector2(0.3831128f, 0.6237867f), new Vector2(0.3596518f, 0.5902431f), new Vector2(0.3403221f, 0.5461249f), new Vector2(0.3331026f, 0.5052515f), new Vector2(0.03492573f, 0.5136167f), new Vector2(0.04097456f, 0.5879234f), new Vector2(0.05995643f, 0.6527159f), new Vector2(0.08531785f, 0.7179197f), new Vector2(0.1234384f, 0.7839465f), new Vector2(0.1789246f, 0.8481365f), new Vector2(0.2230599f, 0.882028f), new Vector2(0.2649471f, 0.9049332f), new Vector2(0.4186204f, 0.6462805f) }, new Vector3[] { new Vector2(0.4977532f, 0.3959289f), new Vector2(0.4552153f, 0.4044364f), new Vector2(0.4235053f, 0.4249319f), new Vector2(0.4006896f, 0.4570287f), new Vector2(0.3902484f, 0.5015f), new Vector2(0.3979826f, 0.5432644f), new Vector2(0.4246655f, 0.5819352f), new Vector2(0.4567622f, 0.6024307f), new Vector2(0.4993f, 0.6097782f), new Vector2(0.5453182f, 0.599337f), new Vector2(0.5774149f, 0.5745878f), new Vector2(0.5979105f, 0.5413309f), new Vector2(0.6044845f, 0.5015f), new Vector2(0.5948168f, 0.4574153f), new Vector2(0.5731611f, 0.426092f), new Vector2(0.5395176f, 0.4048231f), new Vector2(0.4977532f, 0.3959289f) } }; } return icon_nukeNuclearWarning; } + Vector3[][] Icon_biohazardWarning() { if (icon_biohazardWarning == null) { icon_biohazardWarning = new Vector3[][] { new Vector3[] { new Vector2(0.5246479f, 0.5361549f), new Vector2(0.5246479f, 0.4903803f), new Vector2(0.5440141f, 0.4850986f), new Vector2(0.5616197f, 0.4657324f), new Vector2(0.568662f, 0.4393239f), new Vector2(0.5616197f, 0.4164366f), new Vector2(0.6038733f, 0.3953098f), new Vector2(0.6285211f, 0.4287605f), new Vector2(0.6725352f, 0.4622113f), new Vector2(0.7147887f, 0.4798169f), new Vector2(0.7816901f, 0.483338f), new Vector2(0.8380282f, 0.4727746f), new Vector2(0.8873239f, 0.4481267f), new Vector2(0.9207746f, 0.4164366f), new Vector2(0.9507042f, 0.3724225f), new Vector2(0.9647887f, 0.3143239f), new Vector2(0.9647887f, 0.3847465f), new Vector2(0.9401408f, 0.4446057f), new Vector2(0.8926057f, 0.5009437f), new Vector2(0.8485916f, 0.5343943f), new Vector2(0.7975352f, 0.5608028f), new Vector2(0.7464789f, 0.5713662f), new Vector2(0.7623239f, 0.6171408f), new Vector2(0.7676057f, 0.6805211f), new Vector2(0.7588028f, 0.745662f), new Vector2(0.7359155f, 0.8090422f), new Vector2(0.6919014f, 0.8671408f), new Vector2(0.6443662f, 0.9041127f), new Vector2(0.5792254f, 0.9252395f), new Vector2(0.6408451f, 0.886507f), new Vector2(0.6725352f, 0.8477746f), new Vector2(0.6989437f, 0.7984789f), new Vector2(0.7059859f, 0.7386197f), new Vector2(0.6971831f, 0.6699578f), new Vector2(0.6707746f, 0.620662f), new Vector2(0.6320422f, 0.5784084f), new Vector2(0.5774648f, 0.5449578f), new Vector2(0.5246479f, 0.5361549f) }, new Vector3[] { new Vector2(0.4753521f, 0.5361549f), new Vector2(0.4753521f, 0.4903803f), new Vector2(0.4559859f, 0.4850986f), new Vector2(0.4383803f, 0.4657324f), new Vector2(0.431338f, 0.4393239f), new Vector2(0.4383803f, 0.4164366f), new Vector2(0.3961267f, 0.3953098f), new Vector2(0.3714789f, 0.4287605f), new Vector2(0.3274648f, 0.4622113f), new Vector2(0.2852113f, 0.4798169f), new Vector2(0.2183099f, 0.483338f), new Vector2(0.1619718f, 0.4727746f), new Vector2(0.1126761f, 0.4481267f), new Vector2(0.07922542f, 0.4164366f), new Vector2(0.04929578f, 0.3724225f), new Vector2(0.03521132f, 0.3143239f), new Vector2(0.03521132f, 0.3847465f), new Vector2(0.05985922f, 0.4446057f), new Vector2(0.1073943f, 0.5009437f), new Vector2(0.1514084f, 0.5343943f), new Vector2(0.2024648f, 0.5608028f), new Vector2(0.2535211f, 0.5713662f), new Vector2(0.2376761f, 0.6171408f), new Vector2(0.2323943f, 0.6805211f), new Vector2(0.2411972f, 0.745662f), new Vector2(0.2640845f, 0.8090422f), new Vector2(0.3080986f, 0.8671408f), new Vector2(0.3556338f, 0.9041127f), new Vector2(0.4207746f, 0.9252395f), new Vector2(0.3591549f, 0.886507f), new Vector2(0.3274648f, 0.8477746f), new Vector2(0.3010563f, 0.7984789f), new Vector2(0.2940141f, 0.7386197f), new Vector2(0.3028169f, 0.6699578f), new Vector2(0.3292254f, 0.620662f), new Vector2(0.3679578f, 0.5784084f), new Vector2(0.4225352f, 0.5449578f), new Vector2(0.4753521f, 0.5361549f) }, new Vector3[] { new Vector2(0.582207f, 0.3510769f), new Vector2(0.542565f, 0.3739641f), new Vector2(0.5283079f, 0.3598334f), new Vector2(0.5027334f, 0.3542696f), new Vector2(0.4763418f, 0.361375f), new Vector2(0.460042f, 0.3789175f), new Vector2(0.4206188f, 0.3528882f), new Vector2(0.4372641f, 0.3148172f), new Vector2(0.4442263f, 0.2599745f), new Vector2(0.4383465f, 0.2145791f), new Vector2(0.4079451f, 0.1548802f), new Vector2(0.3706279f, 0.1113717f), new Vector2(0.3246343f, 0.08100431f), new Vector2(0.2804645f, 0.0678802f), new Vector2(0.2273824f, 0.06396741f), new Vector2(0.1700253f, 0.0808192f), new Vector2(0.2310131f, 0.0456079f), new Vector2(0.2951766f, 0.037024f), new Vector2(0.3677343f, 0.0500216f), new Vector2(0.4187104f, 0.07141361f), new Vector2(0.467109f, 0.1024256f), new Vector2(0.5017853f, 0.1413599f), new Vector2(0.5335048f, 0.1047504f), new Vector2(0.5857528f, 0.06848609f), new Vector2(0.6465681f, 0.0435392f), new Vector2(0.7129006f, 0.03167f), new Vector2(0.7852224f, 0.0407381f), new Vector2(0.8410087f, 0.06341881f), new Vector2(0.8918754f, 0.109269f), new Vector2(0.8275222f, 0.0752711f), new Vector2(0.7781339f, 0.06719281f), new Vector2(0.7222384f, 0.0689702f), new Vector2(0.6668776f, 0.09280109f), new Vector2(0.6118161f, 0.1347555f), new Vector2(0.5823289f, 0.1822739f), new Vector2(0.5651024f, 0.2369439f), new Vector2(0.563422f, 0.3009346f), new Vector2(0.582207f, 0.3510769f) }, new Vector3[] { new Vector2(0.4070987f, 0.259048f), new Vector2(0.3858456f, 0.1940673f), new Vector2(0.3253296f, 0.237138f), new Vector2(0.291441f, 0.2770328f), new Vector2(0.265239f, 0.3267201f), new Vector2(0.251062f, 0.3796295f), new Vector2(0.2497901f, 0.4372857f), new Vector2(0.3067387f, 0.4267686f), new Vector2(0.3083097f, 0.3872361f), new Vector2(0.3251275f, 0.3389008f), new Vector2(0.3511568f, 0.2994776f), new Vector2(0.3802986f, 0.272488f), new Vector2(0.4070987f, 0.259048f) }, new Vector3[] { new Vector2(0.6919014f, 0.4305211f), new Vector2(0.7588028f, 0.4446057f), new Vector2(0.7517605f, 0.370662f), new Vector2(0.7341549f, 0.3213662f), new Vector2(0.7042254f, 0.273831f), new Vector2(0.665493f, 0.2350986f), new Vector2(0.6161972f, 0.205169f), new Vector2(0.596831f, 0.2597465f), new Vector2(0.6302817f, 0.2808733f), new Vector2(0.6637324f, 0.3196056f), new Vector2(0.6848592f, 0.3618592f), new Vector2(0.693662f, 0.4005915f), new Vector2(0.6919014f, 0.4305211f) }, new Vector3[] { new Vector2(0.4059011f, 0.5936667f), new Vector2(0.4409888f, 0.6112105f), new Vector2(0.4984051f, 0.6207799f), new Vector2(0.5478469f, 0.6175901f), new Vector2(0.5972887f, 0.5920718f), new Vector2(0.638756f, 0.6383237f), new Vector2(0.6036683f, 0.6606523f), new Vector2(0.562201f, 0.6750064f), new Vector2(0.5127591f, 0.6813859f), new Vector2(0.453748f, 0.6766013f), new Vector2(0.4027113f, 0.6606523f), new Vector2(0.3596491f, 0.6415135f), new Vector2(0.4059011f, 0.5936667f) } }; } return icon_biohazardWarning; } + Vector3[][] Icon_fireWarning() { if (icon_fireWarning == null) { icon_fireWarning = new Vector3[][] { new Vector3[] { new Vector2(0.05685619f, 0.1722408f), new Vector2(0.05518395f, 0.1438127f), new Vector2(0.06187291f, 0.1137124f), new Vector2(0.08361204f, 0.09364548f), new Vector2(0.1120401f, 0.08026756f), new Vector2(0.861204f, 0.08026756f), new Vector2(0.8946488f, 0.09030101f), new Vector2(0.9197325f, 0.1086956f), new Vector2(0.9280937f, 0.1404682f), new Vector2(0.9247491f, 0.1755853f), new Vector2(0.5535117f, 0.8244147f), new Vector2(0.5317726f, 0.8494983f), new Vector2(0.4949833f, 0.8595318f), new Vector2(0.4548495f, 0.8511705f), new Vector2(0.4314381f, 0.8277592f), new Vector2(0.05685619f, 0.1722408f) }, new Vector3[] { new Vector2(0.404943f, 0.2376426f), new Vector2(0.3441065f, 0.269962f), new Vector2(0.3117871f, 0.3326996f), new Vector2(0.3022814f, 0.4144487f), new Vector2(0.3346007f, 0.4809886f), new Vector2(0.3897339f, 0.5418251f), new Vector2(0.3973384f, 0.5038023f), new Vector2(0.4201521f, 0.4847909f), new Vector2(0.4239544f, 0.5551331f), new Vector2(0.460076f, 0.6026616f), new Vector2(0.5494297f, 0.6596958f), new Vector2(0.5304183f, 0.5779468f), new Vector2(0.5475285f, 0.5285171f), new Vector2(0.5779468f, 0.4904943f), new Vector2(0.6007605f, 0.5361217f), new Vector2(0.6330798f, 0.5437263f), new Vector2(0.6178707f, 0.4809886f), new Vector2(0.6501901f, 0.4125475f), new Vector2(0.6692015f, 0.3498099f), new Vector2(0.6520913f, 0.2889734f), new Vector2(0.6007605f, 0.2585551f), new Vector2(0.526616f, 0.2395437f), new Vector2(0.5570342f, 0.2775666f), new Vector2(0.5627376f, 0.3231939f), new Vector2(0.5304183f, 0.365019f), new Vector2(0.473384f, 0.4125475f), new Vector2(0.4885932f, 0.473384f), new Vector2(0.4315589f, 0.4201521f), new Vector2(0.4068441f, 0.3555133f), new Vector2(0.4182509f, 0.2984791f), new Vector2(0.3669201f, 0.3250951f), new Vector2(0.3669201f, 0.2870722f), new Vector2(0.404943f, 0.2376426f) }, new Vector3[] { new Vector2(0.2984791f, 0.1711027f), new Vector2(0.6825095f, 0.1711027f) } }; } return icon_fireWarning; } + Vector3[][] Icon_warning() { if (icon_warning == null) { icon_warning = new Vector3[][] { new Vector3[] { new Vector2(0.05685619f, 0.1722408f), new Vector2(0.05518395f, 0.1438127f), new Vector2(0.06187291f, 0.1137124f), new Vector2(0.08361204f, 0.09364548f), new Vector2(0.1120401f, 0.08026756f), new Vector2(0.861204f, 0.08026756f), new Vector2(0.8946488f, 0.09030101f), new Vector2(0.9197325f, 0.1086956f), new Vector2(0.9280937f, 0.1404682f), new Vector2(0.9247491f, 0.1755853f), new Vector2(0.5535117f, 0.8244147f), new Vector2(0.5317726f, 0.8494983f), new Vector2(0.4949833f, 0.8595318f), new Vector2(0.4548495f, 0.8511705f), new Vector2(0.4314381f, 0.8277592f), new Vector2(0.05685619f, 0.1722408f) }, new Vector3[] { new Vector2(0.4481605f, 0.2993311f), new Vector2(0.4481605f, 0.2123746f), new Vector2(0.5334448f, 0.2123746f), new Vector2(0.5334448f, 0.2976589f), new Vector2(0.4481605f, 0.2993311f) }, new Vector3[] { new Vector2(0.4481605f, 0.3879599f), new Vector2(0.4481605f, 0.6454849f), new Vector2(0.5334448f, 0.6454849f), new Vector2(0.5334448f, 0.3879599f), new Vector2(0.4481605f, 0.3879599f) } }; } return icon_warning; } + Vector3[][] Icon_emergencyExit() { if (icon_emergencyExit == null) { icon_emergencyExit = new Vector3[][] { new Vector3[] { new Vector2(0.1054965f, 0.4698582f), new Vector2(0.1054965f, 0.7375886f), new Vector2(0.3891844f, 0.7375886f), new Vector2(0.3891844f, 0.5673759f), new Vector2(0.3466312f, 0.5602837f), new Vector2(0.3005319f, 0.6205674f), new Vector2(0.1710993f, 0.6205674f), new Vector2(0.1320922f, 0.5531915f), new Vector2(0.1356383f, 0.5372341f), new Vector2(0.162234f, 0.5443262f), new Vector2(0.1870567f, 0.5904256f), new Vector2(0.2260638f, 0.5904256f), new Vector2(0.1870567f, 0.5159575f), new Vector2(0.1870567f, 0.4432624f), new Vector2(0.1037234f, 0.4432624f), new Vector2(0.06294326f, 0.4007092f), new Vector2(0.2083333f, 0.4007092f), new Vector2(0.2260638f, 0.4202128f), new Vector2(0.2260638f, 0.4840426f), new Vector2(0.3058511f, 0.3492908f), new Vector2(0.3484043f, 0.3492908f), new Vector2(0.2721631f, 0.5124114f), new Vector2(0.2952128f, 0.570922f), new Vector2(0.3306738f, 0.5265958f), new Vector2(0.3909574f, 0.5265958f), new Vector2(0.3909574f, 0.3351064f), new Vector2(0.3608156f, 0.2978723f) }, new Vector3[] { new Vector2(0.2774823f, 0.6382979f), new Vector2(0.302305f, 0.6382979f), new Vector2(0.3218085f, 0.6542553f), new Vector2(0.3218085f, 0.680851f), new Vector2(0.3076241f, 0.7021276f), new Vector2(0.2757092f, 0.7021276f), new Vector2(0.2579787f, 0.6843972f), new Vector2(0.2579787f, 0.6560284f), new Vector2(0.2774823f, 0.6382979f) }, new Vector3[] { new Vector2(0.02216312f, 0.2943262f), new Vector2(0.9742908f, 0.2943262f), new Vector2(0.9742908f, 0.7712766f), new Vector2(0.02216312f, 0.7712766f), new Vector2(0.02216312f, 0.2943262f) }, new Vector3[] { new Vector2(0.9193262f, 0.535461f), new Vector2(0.7597518f, 0.3794326f), new Vector2(0.6462766f, 0.3794326f), new Vector2(0.7544326f, 0.4840426f), new Vector2(0.5735816f, 0.4840426f), new Vector2(0.5735816f, 0.5744681f), new Vector2(0.7544326f, 0.5744681f), new Vector2(0.6462766f, 0.6826241f), new Vector2(0.7579787f, 0.6826241f), new Vector2(0.9193262f, 0.535461f) }, new Vector3[] { new Vector2(0.07358156f, 0.2960993f), new Vector2(0.1072695f, 0.3297872f), new Vector2(0.1072695f, 0.3687943f) }, new Vector3[] { new Vector2(0.2650709f, 0.2960993f), new Vector2(0.304078f, 0.3333333f), new Vector2(0.3430851f, 0.3333333f), new Vector2(0.3058511f, 0.2978723f) } }; } return icon_emergencyExit; } + Vector3[][] Icon_sun() { if (icon_sun == null) { icon_sun = new Vector3[][] { new Vector3[] { new Vector2(0.501125f, 0.2987834f), new Vector2(0.4220634f, 0.3145957f), new Vector2(0.3631265f, 0.3526891f), new Vector2(0.3207207f, 0.4123447f), new Vector2(0.3013147f, 0.495f), new Vector2(0.3156896f, 0.5726242f), new Vector2(0.3652828f, 0.6444983f), new Vector2(0.4249384f, 0.6825917f), new Vector2(0.504f, 0.6962478f), new Vector2(0.5895303f, 0.6768418f), new Vector2(0.649186f, 0.6308423f), new Vector2(0.6872793f, 0.5690305f), new Vector2(0.6994979f, 0.495f), new Vector2(0.6815293f, 0.4130634f), new Vector2(0.6412798f, 0.3548453f), new Vector2(0.5787492f, 0.3153145f), new Vector2(0.501125f, 0.2987834f) }, new Vector3[] { new Vector2(0.503268f, 0.753268f), new Vector2(0.503268f, 0.9526144f) }, new Vector3[] { new Vector2(0.5f, 0.253268f), new Vector2(0.5f, 0.04411765f) }, new Vector3[] { new Vector2(0.75f, 0.5f), new Vector2(0.9493464f, 0.5f) }, new Vector3[] { new Vector2(0.2418301f, 0.5f), new Vector2(0.0375817f, 0.5f) }, new Vector3[] { new Vector2(0.6830065f, 0.6748366f), new Vector2(0.8218954f, 0.8235294f) }, new Vector3[] { new Vector2(0.3251634f, 0.6830065f), new Vector2(0.1781046f, 0.8284314f) }, new Vector3[] { new Vector2(0.6748366f, 0.3186274f), new Vector2(0.8218954f, 0.1781046f) }, new Vector3[] { new Vector2(0.3120915f, 0.3300654f), new Vector2(0.1683007f, 0.1813726f) } }; } return icon_sun; } + Vector3[][] Icon_rain() { if (icon_rain == null) { icon_rain = new Vector3[][] { new Vector3[] { new Vector2(0.20626f, 0.6853933f), new Vector2(0.1966292f, 0.7817014f), new Vector2(0.2191011f, 0.858748f), new Vector2(0.2833066f, 0.9309791f), new Vector2(0.3523274f, 0.9582664f), new Vector2(0.4357945f, 0.964687f), new Vector2(0.5176565f, 0.9309791f), new Vector2(0.570626f, 0.8812199f), new Vector2(0.6011236f, 0.8250401f), new Vector2(0.6460674f, 0.8651685f), new Vector2(0.711878f, 0.8715891f), new Vector2(0.7889246f, 0.8378812f), new Vector2(0.8370786f, 0.7720706f), new Vector2(0.8483146f, 0.6966292f), new Vector2(0.8258427f, 0.6388443f), new Vector2(0.8804173f, 0.6276084f), new Vector2(0.9414125f, 0.576244f), new Vector2(0.9670947f, 0.5152488f), new Vector2(0.9622793f, 0.4478331f), new Vector2(0.9382023f, 0.399679f), new Vector2(0.8964687f, 0.364366f), new Vector2(0.8322632f, 0.3467095f), new Vector2(0.1629214f, 0.3467095f), new Vector2(0.1019262f, 0.3756019f), new Vector2(0.0505618f, 0.4365971f), new Vector2(0.03611557f, 0.5152488f), new Vector2(0.06019261f, 0.6035313f), new Vector2(0.1019262f, 0.6597111f), new Vector2(0.1532905f, 0.6869984f), new Vector2(0.20626f, 0.6853933f) }, new Vector3[] { new Vector2(0.2704655f, 0.3113965f), new Vector2(0.2271268f, 0.2680578f), new Vector2(0.2399679f, 0.2423756f), new Vector2(0.2720706f, 0.258427f), new Vector2(0.2704655f, 0.3113965f) }, new Vector3[] { new Vector2(0.2239165f, 0.2022472f), new Vector2(0.1853933f, 0.1589085f), new Vector2(0.1998395f, 0.1364366f), new Vector2(0.2287319f, 0.1492777f), new Vector2(0.2239165f, 0.2022472f) }, new Vector3[] { new Vector2(0.1789727f, 0.09149278f), new Vector2(0.1452648f, 0.05457464f), new Vector2(0.1532905f, 0.03210273f), new Vector2(0.1789727f, 0.04173355f), new Vector2(0.1789727f, 0.09149278f) }, new Vector3[] { new Vector2(0.5192617f, 0.3113965f), new Vector2(0.4807384f, 0.2616372f), new Vector2(0.4935794f, 0.2439807f), new Vector2(0.5224719f, 0.2520064f), new Vector2(0.5192617f, 0.3113965f) }, new Vector3[] { new Vector2(0.4775281f, 0.2038523f), new Vector2(0.4422151f, 0.1605136f), new Vector2(0.4518459f, 0.1348315f), new Vector2(0.4759229f, 0.1476725f), new Vector2(0.4775281f, 0.2038523f) }, new Vector3[] { new Vector2(0.4309791f, 0.09149278f), new Vector2(0.3924558f, 0.0529695f), new Vector2(0.405297f, 0.02728732f), new Vector2(0.429374f, 0.04012841f), new Vector2(0.4309791f, 0.09149278f) }, new Vector3[] { new Vector2(0.7696629f, 0.3146068f), new Vector2(0.7279294f, 0.2664526f), new Vector2(0.7439808f, 0.2407705f), new Vector2(0.7680578f, 0.2552167f), new Vector2(0.7696629f, 0.3146068f) }, new Vector3[] { new Vector2(0.7247191f, 0.2022472f), new Vector2(0.6845907f, 0.1589085f), new Vector2(0.6942215f, 0.1348315f), new Vector2(0.723114f, 0.1444623f), new Vector2(0.7247191f, 0.2022472f) }, new Vector3[] { new Vector2(0.676565f, 0.09309791f), new Vector2(0.6428571f, 0.05136437f), new Vector2(0.6508828f, 0.02889246f), new Vector2(0.6749599f, 0.04333868f), new Vector2(0.676565f, 0.09309791f) } }; } return icon_rain; } + Vector3[][] Icon_wind() { if (icon_wind == null) { icon_wind = new Vector3[][] { new Vector3[] { new Vector2(0.0505618f, 0.4060995f), new Vector2(0.1099518f, 0.3900481f), new Vector2(0.1837881f, 0.3916533f), new Vector2(0.2704655f, 0.4109149f), new Vector2(0.3443018f, 0.4333868f), new Vector2(0.4036918f, 0.4446228f), new Vector2(0.4855538f, 0.4430177f), new Vector2(0.5722311f, 0.4044944f), new Vector2(0.6091493f, 0.3659711f), new Vector2(0.6155698f, 0.3274478f), new Vector2(0.605939f, 0.3081862f), new Vector2(0.5770466f, 0.2889245f), new Vector2(0.5321027f, 0.2857143f), new Vector2(0.5032102f, 0.2953451f), new Vector2(0.488764f, 0.3274478f) }, new Vector3[] { new Vector2(0.3394864f, 0.5008026f), new Vector2(0.3956661f, 0.5216693f), new Vector2(0.4775281f, 0.5232745f), new Vector2(0.5497592f, 0.5008026f), new Vector2(0.6878009f, 0.4654896f), new Vector2(0.8226324f, 0.4430177f), new Vector2(0.8980739f, 0.4478331f), new Vector2(0.9414125f, 0.4686998f), new Vector2(0.9574639f, 0.5008026f), new Vector2(0.9622793f, 0.5393258f), new Vector2(0.9494382f, 0.5634029f), new Vector2(0.9157304f, 0.5826645f), new Vector2(0.8820225f, 0.5826645f), new Vector2(0.8451043f, 0.5714286f), new Vector2(0.829053f, 0.5569823f), new Vector2(0.8210273f, 0.529695f), new Vector2(0.8258427f, 0.5040128f) }, new Vector3[] { new Vector2(0.2688603f, 0.5714286f), new Vector2(0.3619583f, 0.6051365f), new Vector2(0.4277689f, 0.6147673f), new Vector2(0.4903692f, 0.5971107f), new Vector2(0.5642055f, 0.5714286f), new Vector2(0.6348315f, 0.5730337f), new Vector2(0.7038524f, 0.5987159f), new Vector2(0.7455859f, 0.6340289f), new Vector2(0.7680578f, 0.6725522f), new Vector2(0.7616372f, 0.7030498f), new Vector2(0.7391653f, 0.7223114f), new Vector2(0.6974318f, 0.7287319f), new Vector2(0.665329f, 0.7191011f), new Vector2(0.6428571f, 0.6982344f), new Vector2(0.6396469f, 0.6741573f), new Vector2(0.6508828f, 0.6484751f) } }; } return icon_wind; } + Vector3[][] Icon_snow() { if (icon_snow == null) { icon_snow = new Vector3[][] { new Vector3[] { new Vector2(0.060477f, 0.5025554f), new Vector2(0.9412266f, 0.5025554f) }, new Vector3[] { new Vector2(0.7180579f, 0.8892674f), new Vector2(0.2785349f, 0.1243612f) }, new Vector3[] { new Vector2(0.2836457f, 0.8858603f), new Vector2(0.7231687f, 0.1192504f) }, new Vector3[] { new Vector2(0.8270869f, 0.7597955f), new Vector2(0.6448041f, 0.7597955f), new Vector2(0.5562181f, 0.9131175f) }, new Vector3[] { new Vector2(0.1729131f, 0.7614992f), new Vector2(0.3551959f, 0.7614992f), new Vector2(0.4420784f, 0.9165247f) }, new Vector3[] { new Vector2(0.1149915f, 0.350937f), new Vector2(0.2018739f, 0.5042589f), new Vector2(0.1132879f, 0.6575809f) }, new Vector3[] { new Vector2(0.883305f, 0.6626917f), new Vector2(0.7964225f, 0.5042589f), new Vector2(0.8867121f, 0.3492334f) }, new Vector3[] { new Vector2(0.1780238f, 0.2487223f), new Vector2(0.3500852f, 0.2487223f), new Vector2(0.4454855f, 0.09028961f) }, new Vector3[] { new Vector2(0.8270869f, 0.2453152f), new Vector2(0.6516184f, 0.2453152f), new Vector2(0.5579216f, 0.09028961f) } }; } return icon_snow; } + Vector3[][] Icon_lightning() { if (icon_lightning == null) { icon_lightning = new Vector3[][] { new Vector3[] { new Vector2(0.3731942f, 0.8764045f), new Vector2(0.5545747f, 0.9711075f), new Vector2(0.4390048f, 0.5136437f), new Vector2(0.7905297f, 0.682183f), new Vector2(0.5914928f, 0.200642f), new Vector2(0.6781701f, 0.2150883f), new Vector2(0.4903692f, 0.01605137f), new Vector2(0.4614767f, 0.2873194f), new Vector2(0.5128411f, 0.2279294f), new Vector2(0.5802568f, 0.505618f), new Vector2(0.2897271f, 0.3467095f), new Vector2(0.3731942f, 0.8764045f) } }; } return icon_lightning; } + Vector3[][] Icon_fire() { if (icon_fire == null) { icon_fire = new Vector3[][] { new Vector3[] { new Vector2(0.3651685f, 0.04815409f), new Vector2(0.2865168f, 0.07223114f), new Vector2(0.2126806f, 0.1235955f), new Vector2(0.14687f, 0.2215088f), new Vector2(0.1227929f, 0.3370787f), new Vector2(0.1372392f, 0.4462279f), new Vector2(0.170947f, 0.5473515f), new Vector2(0.2303371f, 0.6292135f), new Vector2(0.3154093f, 0.7110754f), new Vector2(0.312199f, 0.6597111f), new Vector2(0.3330658f, 0.6131621f), new Vector2(0.3747994f, 0.5858748f), new Vector2(0.3715891f, 0.6789727f), new Vector2(0.4069021f, 0.7624398f), new Vector2(0.4759229f, 0.8410915f), new Vector2(0.5529695f, 0.8956661f), new Vector2(0.6621188f, 0.9598716f), new Vector2(0.6252006f, 0.8715891f), new Vector2(0.6187801f, 0.7800963f), new Vector2(0.6348315f, 0.7030498f), new Vector2(0.7070626f, 0.5842696f), new Vector2(0.7134832f, 0.6452649f), new Vector2(0.7504013f, 0.6837881f), new Vector2(0.7873194f, 0.7030498f), new Vector2(0.8386838f, 0.70626f), new Vector2(0.8049759f, 0.6484751f), new Vector2(0.7953451f, 0.5971107f), new Vector2(0.8033708f, 0.540931f), new Vector2(0.8338684f, 0.4815409f), new Vector2(0.8804173f, 0.4093098f), new Vector2(0.9044944f, 0.3386838f), new Vector2(0.9060995f, 0.2808989f), new Vector2(0.8916533f, 0.2263242f), new Vector2(0.8515249f, 0.1685393f), new Vector2(0.79374f, 0.1252006f), new Vector2(0.7391653f, 0.09149278f), new Vector2(0.6749599f, 0.06741573f), new Vector2(0.5995185f, 0.05136437f), new Vector2(0.6540931f, 0.1043339f), new Vector2(0.6781701f, 0.1573034f), new Vector2(0.6797753f, 0.2150883f), new Vector2(0.6573034f, 0.2712681f), new Vector2(0.6123595f, 0.3194222f), new Vector2(0.5609952f, 0.3595506f), new Vector2(0.5208668f, 0.4012841f), new Vector2(0.4919743f, 0.4526485f), new Vector2(0.4983949f, 0.4991974f), new Vector2(0.5160514f, 0.5505618f), new Vector2(0.4470305f, 0.4911717f), new Vector2(0.3924558f, 0.4253612f), new Vector2(0.3619583f, 0.3739968f), new Vector2(0.3491172f, 0.3146068f), new Vector2(0.3507223f, 0.2568218f), new Vector2(0.3715891f, 0.1958266f), new Vector2(0.334671f, 0.1910112f), new Vector2(0.2929374f, 0.1974318f), new Vector2(0.2608347f, 0.2327448f), new Vector2(0.2576244f, 0.1717496f), new Vector2(0.2736758f, 0.1284109f), new Vector2(0.312199f, 0.0882825f), new Vector2(0.3651685f, 0.04815409f) } }; } return icon_fire; } + Vector3[][] Icon_unitSquare() { if (icon_unitSquare == null) { icon_unitSquare = new Vector3[][] { new Vector3[] { new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f), new Vector2(1.0f, 1.0f), new Vector2(0.0f, 1.0f), new Vector2(0.0f, 0.0f) } }; } return icon_unitSquare; } + Vector3[][] Icon_unitSquareIncl1Right() { if (icon_unitSquareIncl1Right == null) { icon_unitSquareIncl1Right = new Vector3[][] { new Vector3[] { new Vector2(0.0f, 0.0f), new Vector2(2.0f, 0.0f), new Vector2(2.0f, 1.0f), new Vector2(0.0f, 1.0f), new Vector2(0.0f, 0.0f) } }; } return icon_unitSquareIncl1Right; } + Vector3[][] Icon_unitSquareIncl2Right() { if (icon_unitSquareIncl2Right == null) { icon_unitSquareIncl2Right = new Vector3[][] { new Vector3[] { new Vector2(0.0f, 0.0f), new Vector2(3.0f, 0.0f), new Vector2(3.0f, 1.0f), new Vector2(0.0f, 1.0f), new Vector2(0.0f, 0.0f) } }; } return icon_unitSquareIncl2Right; } + Vector3[][] Icon_unitSquareIncl3Right() { if (icon_unitSquareIncl3Right == null) { icon_unitSquareIncl3Right = new Vector3[][] { new Vector3[] { new Vector2(0.0f, 0.0f), new Vector2(4.0f, 0.0f), new Vector2(4.0f, 1.0f), new Vector2(0.0f, 1.0f), new Vector2(0.0f, 0.0f) } }; } return icon_unitSquareIncl3Right; } + Vector3[][] Icon_unitSquareIncl4Right() { if (icon_unitSquareIncl4Right == null) { icon_unitSquareIncl4Right = new Vector3[][] { new Vector3[] { new Vector2(0.0f, 0.0f), new Vector2(5.0f, 0.0f), new Vector2(5.0f, 1.0f), new Vector2(0.0f, 1.0f), new Vector2(0.0f, 0.0f) } }; } return icon_unitSquareIncl4Right; } + Vector3[][] Icon_unitSquareIncl5Right() { if (icon_unitSquareIncl5Right == null) { icon_unitSquareIncl5Right = new Vector3[][] { new Vector3[] { new Vector2(0.0f, 0.0f), new Vector2(6.0f, 0.0f), new Vector2(6.0f, 1.0f), new Vector2(0.0f, 1.0f), new Vector2(0.0f, 0.0f) } }; } return icon_unitSquareIncl5Right; } + Vector3[][] Icon_unitSquareIncl6Right() { if (icon_unitSquareIncl6Right == null) { icon_unitSquareIncl6Right = new Vector3[][] { new Vector3[] { new Vector2(0.0f, 0.0f), new Vector2(7.0f, 0.0f), new Vector2(7.0f, 1.0f), new Vector2(0.0f, 1.0f), new Vector2(0.0f, 0.0f) } }; } return icon_unitSquareIncl6Right; } + Vector3[][] Icon_unitSquareCrossed() { if (icon_unitSquareCrossed == null) { icon_unitSquareCrossed = new Vector3[][] { new Vector3[] { new Vector2(0.5f, 1.0f), new Vector2(0.5f, 0.0f) }, new Vector3[] { new Vector2(0.0f, 1.0f), new Vector2(0.0f, 0.0f) }, new Vector3[] { new Vector2(1.0f, 1.0f), new Vector2(1.0f, 0.0f) }, new Vector3[] { new Vector2(0.0f, 0.5f), new Vector2(1.0f, 0.5f) }, new Vector3[] { new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f) }, new Vector3[] { new Vector2(0.0f, 1.0f), new Vector2(1.0f, 1.0f) } }; } return icon_unitSquareCrossed; } + Vector3[][] Icon_unitCircle() { if (icon_unitCircle == null) { icon_unitCircle = new Vector3[][] { new Vector3[] { new Vector2(0.5f, 0.0f), new Vector2(0.30366f, 0.03569004f), new Vector2(0.15524f, 0.13162f), new Vector2(0.04845002f, 0.2818501f), new Vector2(0.0f, 0.5f), new Vector2(0.03578001f, 0.6854801f), new Vector2(0.16067f, 0.86648f), new Vector2(0.3109f, 0.9624101f), new Vector2(0.5f, 1.0f), new Vector2(0.7253899f, 0.94793f), new Vector2(0.87562f, 0.83209f), new Vector2(0.97155f, 0.6764301f), new Vector2(1.0f, 0.5f), new Vector2(0.95707f, 0.2836601f), new Vector2(0.85571f, 0.1370501f), new Vector2(0.69824f, 0.03750008f), new Vector2(0.5f, 0.0f) } }; } return icon_unitCircle; } + Vector3[][] Icon_animal() { if (icon_animal == null) { icon_animal = new Vector3[][] { new Vector3[] { new Vector2(0.3593156f, 0.4923954f), new Vector2(0.3403042f, 0.3117871f), new Vector2(0.2642586f, 0.1977186f), new Vector2(0.1901141f, 0.1977186f), new Vector2(0.1920152f, 0.2338403f), new Vector2(0.2243346f, 0.2395437f), new Vector2(0.2794677f, 0.3307985f), new Vector2(0.2623574f, 0.4809886f), new Vector2(0.2224335f, 0.513308f), new Vector2(0.1882129f, 0.5665399f), new Vector2(0.161597f, 0.5931559f), new Vector2(0.07604562f, 0.581749f), new Vector2(0.05323194f, 0.6102661f), new Vector2(0.05893536f, 0.6634981f), new Vector2(0.1406844f, 0.6939163f), new Vector2(0.1463878f, 0.7224334f), new Vector2(0.1692015f, 0.7376426f), new Vector2(0.2053232f, 0.7414449f), new Vector2(0.2281369f, 0.7889734f), new Vector2(0.2585551f, 0.7870722f), new Vector2(0.2623574f, 0.7262357f), new Vector2(0.2851711f, 0.7110266f), new Vector2(0.2908745f, 0.6634981f), new Vector2(0.4144487f, 0.6235741f), new Vector2(0.539924f, 0.6159696f), new Vector2(0.621673f, 0.6406844f), new Vector2(0.6749049f, 0.6444867f), new Vector2(0.7357414f, 0.6273764f), new Vector2(0.7851711f, 0.581749f), new Vector2(0.7946768f, 0.5171103f), new Vector2(0.7832699f, 0.4562738f), new Vector2(0.7604563f, 0.404943f) }, new Vector3[] { new Vector2(0.5722433f, 0.4904943f), new Vector2(0.6235741f, 0.4068441f), new Vector2(0.6634981f, 0.3631179f), new Vector2(0.6463878f, 0.2414449f), new Vector2(0.6026616f, 0.230038f), new Vector2(0.608365f, 0.1863118f), new Vector2(0.6863118f, 0.1863118f), new Vector2(0.7376426f, 0.3479087f), new Vector2(0.7357414f, 0.4752852f) }, new Vector3[] { new Vector2(0.621673f, 0.4068441f), new Vector2(0.5475285f, 0.3859316f), new Vector2(0.4752852f, 0.391635f), new Vector2(0.3840304f, 0.4144487f), new Vector2(0.3935361f, 0.28327f), new Vector2(0.3612167f, 0.1977186f), new Vector2(0.2946768f, 0.2015209f), new Vector2(0.2984791f, 0.2357415f), new Vector2(0.3365019f, 0.2509506f), new Vector2(0.3460076f, 0.3365019f) }, new Vector3[] { new Vector2(0.7851711f, 0.5836502f), new Vector2(0.8079848f, 0.5779468f), new Vector2(0.838403f, 0.5418251f), new Vector2(0.8498099f, 0.4904943f), new Vector2(0.8612167f, 0.4220532f), new Vector2(0.8954372f, 0.3821293f), new Vector2(0.9334601f, 0.3669201f), new Vector2(0.9714829f, 0.3688213f), new Vector2(0.9277567f, 0.3346007f), new Vector2(0.8764259f, 0.3346007f), new Vector2(0.8422053f, 0.365019f), new Vector2(0.8193916f, 0.4296578f), new Vector2(0.8136882f, 0.486692f), new Vector2(0.8079848f, 0.5152091f), new Vector2(0.7927757f, 0.5323194f) }, new Vector3[] { new Vector2(0.7281369f, 0.3155894f), new Vector2(0.7642586f, 0.2509506f), new Vector2(0.7262357f, 0.2338403f), new Vector2(0.730038f, 0.1977186f), new Vector2(0.8060837f, 0.1996198f), new Vector2(0.8022814f, 0.3612167f), new Vector2(0.7813688f, 0.4486692f) }, new Vector3[] { new Vector2(0.07794677f, 0.5874525f), new Vector2(0.1064639f, 0.6102661f) }, new Vector3[] { new Vector2(0.1558935f, 0.7053232f), new Vector2(0.1577947f, 0.6787072f), new Vector2(0.1977186f, 0.6958175f), new Vector2(0.1558935f, 0.7053232f) } }; } return icon_animal; } + Vector3[][] Icon_bird() { if (icon_bird == null) { icon_bird = new Vector3[][] { new Vector3[] { new Vector2(0.5722433f, 0.3897339f), new Vector2(0.5380228f, 0.4334601f), new Vector2(0.5304183f, 0.4581749f), new Vector2(0.5494297f, 0.4752852f), new Vector2(0.6387833f, 0.513308f), new Vector2(0.7262357f, 0.5304183f), new Vector2(0.8250951f, 0.526616f), new Vector2(0.8821293f, 0.5057034f), new Vector2(0.9676806f, 0.4467681f), new Vector2(0.8821293f, 0.5323194f), new Vector2(0.7984791f, 0.5798479f), new Vector2(0.7072243f, 0.5969582f), new Vector2(0.6311787f, 0.5893536f), new Vector2(0.5494297f, 0.5551331f), new Vector2(0.5323194f, 0.5779468f), new Vector2(0.5057034f, 0.5912548f), new Vector2(0.4676806f, 0.5931559f), new Vector2(0.4467681f, 0.5741445f), new Vector2(0.4334601f, 0.5513308f), new Vector2(0.3460076f, 0.5893536f), new Vector2(0.2528517f, 0.5931559f), new Vector2(0.1673004f, 0.5703422f), new Vector2(0.09315589f, 0.5285171f), new Vector2(0.03612167f, 0.460076f), new Vector2(0.1311787f, 0.5171103f), new Vector2(0.2205323f, 0.5342205f), new Vector2(0.3174905f, 0.5209125f), new Vector2(0.3954373f, 0.4923954f), new Vector2(0.4410646f, 0.4676806f), new Vector2(0.4562738f, 0.4391635f), new Vector2(0.4429658f, 0.4182509f), new Vector2(0.404943f, 0.3859316f), new Vector2(0.4695818f, 0.4144487f), new Vector2(0.5247148f, 0.4163498f), new Vector2(0.5722433f, 0.3897339f) }, new Vector3[] { new Vector2(0.473384f, 0.5076045f), new Vector2(0.4904943f, 0.4581749f), new Vector2(0.5114068f, 0.5076045f) } }; } return icon_bird; } + Vector3[][] Icon_humanMale() { if (icon_humanMale == null) { icon_humanMale = new Vector3[][] { new Vector3[] { new Vector2(0.6440536f, 0.6448911f), new Vector2(0.6440536f, 0.3886097f), new Vector2(0.657454f, 0.3685092f), new Vector2(0.6943049f, 0.3685092f), new Vector2(0.7077052f, 0.3936349f), new Vector2(0.7077052f, 0.6917923f), new Vector2(0.697655f, 0.7185929f), new Vector2(0.6775544f, 0.7437186f), new Vector2(0.6524288f, 0.758794f), new Vector2(0.618928f, 0.7654941f), new Vector2(0.3659967f, 0.7654941f), new Vector2(0.3358459f, 0.7571189f), new Vector2(0.3107203f, 0.7353434f), new Vector2(0.2922948f, 0.7051926f), new Vector2(0.2906198f, 0.6683417f), new Vector2(0.2906198f, 0.3902847f), new Vector2(0.3056951f, 0.3701842f), new Vector2(0.3324958f, 0.3701842f), new Vector2(0.3525963f, 0.3902847f), new Vector2(0.3525963f, 0.6499162f), new Vector2(0.3877722f, 0.6666667f), new Vector2(0.3877722f, 0.04522613f), new Vector2(0.4061977f, 0.02345059f), new Vector2(0.4463986f, 0.02345059f), new Vector2(0.4648241f, 0.05527638f), new Vector2(0.4648241f, 0.3902847f), new Vector2(0.5301508f, 0.3902847f), new Vector2(0.5301508f, 0.04690117f), new Vector2(0.5469012f, 0.02680067f), new Vector2(0.5887772f, 0.02680067f), new Vector2(0.6072027f, 0.05025126f), new Vector2(0.6072027f, 0.6649916f), new Vector2(0.6440536f, 0.6448911f) }, new Vector3[] { new Vector2(0.499f, 0.7972193f), new Vector2(0.4394741f, 0.8219008f), new Vector2(0.4159542f, 0.8762f), new Vector2(0.438603f, 0.9331126f), new Vector2(0.4975482f, 0.9583747f), new Vector2(0.5544607f, 0.9357259f), new Vector2(0.5774f, 0.8759096f), new Vector2(0.5541703f, 0.8192875f), new Vector2(0.499f, 0.7972193f) } }; } return icon_humanMale; } + Vector3[][] Icon_humanFemale() { if (icon_humanFemale == null) { icon_humanFemale = new Vector3[][] { new Vector3[] { new Vector2(0.7043551f, 0.4137353f), new Vector2(0.7294807f, 0.3919598f), new Vector2(0.7613065f, 0.4020101f), new Vector2(0.7680067f, 0.438861f), new Vector2(0.6792295f, 0.7018425f), new Vector2(0.6658291f, 0.7319933f), new Vector2(0.6340033f, 0.7554439f), new Vector2(0.5971524f, 0.7638191f), new Vector2(0.4011725f, 0.7638191f), new Vector2(0.3643216f, 0.7554439f), new Vector2(0.3324958f, 0.7303182f), new Vector2(0.3107203f, 0.6850922f), new Vector2(0.2319933f, 0.4321608f), new Vector2(0.2420436f, 0.4036851f), new Vector2(0.2621441f, 0.3969849f), new Vector2(0.298995f, 0.4170854f), new Vector2(0.3726968f, 0.6616415f), new Vector2(0.419598f, 0.6616415f), new Vector2(0.2906198f, 0.2546064f), new Vector2(0.3894472f, 0.2546064f), new Vector2(0.3894472f, 0.04355109f), new Vector2(0.4061977f, 0.02512563f), new Vector2(0.4463986f, 0.02512563f), new Vector2(0.4664991f, 0.05360134f), new Vector2(0.4664991f, 0.2546064f), new Vector2(0.5351759f, 0.2546064f), new Vector2(0.5351759f, 0.0519263f), new Vector2(0.5536013f, 0.02680067f), new Vector2(0.5871022f, 0.02680067f), new Vector2(0.6072027f, 0.0519263f), new Vector2(0.6072027f, 0.2529313f), new Vector2(0.7093802f, 0.2529313f), new Vector2(0.5837521f, 0.6566164f), new Vector2(0.6340033f, 0.6566164f), new Vector2(0.7043551f, 0.4137353f) }, new Vector3[] { new Vector2(0.499f, 0.7972193f), new Vector2(0.4394741f, 0.8219008f), new Vector2(0.4159542f, 0.8762f), new Vector2(0.438603f, 0.9331126f), new Vector2(0.4975482f, 0.9583747f), new Vector2(0.5544607f, 0.9357259f), new Vector2(0.5774f, 0.8759096f), new Vector2(0.5541703f, 0.8192875f), new Vector2(0.499f, 0.7972193f) } }; } return icon_humanFemale; } + Vector3[][] Icon_bombExplosion() { if (icon_bombExplosion == null) { icon_bombExplosion = new Vector3[][] { new Vector3[] { new Vector2(0.7787418f, 0.4381779f), new Vector2(0.8980477f, 0.4316703f), new Vector2(0.9696313f, 0.5878525f), new Vector2(0.8655097f, 0.5140998f), new Vector2(0.9370933f, 0.7245119f), new Vector2(0.824295f, 0.6225597f), new Vector2(0.8264642f, 0.878525f), new Vector2(0.7006508f, 0.6789588f), new Vector2(0.6789588f, 0.8004338f), new Vector2(0.64859f, 0.6876356f), new Vector2(0.5704989f, 0.9414316f), new Vector2(0.5704989f, 0.6659436f), new Vector2(0.5032538f, 0.7353579f), new Vector2(0.505423f, 0.6334056f), new Vector2(0.3492408f, 0.7809111f), new Vector2(0.4099783f, 0.6073753f), new Vector2(0.1778742f, 0.7093276f), new Vector2(0.318872f, 0.5075922f), new Vector2(0.2039046f, 0.5401301f), new Vector2(0.2906725f, 0.4620391f), new Vector2(0.04555314f, 0.4750542f), new Vector2(0.2971801f, 0.3752711f), new Vector2(0.2017354f, 0.3383948f), new Vector2(0.2993492f, 0.308026f), new Vector2(0.1084599f, 0.2125814f), new Vector2(0.4251627f, 0.2060737f), new Vector2(0.362256f, 0.1193059f), new Vector2(0.4859002f, 0.1409978f), new Vector2(0.516269f, 0.2451193f), new Vector2(0.4121475f, 0.2798265f), new Vector2(0.494577f, 0.3167028f), new Vector2(0.4295011f, 0.3665944f), new Vector2(0.4707158f, 0.3687636f), new Vector2(0.4425163f, 0.4078091f), new Vector2(0.5032538f, 0.3926247f), new Vector2(0.5227765f, 0.4707158f), new Vector2(0.5553145f, 0.4425163f), new Vector2(0.5553145f, 0.4924078f), new Vector2(0.5878525f, 0.4446855f), new Vector2(0.5965293f, 0.4989154f), new Vector2(0.6182213f, 0.4859002f), new Vector2(0.6442516f, 0.5227765f), new Vector2(0.6659436f, 0.4815618f), new Vector2(0.7223427f, 0.5639913f), new Vector2(0.7288503f, 0.4360087f), new Vector2(0.791757f, 0.483731f), new Vector2(0.7787418f, 0.4381779f) }, new Vector3[] { new Vector2(0.8481562f, 0.2668113f), new Vector2(0.8047723f, 0.2841648f), new Vector2(0.8004338f, 0.3232104f), new Vector2(0.7830803f, 0.3600868f), new Vector2(0.7548807f, 0.3904555f), new Vector2(0.7288503f, 0.4121475f), new Vector2(0.7071583f, 0.3817787f), new Vector2(0.7006508f, 0.4251627f), new Vector2(0.6659436f, 0.4273319f), new Vector2(0.6572668f, 0.3839479f), new Vector2(0.6399133f, 0.4273319f), new Vector2(0.6138828f, 0.4229935f), new Vector2(0.6247289f, 0.3752711f), new Vector2(0.5856833f, 0.4078091f), new Vector2(0.5748373f, 0.3926247f), new Vector2(0.5878525f, 0.362256f), new Vector2(0.5466378f, 0.3600868f), new Vector2(0.5422993f, 0.3383948f), new Vector2(0.5639913f, 0.3232104f), new Vector2(0.527115f, 0.308026f), new Vector2(0.5336226f, 0.2689805f), new Vector2(0.5574837f, 0.2668113f), new Vector2(0.5422993f, 0.2299349f), new Vector2(0.5639913f, 0.197397f), new Vector2(0.5856833f, 0.1778742f), new Vector2(0.616052f, 0.1605206f), new Vector2(0.6442516f, 0.1518438f), new Vector2(0.6876356f, 0.1496746f), new Vector2(0.7245119f, 0.1583514f), new Vector2(0.7440347f, 0.1713666f), new Vector2(0.7592191f, 0.1930586f), new Vector2(0.8156182f, 0.1735358f), new Vector2(0.8481562f, 0.2668113f) }, new Vector3[] { new Vector2(0.8286334f, 0.2190889f), new Vector2(0.8763558f, 0.1930586f) }, new Vector3[] { new Vector2(0.8655097f, 0.1995662f), new Vector2(0.8720173f, 0.2407809f), new Vector2(0.8828633f, 0.2060737f), new Vector2(0.9045553f, 0.2299349f), new Vector2(0.8937093f, 0.2039046f), new Vector2(0.9197397f, 0.1887202f), new Vector2(0.8937093f, 0.1887202f), new Vector2(0.9067245f, 0.1561822f), new Vector2(0.878525f, 0.1800434f), new Vector2(0.8655097f, 0.1475054f), new Vector2(0.8611714f, 0.1735358f), new Vector2(0.8373102f, 0.1713666f), new Vector2(0.8655097f, 0.1995662f) } }; } return icon_bombExplosion; } + Vector3[][] Icon_tower() { if (icon_tower == null) { icon_tower = new Vector3[][] { new Vector3[] { new Vector2(0.6792295f, 0.319933f), new Vector2(0.6792295f, 0.7001675f), new Vector2(0.7328308f, 0.8040201f), new Vector2(0.7328308f, 0.9698492f), new Vector2(0.6541039f, 0.9698492f), new Vector2(0.6541039f, 0.8844221f), new Vector2(0.5971524f, 0.8844221f), new Vector2(0.5971524f, 0.9698492f), new Vector2(0.5234506f, 0.9698492f), new Vector2(0.5234506f, 0.8844221f), new Vector2(0.4664991f, 0.8844221f), new Vector2(0.4664991f, 0.9698492f), new Vector2(0.3894472f, 0.9698492f), new Vector2(0.3894472f, 0.8844221f), new Vector2(0.3341708f, 0.8844221f), new Vector2(0.3341708f, 0.9698492f), new Vector2(0.258794f, 0.9698492f), new Vector2(0.258794f, 0.802345f), new Vector2(0.3174204f, 0.7085427f), new Vector2(0.3174204f, 0.319933f), new Vector2(0.2336683f, 0.1859296f), new Vector2(0.2336683f, 0.03685092f), new Vector2(0.4380234f, 0.03685092f), new Vector2(0.4380234f, 0.1859296f), new Vector2(0.4731993f, 0.2110553f), new Vector2(0.5351759f, 0.2110553f), new Vector2(0.5686767f, 0.1859296f), new Vector2(0.5686767f, 0.03685092f), new Vector2(0.7663317f, 0.03685092f), new Vector2(0.7663317f, 0.1859296f), new Vector2(0.6792295f, 0.319933f) }, new Vector3[] { new Vector2(0.4631491f, 0.6649916f), new Vector2(0.4631491f, 0.5159129f), new Vector2(0.3844221f, 0.5159129f), new Vector2(0.3844221f, 0.6633166f), new Vector2(0.4246231f, 0.6901172f), new Vector2(0.4631491f, 0.6649916f) }, new Vector3[] { new Vector2(0.6239531f, 0.6633166f), new Vector2(0.6239531f, 0.517588f), new Vector2(0.5452262f, 0.517588f), new Vector2(0.5452262f, 0.6633166f), new Vector2(0.5854272f, 0.6901172f), new Vector2(0.6239531f, 0.6633166f) } }; } return icon_tower; } + Vector3[][] Icon_circleDotFilled() { if (icon_circleDotFilled == null) { icon_circleDotFilled = new Vector3[][] { new Vector3[] { new Vector2(0.4852f, 0.1091501f), new Vector2(0.3257f, 0.14105f), new Vector2(0.2068f, 0.2179f), new Vector2(0.12125f, 0.33825f), new Vector2(0.08209997f, 0.505f), new Vector2(0.1111f, 0.6616f), new Vector2(0.21115f, 0.8066f), new Vector2(0.3315f, 0.88345f), new Vector2(0.491f, 0.911f), new Vector2(0.66355f, 0.87185f), new Vector2(0.7839f, 0.77905f), new Vector2(0.86075f, 0.65435f), new Vector2(0.8854001f, 0.505f), new Vector2(0.84915f, 0.3397f), new Vector2(0.76795f, 0.22225f), new Vector2(0.6418f, 0.1425f), new Vector2(0.4852f, 0.1091501f) }, new Vector3[] { new Vector2(0.487665f, 0.269604f), new Vector2(0.3959525f, 0.288574f), new Vector2(0.327585f, 0.334273f), new Vector2(0.2783937f, 0.40584f), new Vector2(0.2558825f, 0.505f), new Vector2(0.2725575f, 0.598124f), new Vector2(0.3300862f, 0.68435f), new Vector2(0.3992875f, 0.730049f), new Vector2(0.491f, 0.7464319f), new Vector2(0.5902162f, 0.723151f), new Vector2(0.6594175f, 0.667967f), new Vector2(0.7036062f, 0.5938129f), new Vector2(0.71778f, 0.505f), new Vector2(0.6969362f, 0.406703f), new Vector2(0.6502463f, 0.3368599f), new Vector2(0.57771f, 0.289436f), new Vector2(0.487665f, 0.269604f) }, new Vector3[] { new Vector2(0.4874147f, 0.1863281f), new Vector2(0.3613202f, 0.211686f), new Vector2(0.2673224f, 0.272776f), new Vector2(0.1996899f, 0.368446f), new Vector2(0.1687393f, 0.501f), new Vector2(0.1916656f, 0.625486f), new Vector2(0.2707613f, 0.74075f), new Vector2(0.3659054f, 0.801841f), new Vector2(0.492f, 0.823741f), new Vector2(0.6284114f, 0.792619f), new Vector2(0.7235556f, 0.71885f), new Vector2(0.7843102f, 0.619723f), new Vector2(0.8037975f, 0.501f), new Vector2(0.7751396f, 0.369599f), new Vector2(0.710946f, 0.276234f), new Vector2(0.6112167f, 0.212839f), new Vector2(0.4874147f, 0.1863281f) }, new Vector3[] { new Vector2(0.4901f, 0.367462f), new Vector2(0.3861557f, 0.410537f), new Vector2(0.3450851f, 0.5053f), new Vector2(0.3846346f, 0.604624f), new Vector2(0.4875648f, 0.648712f), new Vector2(0.5869456f, 0.609185f), new Vector2(0.6270022f, 0.504793f), new Vector2(0.5864386f, 0.4059761f), new Vector2(0.4901f, 0.367462f) }, new Vector3[] { new Vector2(0.492f, 0.447932f), new Vector2(0.4475325f, 0.466328f), new Vector2(0.4299624f, 0.5068001f), new Vector2(0.4468817f, 0.54922f), new Vector2(0.4909154f, 0.568049f), new Vector2(0.5334307f, 0.551168f), new Vector2(0.550567f, 0.506584f), new Vector2(0.5332138f, 0.46438f), new Vector2(0.492f, 0.447932f) } }; } return icon_circleDotFilled; } + Vector3[][] Icon_circleDotUnfilled() { if (icon_circleDotUnfilled == null) { icon_circleDotUnfilled = new Vector3[][] { new Vector3[] { new Vector2(0.4852f, 0.1091501f), new Vector2(0.3257f, 0.14105f), new Vector2(0.2068f, 0.2179f), new Vector2(0.12125f, 0.33825f), new Vector2(0.08209997f, 0.505f), new Vector2(0.1111f, 0.6616f), new Vector2(0.21115f, 0.8066f), new Vector2(0.3315f, 0.88345f), new Vector2(0.491f, 0.911f), new Vector2(0.66355f, 0.87185f), new Vector2(0.7839f, 0.77905f), new Vector2(0.86075f, 0.65435f), new Vector2(0.8854001f, 0.505f), new Vector2(0.84915f, 0.3397f), new Vector2(0.76795f, 0.22225f), new Vector2(0.6418f, 0.1425f), new Vector2(0.4852f, 0.1091501f) } }; } return icon_circleDotUnfilled; } + Vector3[][] Icon_logMessage() { if (icon_logMessage == null) { icon_logMessage = new Vector3[][] { new Vector3[] { new Vector2(0.6321586f, 0.154185f), new Vector2(0.8303965f, 0.08370044f), new Vector2(0.8039647f, 0.284141f), new Vector2(0.8634361f, 0.3788546f), new Vector2(0.8986784f, 0.5330396f), new Vector2(0.8700441f, 0.6894273f), new Vector2(0.7643172f, 0.8281938f), new Vector2(0.6211454f, 0.9185022f), new Vector2(0.4625551f, 0.9427313f), new Vector2(0.2929516f, 0.8876652f), new Vector2(0.1519824f, 0.7599119f), new Vector2(0.09030837f, 0.6123348f), new Vector2(0.09030837f, 0.4537445f), new Vector2(0.1585903f, 0.3039648f), new Vector2(0.2863436f, 0.185022f), new Vector2(0.4140969f, 0.1299559f), new Vector2(0.5264317f, 0.123348f), new Vector2(0.6321586f, 0.154185f) }, new Vector3[] { new Vector2(0.4933921f, 0.7929515f), new Vector2(0.4361233f, 0.7555066f), new Vector2(0.4603524f, 0.4625551f), new Vector2(0.4955947f, 0.4449339f), new Vector2(0.5374449f, 0.4713656f), new Vector2(0.5550661f, 0.7621145f), new Vector2(0.4933921f, 0.7929515f) }, new Vector3[] { new Vector2(0.4713656f, 0.4118943f), new Vector2(0.4427313f, 0.3832599f), new Vector2(0.4427313f, 0.3281938f), new Vector2(0.4669603f, 0.2973568f), new Vector2(0.5154185f, 0.2973568f), new Vector2(0.5484582f, 0.3281938f), new Vector2(0.5484582f, 0.3876652f), new Vector2(0.5198238f, 0.4096916f), new Vector2(0.4713656f, 0.4118943f) } }; } return icon_logMessage; } + Vector3[][] Icon_logMessageError() { if (icon_logMessageError == null) { icon_logMessageError = new Vector3[][] { new Vector3[] { new Vector2(0.326087f, 0.1404682f), new Vector2(0.6438127f, 0.1404682f), new Vector2(0.8645485f, 0.326087f), new Vector2(0.8645485f, 0.6488295f), new Vector2(0.6622074f, 0.8729097f), new Vector2(0.3361204f, 0.8729097f), new Vector2(0.1103679f, 0.6789297f), new Vector2(0.1103679f, 0.3444816f), new Vector2(0.326087f, 0.1404682f) }, new Vector3[] { new Vector2(0.4916388f, 0.7508361f), new Vector2(0.4230769f, 0.7090301f), new Vector2(0.4632107f, 0.4130435f), new Vector2(0.493311f, 0.3996656f), new Vector2(0.5217391f, 0.4197325f), new Vector2(0.5518395f, 0.7190635f), new Vector2(0.4916388f, 0.7508361f) }, new Vector3[] { new Vector2(0.496f, 0.2563437f), new Vector2(0.4610812f, 0.2699863f), new Vector2(0.447284f, 0.3f), new Vector2(0.4605702f, 0.3314583f), new Vector2(0.4951483f, 0.3454219f), new Vector2(0.5285341f, 0.3329028f), new Vector2(0.5419906f, 0.2998395f), new Vector2(0.5283638f, 0.2685418f), new Vector2(0.496f, 0.2563437f) } }; } return icon_logMessageError; } + Vector3[][] Icon_logMessageException() { if (icon_logMessageException == null) { icon_logMessageException = new Vector3[][] { new Vector3[] { new Vector2(0.07929515f, 0.6696035f), new Vector2(0.07929515f, 0.345815f), new Vector2(0.2687225f, 0.1475771f), new Vector2(0.6916299f, 0.1475771f), new Vector2(0.9096916f, 0.3546256f), new Vector2(0.9096916f, 0.6563877f), new Vector2(0.7070485f, 0.8678414f), new Vector2(0.2819383f, 0.8678414f), new Vector2(0.07929515f, 0.6696035f) }, new Vector3[] { new Vector2(0.2753304f, 0.7202643f), new Vector2(0.3348018f, 0.7202643f), new Vector2(0.438326f, 0.5506608f), new Vector2(0.5440528f, 0.7202643f), new Vector2(0.6035242f, 0.7202643f), new Vector2(0.4669603f, 0.5132158f), new Vector2(0.6079295f, 0.2995595f), new Vector2(0.5418502f, 0.2995595f), new Vector2(0.4361233f, 0.4669603f), new Vector2(0.3259912f, 0.2995595f), new Vector2(0.2643172f, 0.2995595f), new Vector2(0.4052863f, 0.5154185f), new Vector2(0.2753304f, 0.7202643f) }, new Vector3[] { new Vector2(0.6806167f, 0.7202643f), new Vector2(0.6806167f, 0.4427313f), new Vector2(0.7246696f, 0.4427313f), new Vector2(0.7246696f, 0.7180617f), new Vector2(0.6806167f, 0.7202643f) }, new Vector3[] { new Vector2(0.7048458f, 0.3612335f), new Vector2(0.6806167f, 0.3524229f), new Vector2(0.6674009f, 0.3237886f), new Vector2(0.6784141f, 0.2995595f), new Vector2(0.7048458f, 0.2885463f), new Vector2(0.7268723f, 0.2995595f), new Vector2(0.7378855f, 0.3259912f), new Vector2(0.7246696f, 0.3524229f), new Vector2(0.7048458f, 0.3612335f) } }; } return icon_logMessageException; } + Vector3[][] Icon_logMessageAssertion() { if (icon_logMessageAssertion == null) { icon_logMessageAssertion = new Vector3[][] { new Vector3[] { new Vector2(0.07929515f, 0.6696035f), new Vector2(0.07929515f, 0.345815f), new Vector2(0.2687225f, 0.1475771f), new Vector2(0.6916299f, 0.1475771f), new Vector2(0.9096916f, 0.3546256f), new Vector2(0.9096916f, 0.6563877f), new Vector2(0.7070485f, 0.8678414f), new Vector2(0.2819383f, 0.8678414f), new Vector2(0.07929515f, 0.6696035f) }, new Vector3[] { new Vector2(0.2253045f, 0.3058187f), new Vector2(0.2740189f, 0.3058187f), new Vector2(0.3173207f, 0.4154263f), new Vector2(0.5094723f, 0.4154263f), new Vector2(0.5581867f, 0.3058187f), new Vector2(0.6109608f, 0.3058187f), new Vector2(0.4458728f, 0.7280108f), new Vector2(0.3890392f, 0.7280108f), new Vector2(0.2253045f, 0.3058187f) }, new Vector3[] { new Vector2(0.4161029f, 0.6671177f), new Vector2(0.3403248f, 0.4654939f), new Vector2(0.4945873f, 0.4654939f), new Vector2(0.4161029f, 0.6671177f) }, new Vector3[] { new Vector2(0.6705007f, 0.7307172f), new Vector2(0.6705007f, 0.4519621f), new Vector2(0.7124493f, 0.4519621f), new Vector2(0.7124493f, 0.7320704f), new Vector2(0.6705007f, 0.7307172f) }, new Vector3[] { new Vector2(0.6894452f, 0.3707713f), new Vector2(0.6650879f, 0.3599459f), new Vector2(0.6529093f, 0.3328823f), new Vector2(0.6650879f, 0.308525f), new Vector2(0.6935048f, 0.2976996f), new Vector2(0.7151556f, 0.3098782f), new Vector2(0.7286874f, 0.3342355f), new Vector2(0.7124493f, 0.3626522f), new Vector2(0.6894452f, 0.3707713f) } }; } return icon_logMessageAssertion; } + Vector3[][] Icon_up_oneStroke() { if (icon_up_oneStroke == null) { icon_up_oneStroke = new Vector3[][] { new Vector3[] { new Vector2(0.0945946f, 0.3260135f), new Vector2(0.4983108f, 0.722973f), new Vector2(0.8918919f, 0.3310811f) } }; } return icon_up_oneStroke; } + Vector3[][] Icon_up_twoStroke() { if (icon_up_twoStroke == null) { icon_up_twoStroke = new Vector3[][] { new Vector3[] { new Vector2(0.0945946f, 0.4746622f), new Vector2(0.4966216f, 0.8682432f), new Vector2(0.8935811f, 0.4814189f) }, new Vector3[] { new Vector2(0.0945946f, 0.1452703f), new Vector2(0.5f, 0.5405405f), new Vector2(0.8935811f, 0.1554054f) } }; } return icon_up_twoStroke; } + Vector3[][] Icon_up_threeStroke() { if (icon_up_threeStroke == null) { icon_up_threeStroke = new Vector3[][] { new Vector3[] { new Vector2(0.0929054f, 0.5625f), new Vector2(0.4932432f, 0.9543919f), new Vector2(0.8902027f, 0.5692568f) }, new Vector3[] { new Vector2(0.0945946f, 0.3023649f), new Vector2(0.4966216f, 0.6959459f), new Vector2(0.8902027f, 0.3125f) }, new Vector3[] { new Vector2(0.0929054f, 0.04391892f), new Vector2(0.4949324f, 0.4324324f), new Vector2(0.8885135f, 0.05236486f) } }; } return icon_up_threeStroke; } + Vector3[][] Icon_down_oneStroke() { if (icon_down_oneStroke == null) { icon_down_oneStroke = new Vector3[][] { new Vector3[] { new Vector2(0.9054054f, 0.6739866f), new Vector2(0.5016892f, 0.277027f), new Vector2(0.1081081f, 0.6689188f) } }; } return icon_down_oneStroke; } + Vector3[][] Icon_down_twoStroke() { if (icon_down_twoStroke == null) { icon_down_twoStroke = new Vector3[][] { new Vector3[] { new Vector2(0.9054054f, 0.5253378f), new Vector2(0.5033785f, 0.1317568f), new Vector2(0.1064189f, 0.518581f) }, new Vector3[] { new Vector2(0.9054054f, 0.8547298f), new Vector2(0.5f, 0.4594595f), new Vector2(0.1064189f, 0.8445946f) } }; } return icon_down_twoStroke; } + Vector3[][] Icon_down_threeStroke() { if (icon_down_threeStroke == null) { icon_down_threeStroke = new Vector3[][] { new Vector3[] { new Vector2(0.9070946f, 0.4375f), new Vector2(0.5067568f, 0.0456081f), new Vector2(0.1097973f, 0.4307432f) }, new Vector3[] { new Vector2(0.9054054f, 0.6976352f), new Vector2(0.5033784f, 0.3040541f), new Vector2(0.1097973f, 0.6875f) }, new Vector3[] { new Vector2(0.9070946f, 0.9560812f), new Vector2(0.5050676f, 0.5675676f), new Vector2(0.1114865f, 0.9476351f) } }; } return icon_down_threeStroke; } + Vector3[][] Icon_left_oneStroke() { if (icon_left_oneStroke == null) { icon_left_oneStroke = new Vector3[][] { new Vector3[] { new Vector2(0.6739864f, 0.0945946f), new Vector2(0.277027f, 0.4983108f), new Vector2(0.6689189f, 0.8918918f) } }; } return icon_left_oneStroke; } + Vector3[][] Icon_left_twoStroke() { if (icon_left_twoStroke == null) { icon_left_twoStroke = new Vector3[][] { new Vector3[] { new Vector2(0.5253378f, 0.09459463f), new Vector2(0.1317568f, 0.4966216f), new Vector2(0.5185811f, 0.893581f) }, new Vector3[] { new Vector2(0.8547297f, 0.0945946f), new Vector2(0.4594595f, 0.5f), new Vector2(0.8445946f, 0.893581f) } }; } return icon_left_twoStroke; } + Vector3[][] Icon_left_threeStroke() { if (icon_left_threeStroke == null) { icon_left_threeStroke = new Vector3[][] { new Vector3[] { new Vector2(0.4375f, 0.09290543f), new Vector2(0.04560813f, 0.4932432f), new Vector2(0.4307432f, 0.8902026f) }, new Vector3[] { new Vector2(0.6976351f, 0.0945946f), new Vector2(0.3040541f, 0.4966216f), new Vector2(0.6875f, 0.8902026f) }, new Vector3[] { new Vector2(0.956081f, 0.0929054f), new Vector2(0.5675676f, 0.4949324f), new Vector2(0.9476352f, 0.8885134f) } }; } return icon_left_threeStroke; } + Vector3[][] Icon_right_oneStroke() { if (icon_right_oneStroke == null) { icon_right_oneStroke = new Vector3[][] { new Vector3[] { new Vector2(0.3260135f, 0.9054054f), new Vector2(0.722973f, 0.5016892f), new Vector2(0.3310811f, 0.1081081f) } }; } return icon_right_oneStroke; } + Vector3[][] Icon_right_twoStroke() { if (icon_right_twoStroke == null) { icon_right_twoStroke = new Vector3[][] { new Vector3[] { new Vector2(0.4746622f, 0.9054054f), new Vector2(0.8682432f, 0.5033784f), new Vector2(0.4814189f, 0.1064189f) }, new Vector3[] { new Vector2(0.1452703f, 0.9054053f), new Vector2(0.5405405f, 0.5f), new Vector2(0.1554054f, 0.1064189f) } }; } return icon_right_twoStroke; } + Vector3[][] Icon_right_threeStroke() { if (icon_right_threeStroke == null) { icon_right_threeStroke = new Vector3[][] { new Vector3[] { new Vector2(0.5625f, 0.9070946f), new Vector2(0.9543918f, 0.5067568f), new Vector2(0.5692568f, 0.1097973f) }, new Vector3[] { new Vector2(0.3023649f, 0.9054054f), new Vector2(0.6959459f, 0.5033784f), new Vector2(0.3125f, 0.1097973f) }, new Vector3[] { new Vector2(0.04391891f, 0.9070945f), new Vector2(0.4324324f, 0.5050676f), new Vector2(0.05236492f, 0.1114865f) } }; } return icon_right_threeStroke; } + Vector3[][] Icon_fist() { if (icon_fist == null) { icon_fist = new Vector3[][] { new Vector3[] { new Vector2(0.4832496f, 0.2830821f), new Vector2(0.4664991f, 0.3802345f), new Vector2(0.4061977f, 0.4824121f), new Vector2(0.3442211f, 0.520938f), new Vector2(0.2822446f, 0.5376884f), new Vector2(0.2822446f, 0.5762144f), new Vector2(0.3559464f, 0.5896147f), new Vector2(0.3944724f, 0.6130653f), new Vector2(0.4112228f, 0.6649916f), new Vector2(0.4078727f, 0.7068677f), new Vector2(0.3710218f, 0.721943f), new Vector2(0.1281407f, 0.7068677f), new Vector2(0.06951424f, 0.6331658f), new Vector2(0.04271357f, 0.4271357f), new Vector2(0.09463987f, 0.318258f), new Vector2(0.2721943f, 0.1809045f), new Vector2(0.2554439f, 0.03350084f), new Vector2(0.7160804f, 0.03350084f), new Vector2(0.6876047f, 0.2127303f), new Vector2(0.7730318f, 0.318258f), new Vector2(0.8232831f, 0.4036851f), new Vector2(0.8618091f, 0.4874372f), new Vector2(0.8785595f, 0.7906198f), new Vector2(0.8651592f, 0.8559464f), new Vector2(0.8333333f, 0.8927973f), new Vector2(0.7613065f, 0.8927973f), new Vector2(0.7462311f, 0.879397f), new Vector2(0.7328308f, 0.8291457f), new Vector2(0.7227806f, 0.6750419f), new Vector2(0.7361809f, 0.6415411f), new Vector2(0.7629816f, 0.6281407f), new Vector2(0.8115578f, 0.6348408f), new Vector2(0.8534338f, 0.6599665f), new Vector2(0.8735343f, 0.7118928f) }, new Vector3[] { new Vector2(0.3726968f, 0.721943f), new Vector2(0.3978224f, 0.9078727f), new Vector2(0.4313233f, 0.9497488f), new Vector2(0.4631491f, 0.9614741f), new Vector2(0.5385259f, 0.9564489f), new Vector2(0.5653266f, 0.9262981f), new Vector2(0.5703518f, 0.8944724f), new Vector2(0.5636516f, 0.7185929f), new Vector2(0.5502512f, 0.6499162f), new Vector2(0.5201005f, 0.6030151f), new Vector2(0.4782245f, 0.5812395f), new Vector2(0.4162479f, 0.5862647f), new Vector2(0.3911223f, 0.6130653f) }, new Vector3[] { new Vector2(0.2068677f, 0.7118928f), new Vector2(0.220268f, 0.839196f), new Vector2(0.2319933f, 0.8827471f), new Vector2(0.2839196f, 0.9128978f), new Vector2(0.3274707f, 0.9229481f), new Vector2(0.3643216f, 0.9128978f), new Vector2(0.3927973f, 0.8760469f) }, new Vector3[] { new Vector2(0.5703518f, 0.8676717f), new Vector2(0.5938023f, 0.9078727f), new Vector2(0.6273032f, 0.9380234f), new Vector2(0.6792295f, 0.9380234f), new Vector2(0.7211055f, 0.9128978f), new Vector2(0.7361809f, 0.8492462f) }, new Vector3[] { new Vector2(0.5519263f, 0.6566164f), new Vector2(0.5603015f, 0.6214405f), new Vector2(0.5837521f, 0.5963149f), new Vector2(0.6557789f, 0.599665f), new Vector2(0.6943049f, 0.6281407f), new Vector2(0.7227806f, 0.6817421f) } }; } return icon_fist; } + Vector3[][] Icon_boxingGlove() { if (icon_boxingGlove == null) { icon_boxingGlove = new Vector3[][] { new Vector3[] { new Vector2(0.2688442f, 0.6867672f), new Vector2(0.2688442f, 0.3031826f), new Vector2(0.2453936f, 0.2931323f), new Vector2(0.1582915f, 0.2830821f), new Vector2(0.07286432f, 0.2914573f), new Vector2(0.04438861f, 0.3149079f), new Vector2(0.04438861f, 0.6884422f), new Vector2(0.06281407f, 0.7169179f), new Vector2(0.1566164f, 0.7269682f), new Vector2(0.2554439f, 0.7102178f), new Vector2(0.2688442f, 0.6867672f) }, new Vector3[] { new Vector2(0.0879397f, 0.2914573f), new Vector2(0.0879397f, 0.5778894f), new Vector2(0.2236181f, 0.5778894f), new Vector2(0.2236181f, 0.2914573f) }, new Vector3[] { new Vector2(0.4296483f, 0.6750419f), new Vector2(0.5653266f, 0.7487437f), new Vector2(0.6407035f, 0.7755444f), new Vector2(0.778057f, 0.7772194f), new Vector2(0.8551089f, 0.7504188f), new Vector2(0.9103853f, 0.7102178f), new Vector2(0.9321608f, 0.6683417f), new Vector2(0.9472362f, 0.5829146f), new Vector2(0.9472362f, 0.4623116f), new Vector2(0.9371859f, 0.361809f), new Vector2(0.9154104f, 0.3082077f), new Vector2(0.8718593f, 0.2596315f), new Vector2(0.8115578f, 0.2294807f), new Vector2(0.7345059f, 0.2177554f), new Vector2(0.4916248f, 0.2211055f), new Vector2(0.4246231f, 0.2311558f), new Vector2(0.3726968f, 0.2529313f), new Vector2(0.2705193f, 0.3316583f) }, new Vector3[] { new Vector2(0.2671692f, 0.6934673f), new Vector2(0.3375209f, 0.7755444f), new Vector2(0.4061977f, 0.8341709f), new Vector2(0.4916248f, 0.8592965f), new Vector2(0.5703518f, 0.8743719f), new Vector2(0.6038526f, 0.8693467f), new Vector2(0.6356784f, 0.840871f), new Vector2(0.6641541f, 0.7788945f) } }; } return icon_boxingGlove; } + Vector3[][] Icon_stars5Rate() { if (icon_stars5Rate == null) { icon_stars5Rate = new Vector3[][] { new Vector3[] { new Vector2(0.379397f, 0.5259631f), new Vector2(0.4681742f, 0.5259631f), new Vector2(0.498325f, 0.6147404f), new Vector2(0.5251256f, 0.5242881f), new Vector2(0.6172529f, 0.5242881f), new Vector2(0.5385259f, 0.4723618f), new Vector2(0.5703518f, 0.3802345f), new Vector2(0.5f, 0.440536f), new Vector2(0.421273f, 0.3819095f), new Vector2(0.4497488f, 0.4740368f), new Vector2(0.379397f, 0.5259631f) }, new Vector3[] { new Vector2(0.6139029f, 0.4974874f), new Vector2(0.6825796f, 0.4974874f), new Vector2(0.7043551f, 0.559464f), new Vector2(0.7294807f, 0.4974874f), new Vector2(0.7931323f, 0.4974874f), new Vector2(0.741206f, 0.4539363f), new Vector2(0.7596315f, 0.3902847f), new Vector2(0.7026801f, 0.4338358f), new Vector2(0.6457286f, 0.3886097f), new Vector2(0.6675042f, 0.4606365f), new Vector2(0.6139029f, 0.4974874f) }, new Vector3[] { new Vector2(0.2051926f, 0.4974874f), new Vector2(0.2721943f, 0.4974874f), new Vector2(0.2956449f, 0.5628141f), new Vector2(0.3174204f, 0.4991625f), new Vector2(0.3760469f, 0.4991625f), new Vector2(0.3257957f, 0.4522613f), new Vector2(0.3509213f, 0.3835846f), new Vector2(0.2939698f, 0.4321608f), new Vector2(0.2319933f, 0.3902847f), new Vector2(0.2537688f, 0.4556114f), new Vector2(0.2051926f, 0.4974874f) }, new Vector3[] { new Vector2(0.03768844f, 0.479062f), new Vector2(0.09463987f, 0.479062f), new Vector2(0.1113903f, 0.5293132f), new Vector2(0.1281407f, 0.4757119f), new Vector2(0.1867672f, 0.4757119f), new Vector2(0.1365159f, 0.440536f), new Vector2(0.1582915f, 0.3835846f), new Vector2(0.1097152f, 0.4237856f), new Vector2(0.06448911f, 0.3886097f), new Vector2(0.07956449f, 0.4489112f), new Vector2(0.03768844f, 0.479062f) }, new Vector3[] { new Vector2(0.8115578f, 0.4773869f), new Vector2(0.8685092f, 0.4773869f), new Vector2(0.8852596f, 0.5276382f), new Vector2(0.9053602f, 0.4757119f), new Vector2(0.9606365f, 0.4757119f), new Vector2(0.9120603f, 0.4422111f), new Vector2(0.9304858f, 0.3835846f), new Vector2(0.8852596f, 0.4237856f), new Vector2(0.8366834f, 0.3819095f), new Vector2(0.8567839f, 0.4489112f), new Vector2(0.8115578f, 0.4773869f) } }; } return icon_stars5Rate; } + Vector3[][] Icon_stars3() { if (icon_stars3 == null) { icon_stars3 = new Vector3[][] { new Vector3[] { new Vector2(0.4346734f, 0.4304858f), new Vector2(0.659129f, 0.479062f), new Vector2(0.5033501f, 0.3132328f), new Vector2(0.6172529f, 0.09715243f), new Vector2(0.4095477f, 0.2110553f), new Vector2(0.2504188f, 0.03350084f), new Vector2(0.2772194f, 0.2579564f), new Vector2(0.07118928f, 0.3517588f), new Vector2(0.298995f, 0.3969849f), new Vector2(0.3274707f, 0.6298158f), new Vector2(0.4346734f, 0.4304858f) }, new Vector3[] { new Vector2(0.7881072f, 0.7922948f), new Vector2(0.9572864f, 0.7805695f), new Vector2(0.8082077f, 0.7018425f), new Vector2(0.8467337f, 0.5276382f), new Vector2(0.7278057f, 0.6499162f), new Vector2(0.5854272f, 0.5628141f), new Vector2(0.6474037f, 0.7152429f), new Vector2(0.5217755f, 0.8190955f), new Vector2(0.6909547f, 0.7973199f), new Vector2(0.7562814f, 0.9547738f), new Vector2(0.7881072f, 0.7922948f) }, new Vector3[] { new Vector2(0.2169179f, 0.8676717f), new Vector2(0.3241206f, 0.9061977f), new Vector2(0.2537688f, 0.8107203f), new Vector2(0.3257957f, 0.7068677f), new Vector2(0.2102178f, 0.7554439f), new Vector2(0.139866f, 0.6532663f), new Vector2(0.141541f, 0.7772194f), new Vector2(0.02931323f, 0.8056951f), new Vector2(0.1432161f, 0.8458961f), new Vector2(0.1465662f, 0.9648241f), new Vector2(0.2169179f, 0.8676717f) } }; } return icon_stars3; } + Vector3[][] Icon_shootingStar() { if (icon_shootingStar == null) { icon_shootingStar = new Vector3[][] { new Vector3[] { new Vector2(0.8433836f, 0.3232831f), new Vector2(0.9505863f, 0.3232831f), new Vector2(0.8584589f, 0.2596315f), new Vector2(0.8936349f, 0.1574539f), new Vector2(0.8098828f, 0.2278057f), new Vector2(0.7177554f, 0.160804f), new Vector2(0.7562814f, 0.2663317f), new Vector2(0.6641541f, 0.3333333f), new Vector2(0.778057f, 0.3333333f), new Vector2(0.8115578f, 0.4304858f), new Vector2(0.8433836f, 0.3232831f) }, new Vector3[] { new Vector2(0.04606365f, 0.5242881f), new Vector2(0.180067f, 0.5276382f), new Vector2(0.3040201f, 0.5125628f), new Vector2(0.3944724f, 0.4874372f), new Vector2(0.461474f, 0.4556114f) }, new Vector3[] { new Vector2(0.5251256f, 0.4254606f), new Vector2(0.622278f, 0.3551089f) }, new Vector3[] { new Vector2(0.05276382f, 0.6700168f), new Vector2(0.1348409f, 0.6666667f), new Vector2(0.2169179f, 0.6515913f) }, new Vector3[] { new Vector2(0.2922948f, 0.6331658f), new Vector2(0.379397f, 0.6046901f), new Vector2(0.4765494f, 0.5661641f), new Vector2(0.5569514f, 0.519263f), new Vector2(0.6407035f, 0.4656616f), new Vector2(0.6926298f, 0.4170854f) }, new Vector3[] { new Vector2(0.04941374f, 0.8291457f), new Vector2(0.1649916f, 0.8040201f), new Vector2(0.2688442f, 0.7688442f), new Vector2(0.3592965f, 0.7319933f), new Vector2(0.4648241f, 0.6767169f) }, new Vector3[] { new Vector2(0.5452262f, 0.6264657f), new Vector2(0.618928f, 0.5695142f), new Vector2(0.6859297f, 0.5041876f), new Vector2(0.7361809f, 0.4489112f) } }; } return icon_shootingStar; } + Vector3[][] Icon_moonHalf() { if (icon_moonHalf == null) { icon_moonHalf = new Vector3[][] { new Vector3[] { new Vector2(0.5217755f, 0.9564489f), new Vector2(0.4631491f, 0.8643216f), new Vector2(0.4262982f, 0.7420436f), new Vector2(0.4279732f, 0.6180905f), new Vector2(0.4782245f, 0.5008375f), new Vector2(0.5653266f, 0.400335f), new Vector2(0.6758794f, 0.3383585f), new Vector2(0.7747068f, 0.318258f), new Vector2(0.8685092f, 0.3266332f), new Vector2(0.9438861f, 0.3500837f), new Vector2(0.8986599f, 0.2579564f), new Vector2(0.8283082f, 0.1775544f), new Vector2(0.741206f, 0.1122278f), new Vector2(0.6340033f, 0.0720268f), new Vector2(0.5167504f, 0.05360134f), new Vector2(0.3994975f, 0.06867672f), new Vector2(0.2939698f, 0.1155779f), new Vector2(0.1867672f, 0.1959799f), new Vector2(0.1197655f, 0.2948074f), new Vector2(0.07286432f, 0.4204355f), new Vector2(0.06951424f, 0.5561139f), new Vector2(0.09798995f, 0.6733668f), new Vector2(0.1616415f, 0.7822446f), new Vector2(0.2370184f, 0.8576214f), new Vector2(0.3358459f, 0.9162479f), new Vector2(0.4329983f, 0.9480737f), new Vector2(0.5217755f, 0.9564489f) } }; } return icon_moonHalf; } + Vector3[][] Icon_moonFullPlanet() { if (icon_moonFullPlanet == null) { icon_moonFullPlanet = new Vector3[][] { new Vector3[] { new Vector2(0.50252f, 0.05774003f), new Vector2(0.32432f, 0.09338003f), new Vector2(0.19148f, 0.17924f), new Vector2(0.0959f, 0.3137001f), new Vector2(0.05215999f, 0.5f), new Vector2(0.08456001f, 0.6749601f), new Vector2(0.19634f, 0.83696f), new Vector2(0.3308f, 0.9228201f), new Vector2(0.509f, 0.9536f), new Vector2(0.70178f, 0.90986f), new Vector2(0.8362401f, 0.80618f), new Vector2(0.9221f, 0.6668601f), new Vector2(0.94964f, 0.5f), new Vector2(0.90914f, 0.3153201f), new Vector2(0.81842f, 0.1841001f), new Vector2(0.67748f, 0.09500006f), new Vector2(0.50252f, 0.05774003f) }, new Vector3[] { new Vector2(0.1888686f, 0.6806569f), new Vector2(0.1596715f, 0.689781f), new Vector2(0.1195255f, 0.620438f), new Vector2(0.1012774f, 0.5127738f), new Vector2(0.1177007f, 0.4251825f), new Vector2(0.1833942f, 0.4014598f), new Vector2(0.2144161f, 0.4251825f), new Vector2(0.1979927f, 0.4835767f), new Vector2(0.1779197f, 0.5291971f), new Vector2(0.1870438f, 0.5894161f), new Vector2(0.2144161f, 0.6459854f), new Vector2(0.1888686f, 0.6806569f) }, new Vector3[] { new Vector2(0.2855839f, 0.8193431f), new Vector2(0.3640511f, 0.8357664f), new Vector2(0.4078467f, 0.8740876f), new Vector2(0.4954379f, 0.859489f), new Vector2(0.5282847f, 0.8120438f), new Vector2(0.5209854f, 0.7427008f), new Vector2(0.4206204f, 0.6660584f), new Vector2(0.314781f, 0.6751825f), new Vector2(0.2709854f, 0.7390511f), new Vector2(0.2855839f, 0.8193431f) }, new Vector3[] { new Vector2(0.6122262f, 0.8010949f), new Vector2(0.5885037f, 0.7591241f), new Vector2(0.6104015f, 0.6879562f), new Vector2(0.6833941f, 0.6678832f), new Vector2(0.7363139f, 0.7080292f), new Vector2(0.7016423f, 0.7846715f), new Vector2(0.6122262f, 0.8010949f) }, new Vector3[] { new Vector2(0.7089416f, 0.6167883f), new Vector2(0.7673358f, 0.6350365f), new Vector2(0.8020073f, 0.6167883f), new Vector2(0.8275548f, 0.5255474f), new Vector2(0.7381387f, 0.4744526f), new Vector2(0.6742701f, 0.5346715f), new Vector2(0.6687956f, 0.5894161f), new Vector2(0.7089416f, 0.6167883f) }, new Vector3[] { new Vector2(0.7582117f, 0.3850365f), new Vector2(0.7509124f, 0.3430657f), new Vector2(0.7892336f, 0.3357664f), new Vector2(0.8038321f, 0.3576642f), new Vector2(0.794708f, 0.3959854f), new Vector2(0.7582117f, 0.3850365f) }, new Vector3[] { new Vector2(0.185219f, 0.3321168f), new Vector2(0.1797445f, 0.2956204f), new Vector2(0.2125912f, 0.2463504f), new Vector2(0.2509124f, 0.2463504f), new Vector2(0.2636861f, 0.2810219f), new Vector2(0.2417883f, 0.3229927f), new Vector2(0.2089416f, 0.3394161f), new Vector2(0.185219f, 0.3321168f) }, new Vector3[] { new Vector2(0.334854f, 0.2737226f), new Vector2(0.3622263f, 0.2372263f), new Vector2(0.4260949f, 0.2372263f), new Vector2(0.4571168f, 0.2682482f), new Vector2(0.4114963f, 0.2937956f), new Vector2(0.3567518f, 0.3010949f), new Vector2(0.334854f, 0.2737226f) } }; } return icon_moonFullPlanet; } + Vector3[][] Icon_leftHandRule() { if (icon_leftHandRule == null) { icon_leftHandRule = new Vector3[][] { new Vector3[] { new Vector2(0.1080402f, 0.4773869f), new Vector2(0.2370184f, 0.5410385f), new Vector2(0.340871f, 0.8559464f), new Vector2(0.3090452f, 0.9514238f), new Vector2(0.3659967f, 0.9648241f), new Vector2(0.4061977f, 0.9530988f), new Vector2(0.4313233f, 0.9262981f), new Vector2(0.4413735f, 0.8927973f), new Vector2(0.4380234f, 0.7822446f), new Vector2(0.4279732f, 0.7353434f), new Vector2(0.4430486f, 0.6750419f), new Vector2(0.4514238f, 0.6281407f), new Vector2(0.4413735f, 0.5845896f), new Vector2(0.419598f, 0.5443886f), new Vector2(0.3877722f, 0.5092127f), new Vector2(0.3442211f, 0.4991625f) }, new Vector3[] { new Vector2(0.4279732f, 0.7319933f), new Vector2(0.5871022f, 0.7319933f), new Vector2(0.8366834f, 0.8040201f), new Vector2(0.8651592f, 0.7973199f), new Vector2(0.8835846f, 0.7772194f), new Vector2(0.8819095f, 0.7470687f), new Vector2(0.8618091f, 0.7169179f), new Vector2(0.6256281f, 0.639866f), new Vector2(0.9137353f, 0.5443886f), new Vector2(0.9321608f, 0.5125628f), new Vector2(0.9321608f, 0.4740368f), new Vector2(0.8986599f, 0.4522613f), new Vector2(0.8584589f, 0.4539363f), new Vector2(0.5720268f, 0.5410385f), new Vector2(0.5670017f, 0.5845896f) }, new Vector3[] { new Vector2(0.6541039f, 0.517588f), new Vector2(0.6775544f, 0.4840871f), new Vector2(0.6842546f, 0.4355109f), new Vector2(0.6641541f, 0.400335f), new Vector2(0.5720268f, 0.3869347f), new Vector2(0.4648241f, 0.3835846f), new Vector2(0.4246231f, 0.39866f), new Vector2(0.421273f, 0.4355109f), new Vector2(0.4396985f, 0.4589615f), new Vector2(0.4731993f, 0.479062f), new Vector2(0.5536013f, 0.480737f), new Vector2(0.6055276f, 0.4924623f) }, new Vector3[] { new Vector2(0.6658291f, 0.4053601f), new Vector2(0.6892797f, 0.3785595f), new Vector2(0.6892797f, 0.3400335f), new Vector2(0.6725293f, 0.3165829f), new Vector2(0.5703518f, 0.3015075f), new Vector2(0.5150754f, 0.2998325f), new Vector2(0.458124f, 0.3082077f), new Vector2(0.4497488f, 0.3450586f), new Vector2(0.4648241f, 0.3869347f) }, new Vector3[] { new Vector2(0.138191f, 0.04857621f), new Vector2(0.340871f, 0.2562814f), new Vector2(0.4463986f, 0.2579564f), new Vector2(0.5117253f, 0.3015075f) }, new Vector3[] { new Vector2(0.5435511f, 0.4857621f), new Vector2(0.5351759f, 0.5075377f), new Vector2(0.5569514f, 0.5326633f) }, new Vector3[] { new Vector2(0.4396985f, 0.4623116f), new Vector2(0.4798995f, 0.4606365f), new Vector2(0.4949749f, 0.438861f), new Vector2(0.4916248f, 0.4036851f), new Vector2(0.4798995f, 0.3886097f) }, new Vector3[] { new Vector2(0.4564489f, 0.358459f), new Vector2(0.5f, 0.360134f), new Vector2(0.5217755f, 0.3433836f), new Vector2(0.5217755f, 0.3165829f), new Vector2(0.5150754f, 0.3082077f) }, new Vector3[] { new Vector2(0.6943049f, 0.5041876f), new Vector2(0.6926298f, 0.5427136f) }, new Vector3[] { new Vector2(0.622278f, 0.6415411f), new Vector2(0.6088777f, 0.6817421f) }, new Vector3[] { new Vector2(0.7144054f, 0.6716918f), new Vector2(0.701005f, 0.7035176f) }, new Vector3[] { new Vector2(0.8115578f, 0.7018425f), new Vector2(0.7931323f, 0.7336683f) }, new Vector3[] { new Vector2(0.3358459f, 0.8643216f), new Vector2(0.3592965f, 0.8894472f), new Vector2(0.3458962f, 0.9564489f) }, new Vector3[] { new Vector2(0.7857143f, 0.4789916f), new Vector2(0.7857143f, 0.5126051f) }, new Vector3[] { new Vector2(0.5672269f, 0.5831933f), new Vector2(0.5722689f, 0.605042f), new Vector2(0.5907563f, 0.6252101f) }, new Vector3[] { new Vector2(0.905042f, 0.5478992f), new Vector2(0.9218487f, 0.5109244f), new Vector2(0.920168f, 0.4789916f), new Vector2(0.910084f, 0.4588235f) } }; } return icon_leftHandRule; } + Vector3[][] Icon_rightHandRule() { if (icon_rightHandRule == null) { icon_rightHandRule = new Vector3[][] { new Vector3[] { new Vector2(0.8919598f, 0.4773869f), new Vector2(0.7629816f, 0.5410385f), new Vector2(0.659129f, 0.8559464f), new Vector2(0.6909548f, 0.9514238f), new Vector2(0.6340033f, 0.9648241f), new Vector2(0.5938023f, 0.9530988f), new Vector2(0.5686767f, 0.9262981f), new Vector2(0.5586265f, 0.8927973f), new Vector2(0.5619766f, 0.7822446f), new Vector2(0.5720268f, 0.7353434f), new Vector2(0.5569514f, 0.6750419f), new Vector2(0.5485762f, 0.6281407f), new Vector2(0.5586265f, 0.5845896f), new Vector2(0.580402f, 0.5443886f), new Vector2(0.6122278f, 0.5092127f), new Vector2(0.6557789f, 0.4991625f) }, new Vector3[] { new Vector2(0.5720268f, 0.7319933f), new Vector2(0.4128978f, 0.7319933f), new Vector2(0.1633166f, 0.8040201f), new Vector2(0.1348408f, 0.7973199f), new Vector2(0.1164154f, 0.7772194f), new Vector2(0.1180905f, 0.7470687f), new Vector2(0.1381909f, 0.7169179f), new Vector2(0.3743719f, 0.639866f), new Vector2(0.08626473f, 0.5443886f), new Vector2(0.06783921f, 0.5125628f), new Vector2(0.06783921f, 0.4740368f), new Vector2(0.1013401f, 0.4522613f), new Vector2(0.1415411f, 0.4539363f), new Vector2(0.4279732f, 0.5410385f), new Vector2(0.4329983f, 0.5845896f) }, new Vector3[] { new Vector2(0.3458961f, 0.517588f), new Vector2(0.3224456f, 0.4840871f), new Vector2(0.3157454f, 0.4355109f), new Vector2(0.3358459f, 0.400335f), new Vector2(0.4279732f, 0.3869347f), new Vector2(0.5351759f, 0.3835846f), new Vector2(0.5753769f, 0.39866f), new Vector2(0.578727f, 0.4355109f), new Vector2(0.5603015f, 0.4589615f), new Vector2(0.5268007f, 0.479062f), new Vector2(0.4463987f, 0.480737f), new Vector2(0.3944724f, 0.4924623f) }, new Vector3[] { new Vector2(0.3341709f, 0.4053601f), new Vector2(0.3107203f, 0.3785595f), new Vector2(0.3107203f, 0.3400335f), new Vector2(0.3274707f, 0.3165829f), new Vector2(0.4296482f, 0.3015075f), new Vector2(0.4849246f, 0.2998325f), new Vector2(0.541876f, 0.3082077f), new Vector2(0.5502512f, 0.3450586f), new Vector2(0.5351759f, 0.3869347f) }, new Vector3[] { new Vector2(0.861809f, 0.04857621f), new Vector2(0.659129f, 0.2562814f), new Vector2(0.5536014f, 0.2579564f), new Vector2(0.4882747f, 0.3015075f) }, new Vector3[] { new Vector2(0.4564489f, 0.4857621f), new Vector2(0.4648241f, 0.5075377f), new Vector2(0.4430486f, 0.5326633f) }, new Vector3[] { new Vector2(0.5603015f, 0.4623116f), new Vector2(0.5201005f, 0.4606365f), new Vector2(0.5050251f, 0.438861f), new Vector2(0.5083752f, 0.4036851f), new Vector2(0.5201005f, 0.3886097f) }, new Vector3[] { new Vector2(0.5435511f, 0.358459f), new Vector2(0.5f, 0.360134f), new Vector2(0.4782245f, 0.3433836f), new Vector2(0.4782245f, 0.3165829f), new Vector2(0.4849246f, 0.3082077f) }, new Vector3[] { new Vector2(0.3056951f, 0.5041876f), new Vector2(0.3073702f, 0.5427136f) }, new Vector3[] { new Vector2(0.377722f, 0.6415411f), new Vector2(0.3911223f, 0.6817421f) }, new Vector3[] { new Vector2(0.2855946f, 0.6716918f), new Vector2(0.298995f, 0.7035176f) }, new Vector3[] { new Vector2(0.1884422f, 0.7018425f), new Vector2(0.2068677f, 0.7336683f) }, new Vector3[] { new Vector2(0.6641541f, 0.8643216f), new Vector2(0.6407035f, 0.8894472f), new Vector2(0.6541038f, 0.9564489f) }, new Vector3[] { new Vector2(0.2142857f, 0.4789916f), new Vector2(0.2142857f, 0.5126051f) }, new Vector3[] { new Vector2(0.4327731f, 0.5831933f), new Vector2(0.4277311f, 0.605042f), new Vector2(0.4092437f, 0.6252101f) }, new Vector3[] { new Vector2(0.09495801f, 0.5478992f), new Vector2(0.07815129f, 0.5109244f), new Vector2(0.07983196f, 0.4789916f), new Vector2(0.08991599f, 0.4588235f) } }; } return icon_rightHandRule; } + Vector3[][] Icon_megaphone() { if (icon_megaphone == null) { icon_megaphone = new Vector3[][] { new Vector3[] { new Vector2(0.7116182f, 0.8008299f), new Vector2(0.7116182f, 0.1950208f), new Vector2(0.6473029f, 0.2634855f), new Vector2(0.5643154f, 0.3340249f), new Vector2(0.4958506f, 0.3651452f), new Vector2(0.4273859f, 0.3796681f), new Vector2(0.1369295f, 0.3796681f), new Vector2(0.1369295f, 0.6244813f), new Vector2(0.4315353f, 0.6244813f), new Vector2(0.4917012f, 0.6369295f), new Vector2(0.560166f, 0.6659751f), new Vector2(0.6203319f, 0.7116182f), new Vector2(0.7116182f, 0.8008299f) }, new Vector3[] { new Vector2(0.1369295f, 0.6037344f), new Vector2(0.1058091f, 0.6016598f), new Vector2(0.06431536f, 0.5705394f), new Vector2(0.0373444f, 0.5290456f), new Vector2(0.0373444f, 0.473029f), new Vector2(0.05809129f, 0.4294606f), new Vector2(0.09751038f, 0.4024896f), new Vector2(0.1348548f, 0.4004149f) }, new Vector3[] { new Vector2(0.7116182f, 0.5809129f), new Vector2(0.7365145f, 0.5622407f), new Vector2(0.7551867f, 0.5394191f), new Vector2(0.7655602f, 0.4958506f), new Vector2(0.7551867f, 0.4543568f), new Vector2(0.7365145f, 0.4294606f), new Vector2(0.713693f, 0.4128631f) }, new Vector3[] { new Vector2(0.7987552f, 0.6639004f), new Vector2(0.8319502f, 0.626556f), new Vector2(0.8609958f, 0.5539419f), new Vector2(0.8672199f, 0.5020747f), new Vector2(0.8589212f, 0.4439834f), new Vector2(0.8319502f, 0.3900415f), new Vector2(0.7966805f, 0.3443983f) }, new Vector3[] { new Vector2(0.8692946f, 0.7323651f), new Vector2(0.9045643f, 0.6825726f), new Vector2(0.9377593f, 0.6120332f), new Vector2(0.9543568f, 0.5560166f), new Vector2(0.9585062f, 0.5f), new Vector2(0.9502075f, 0.4294606f), new Vector2(0.9273859f, 0.3651452f), new Vector2(0.8941908f, 0.3195021f), new Vector2(0.8589212f, 0.280083f) }, new Vector3[] { new Vector2(0.1804979f, 0.3775934f), new Vector2(0.2717842f, 0.1618257f), new Vector2(0.4128631f, 0.1618257f), new Vector2(0.3174274f, 0.3796681f) } }; } return icon_megaphone; } + Vector3[][] Icon_arrowLeft() { if (icon_arrowLeft == null) { icon_arrowLeft = new Vector3[][] { new Vector3[] { new Vector2(0.5063869f, 0.3777372f), new Vector2(0.915146f, 0.3777373f), new Vector2(0.915146f, 0.6441606f), new Vector2(0.5082117f, 0.6441606f), new Vector2(0.5082117f, 0.8448905f), new Vector2(0.05930662f, 0.5f), new Vector2(0.5063869f, 0.1368613f), new Vector2(0.5063869f, 0.3777372f) } }; } return icon_arrowLeft; } + Vector3[][] Icon_arrowRight() { if (icon_arrowRight == null) { icon_arrowRight = new Vector3[][] { new Vector3[] { new Vector2(0.4936131f, 0.6222628f), new Vector2(0.08485401f, 0.6222628f), new Vector2(0.08485401f, 0.3558394f), new Vector2(0.4917883f, 0.3558394f), new Vector2(0.4917883f, 0.1551095f), new Vector2(0.9406934f, 0.5f), new Vector2(0.4936131f, 0.8631387f), new Vector2(0.4936131f, 0.6222628f) } }; } return icon_arrowRight; } + Vector3[][] Icon_arrowUp() { if (icon_arrowUp == null) { icon_arrowUp = new Vector3[][] { new Vector3[] { new Vector2(0.3777372f, 0.4936131f), new Vector2(0.3777372f, 0.08485404f), new Vector2(0.6441606f, 0.08485404f), new Vector2(0.6441606f, 0.4917883f), new Vector2(0.8448905f, 0.4917883f), new Vector2(0.5f, 0.9406934f), new Vector2(0.1368614f, 0.4936131f), new Vector2(0.3777372f, 0.4936131f) } }; } return icon_arrowUp; } + Vector3[][] Icon_arrowDown() { if (icon_arrowDown == null) { icon_arrowDown = new Vector3[][] { new Vector3[] { new Vector2(0.6222628f, 0.5063869f), new Vector2(0.6222627f, 0.915146f), new Vector2(0.3558394f, 0.915146f), new Vector2(0.3558394f, 0.5082117f), new Vector2(0.1551095f, 0.5082117f), new Vector2(0.5f, 0.05930665f), new Vector2(0.8631387f, 0.5063869f), new Vector2(0.6222628f, 0.5063869f) } }; } return icon_arrowDown; } + Vector3[][] Icon_healthBox() { if (icon_healthBox == null) { icon_healthBox = new Vector3[][] { new Vector3[] { new Vector2(0.05186722f, 0.3008299f), new Vector2(0.05186722f, 0.5290456f), new Vector2(0.2655602f, 0.8402489f), new Vector2(0.9502075f, 0.6825726f), new Vector2(0.9502075f, 0.466805f), new Vector2(0.7365145f, 0.1514523f), new Vector2(0.05186722f, 0.3008299f) }, new Vector3[] { new Vector2(0.7365145f, 0.153527f), new Vector2(0.7365145f, 0.373444f), new Vector2(0.9481328f, 0.6846473f) }, new Vector3[] { new Vector2(0.3319502f, 0.4087137f), new Vector2(0.3319502f, 0.2904564f), new Vector2(0.4502075f, 0.2614108f), new Vector2(0.4502075f, 0.3796681f), new Vector2(0.3319502f, 0.4087137f) }, new Vector3[] { new Vector2(0.7344398f, 0.373444f), new Vector2(0.05186722f, 0.5311204f) }, new Vector3[] { new Vector2(0.7365145f, 0.2551867f), new Vector2(0.9502075f, 0.560166f) }, new Vector3[] { new Vector2(0.9502075f, 0.5767635f), new Vector2(0.7344398f, 0.2697096f), new Vector2(0.4502075f, 0.3319502f) }, new Vector3[] { new Vector2(0.7385892f, 0.253112f), new Vector2(0.4502075f, 0.3174274f) }, new Vector3[] { new Vector2(0.3298755f, 0.3609959f), new Vector2(0.04979253f, 0.4211618f) }, new Vector3[] { new Vector2(0.3278008f, 0.346473f), new Vector2(0.04979253f, 0.406639f) }, new Vector3[] { new Vector2(0.2987552f, 0.6120332f), new Vector2(0.4170125f, 0.5892116f), new Vector2(0.373444f, 0.5186722f), new Vector2(0.4958506f, 0.4896266f), new Vector2(0.5394191f, 0.560166f), new Vector2(0.6493776f, 0.5373444f), new Vector2(0.6991701f, 0.6037344f), new Vector2(0.5892116f, 0.6327801f), new Vector2(0.6286307f, 0.6929461f), new Vector2(0.5062241f, 0.719917f), new Vector2(0.4647303f, 0.653527f), new Vector2(0.3485477f, 0.6825726f), new Vector2(0.2987552f, 0.6120332f) }, new Vector3[] { new Vector2(0.3879668f, 0.3672199f), new Vector2(0.3879668f, 0.3008299f) } }; } return icon_healthBox; } + Vector3[][] Icon_iceIcicle() { if (icon_iceIcicle == null) { icon_iceIcicle = new Vector3[][] { new Vector3[] { new Vector2(0.0746888f, 0.9647303f), new Vector2(0.9377593f, 0.9647303f), new Vector2(0.8319502f, 0.9439834f), new Vector2(0.7780083f, 0.9190871f), new Vector2(0.7219917f, 0.8485477f), new Vector2(0.6825726f, 0.6286307f), new Vector2(0.6431535f, 0.8921162f), new Vector2(0.6037344f, 0.4294606f), new Vector2(0.5290456f, 0.8983402f), new Vector2(0.473029f, 0.5580913f), new Vector2(0.4211618f, 0.906639f), new Vector2(0.373444f, 0.373444f), new Vector2(0.3112033f, 0.8921162f), new Vector2(0.2780083f, 0.7302905f), new Vector2(0.2323651f, 0.9315352f), new Vector2(0.2095436f, 0.8526971f), new Vector2(0.1970954f, 0.9149377f), new Vector2(0.1659751f, 0.9439834f), new Vector2(0.0746888f, 0.9647303f) }, new Vector3[] { new Vector2(0.3755187f, 0.2219917f), new Vector2(0.4211618f, 0.093361f), new Vector2(0.4253112f, 0.06846473f), new Vector2(0.4190871f, 0.04564315f), new Vector2(0.4045643f, 0.02697095f), new Vector2(0.3775934f, 0.02282158f), new Vector2(0.3423237f, 0.0373444f), new Vector2(0.3257262f, 0.05809129f), new Vector2(0.3257262f, 0.08298755f), new Vector2(0.3340249f, 0.1182573f), new Vector2(0.3755187f, 0.2219917f) }, new Vector3[] { new Vector2(0.6037344f, 0.373444f), new Vector2(0.6493776f, 0.2489627f), new Vector2(0.6514523f, 0.2240664f), new Vector2(0.6431535f, 0.1970954f), new Vector2(0.6182573f, 0.1825726f), new Vector2(0.5809129f, 0.1825726f), new Vector2(0.560166f, 0.2074689f), new Vector2(0.5518672f, 0.2365145f), new Vector2(0.5643154f, 0.2697096f), new Vector2(0.6037344f, 0.373444f) } }; } return icon_iceIcicle; } + Vector3[][] Icon_pickAxe() { if (icon_pickAxe == null) { icon_pickAxe = new Vector3[][] { new Vector3[] { new Vector2(0.7095436f, 0.8298755f), new Vector2(0.8215768f, 0.7074689f), new Vector2(0.7074689f, 0.593361f), new Vector2(0.5871369f, 0.7116182f), new Vector2(0.7095436f, 0.8298755f) }, new Vector3[] { new Vector2(0.8029045f, 0.686722f), new Vector2(0.8568465f, 0.6058092f), new Vector2(0.9024896f, 0.5228216f), new Vector2(0.9273859f, 0.4460581f), new Vector2(0.9419087f, 0.3443983f), new Vector2(0.8900415f, 0.4522822f), new Vector2(0.8319502f, 0.5394191f), new Vector2(0.7738589f, 0.6016598f), new Vector2(0.7406639f, 0.6286307f) }, new Vector3[] { new Vector2(0.6784232f, 0.8008299f), new Vector2(0.5975104f, 0.8651452f), new Vector2(0.5124481f, 0.9128631f), new Vector2(0.43361f, 0.9377593f), new Vector2(0.3381743f, 0.9502075f), new Vector2(0.4315353f, 0.9045643f), new Vector2(0.5041494f, 0.8589212f), new Vector2(0.56639f, 0.8049793f), new Vector2(0.6161826f, 0.7448133f) }, new Vector3[] { new Vector2(0.6182573f, 0.686722f), new Vector2(0.03941909f, 0.1016598f), new Vector2(0.1016598f, 0.03319502f), new Vector2(0.6804979f, 0.6182573f) }, new Vector3[] { new Vector2(0.7344398f, 0.8029045f), new Vector2(0.7572614f, 0.8257262f), new Vector2(0.8195021f, 0.7593361f), new Vector2(0.7946058f, 0.7385892f) } }; } return icon_pickAxe; } + Vector3[][] Icon_audioSpeakerMute() { if (icon_audioSpeakerMute == null) { icon_audioSpeakerMute = new Vector3[][] { new Vector3[] { new Vector2(0.3284314f, 0.6405229f), new Vector2(0.06045752f, 0.6405229f), new Vector2(0.06045752f, 0.3562092f), new Vector2(0.3284314f, 0.3562092f), new Vector2(0.509804f, 0.1846405f), new Vector2(0.509804f, 0.8202614f), new Vector2(0.3284314f, 0.6405229f) }, new Vector3[] { new Vector2(0.6307189f, 0.6290849f), new Vector2(0.8921568f, 0.3627451f) }, new Vector3[] { new Vector2(0.6339869f, 0.3594771f), new Vector2(0.8970588f, 0.627451f) } }; } return icon_audioSpeakerMute; } + Vector3[][] Icon_chestTreasureBox_open() { if (icon_chestTreasureBox_open == null) { icon_chestTreasureBox_open = new Vector3[][] { new Vector3[] { new Vector2(0.1276596f, 0.5567376f), new Vector2(0.1276596f, 0.214539f), new Vector2(0.6382979f, 0.04609929f), new Vector2(0.856383f, 0.2216312f), new Vector2(0.856383f, 0.5567376f), new Vector2(0.6382979f, 0.4521277f), new Vector2(0.1276596f, 0.5567376f), new Vector2(0.3900709f, 0.641844f), new Vector2(0.2180851f, 0.8723404f), new Vector2(0.7234042f, 0.8280142f), new Vector2(0.856383f, 0.5638298f) }, new Vector3[] { new Vector2(0.7234042f, 0.8262411f), new Vector2(0.7446808f, 0.8617021f), new Vector2(0.7677305f, 0.8865248f), new Vector2(0.7960993f, 0.8953901f), new Vector2(0.822695f, 0.891844f), new Vector2(0.856383f, 0.8705674f), new Vector2(0.8758865f, 0.8368794f), new Vector2(0.891844f, 0.7765958f), new Vector2(0.8953901f, 0.7109929f), new Vector2(0.8882979f, 0.641844f), new Vector2(0.8741135f, 0.5975177f), new Vector2(0.8546099f, 0.5602837f) }, new Vector3[] { new Vector2(0.8173759f, 0.8953901f), new Vector2(0.3368794f, 0.9343972f), new Vector2(0.2978723f, 0.9255319f), new Vector2(0.2659574f, 0.9095744f), new Vector2(0.2429078f, 0.893617f), new Vector2(0.2198582f, 0.8723404f) }, new Vector3[] { new Vector2(0.3368794f, 0.5460993f), new Vector2(0.3758865f, 0.5833333f), new Vector2(0.4166667f, 0.6117021f), new Vector2(0.4680851f, 0.6400709f), new Vector2(0.5265958f, 0.6507092f), new Vector2(0.5921986f, 0.6507092f), new Vector2(0.643617f, 0.6312057f), new Vector2(0.6861702f, 0.6046099f), new Vector2(0.7163121f, 0.569149f), new Vector2(0.7393617f, 0.5336879f) }, new Vector3[] { new Vector2(0.8546099f, 0.5638298f), new Vector2(0.7517731f, 0.5815603f) }, new Vector3[] { new Vector2(0.6382979f, 0.4539007f), new Vector2(0.6382979f, 0.04255319f) }, new Vector3[] { new Vector2(0.4503546f, 0.4893617f), new Vector2(0.4503546f, 0.108156f) }, new Vector3[] { new Vector2(0.2819149f, 0.5230497f), new Vector2(0.2819149f, 0.1595745f) }, new Vector3[] { new Vector2(0.6719858f, 0.6613475f), new Vector2(0.714539f, 0.7322695f) }, new Vector3[] { new Vector2(0.5762411f, 0.6879433f), new Vector2(0.5762411f, 0.7872341f) }, new Vector3[] { new Vector2(0.462766f, 0.6879433f), new Vector2(0.4237589f, 0.7677305f) } }; } return icon_chestTreasureBox_open; } + Vector3[][] Icon_doorClosed() { if (icon_doorClosed == null) { icon_doorClosed = new Vector3[][] { new Vector3[] { new Vector2(0.129085f, 0.1830065f), new Vector2(0.8660131f, 0.1830065f) }, new Vector3[] { new Vector2(0.2957516f, 0.1846405f), new Vector2(0.2957516f, 0.8169935f), new Vector2(0.6960784f, 0.8169935f), new Vector2(0.6960784f, 0.1813726f) }, new Vector3[] { new Vector2(0.2630719f, 0.1846405f), new Vector2(0.2630719f, 0.8464052f), new Vector2(0.7271242f, 0.8464052f), new Vector2(0.7271242f, 0.1813726f) }, new Vector3[] { new Vector2(0.3349673f, 0.5212418f), new Vector2(0.3349673f, 0.4738562f) }, new Vector3[] { new Vector2(0.3366013f, 0.509804f), new Vector2(0.4101307f, 0.509804f), new Vector2(0.4101307f, 0.4885621f), new Vector2(0.3349673f, 0.4885621f) } }; } return icon_doorClosed; } + + Vector3[][] char_a; + Vector3[][] char_b; + Vector3[][] char_c; + Vector3[][] char_d; + Vector3[][] char_e; + Vector3[][] char_f; + Vector3[][] char_g; + Vector3[][] char_h; + Vector3[][] char_i; + Vector3[][] char_j; + Vector3[][] char_k; + Vector3[][] char_l; + Vector3[][] char_m; + Vector3[][] char_n; + Vector3[][] char_o; + Vector3[][] char_p; + Vector3[][] char_q; + Vector3[][] char_r; + Vector3[][] char_s; + Vector3[][] char_t; + Vector3[][] char_u; + Vector3[][] char_v; + Vector3[][] char_w; + Vector3[][] char_x; + Vector3[][] char_y; + Vector3[][] char_z; + Vector3[][] char_ae; + Vector3[][] char_oe; + Vector3[][] char_ue; + + Vector3[][] char_A; + Vector3[][] char_B; + Vector3[][] char_C; + Vector3[][] char_D; + Vector3[][] char_E; + Vector3[][] char_F; + Vector3[][] char_G; + Vector3[][] char_H; + Vector3[][] char_I; + Vector3[][] char_J; + Vector3[][] char_K; + Vector3[][] char_L; + Vector3[][] char_M; + Vector3[][] char_N; + Vector3[][] char_O; + Vector3[][] char_P; + Vector3[][] char_Q; + Vector3[][] char_R; + Vector3[][] char_S; + Vector3[][] char_T; + Vector3[][] char_U; + Vector3[][] char_V; + Vector3[][] char_W; + Vector3[][] char_X; + Vector3[][] char_Y; + Vector3[][] char_Z; + Vector3[][] char_AE; + Vector3[][] char_OE; + Vector3[][] char_UE; + + Vector3[][] char_0; + Vector3[][] char_1; + Vector3[][] char_2; + Vector3[][] char_3; + Vector3[][] char_4; + Vector3[][] char_5; + Vector3[][] char_6; + Vector3[][] char_7; + Vector3[][] char_8; + Vector3[][] char_9; + + Vector3[][] char_space; + Vector3[][] char_unknown; + Vector3[][] char_dollar; + Vector3[][] char_euro; + Vector3[][] char_hashtag; + Vector3[][] char_exclamationMark; + Vector3[][] char_questionMark; + Vector3[][] char_quote; + Vector3[][] char_doublequote; + Vector3[][] char_plus; + Vector3[][] char_minus; + Vector3[][] char_comma; + Vector3[][] char_asterisk; + Vector3[][] char_underscore; + Vector3[][] char_period; + Vector3[][] char_forwardslash; + Vector3[][] char_backwardslash; + Vector3[][] char_colon; + Vector3[][] char_semicolon; + Vector3[][] char_lessthan; + Vector3[][] char_equals; + Vector3[][] char_greaterthan; + Vector3[][] char_percent; + Vector3[][] char_ampersand; + Vector3[][] char_openbracket; + Vector3[][] char_closebracket; + Vector3[][] char_opensquarebracket; + Vector3[][] char_closesquarebracket; + Vector3[][] char_leftbrace; + Vector3[][] char_rightbrace; + Vector3[][] char_verticalbar; + Vector3[][] char_at; + Vector3[][] char_caret; + Vector3[][] char_tilde; + Vector3[][] char_degree; + Vector3[][] char_section; + + Vector3[][] icon_profileFoto; + Vector3[][] icon_imageLandscape; + Vector3[][] icon_homeHouse; + Vector3[][] icon_dataDisc; + Vector3[][] icon_saveData; + Vector3[][] icon_loadData; + Vector3[][] icon_speechBubble; + Vector3[][] icon_speechBubbleEmpty; + Vector3[][] icon_thumbUp; + Vector3[][] icon_thumbDown; + Vector3[][] icon_lightBulbOn; + Vector3[][] icon_lightBulbOff; + Vector3[][] icon_videoCamera; + Vector3[][] icon_camera; + Vector3[][] icon_music; + Vector3[][] icon_audioSpeaker; + Vector3[][] icon_microphone; + Vector3[][] icon_wlan_wifi; + Vector3[][] icon_share; + Vector3[][] icon_timeClock; + Vector3[][] icon_telephone; + Vector3[][] icon_doorOpen; + Vector3[][] icon_doorEnter; + Vector3[][] icon_doorLeave; + Vector3[][] icon_locationPin; + Vector3[][] icon_folder; + Vector3[][] icon_saveToFolder; + Vector3[][] icon_loadFromFolder; + Vector3[][] icon_optionsSettingsGear; + Vector3[][] icon_adjustOptionsSettings; + Vector3[][] icon_pen; + Vector3[][] icon_questionMark; + Vector3[][] icon_exclamationMark; + Vector3[][] icon_shoppingCart; + Vector3[][] icon_checkmarkChecked; + Vector3[][] icon_checkmarkUnchecked; + Vector3[][] icon_battery; + Vector3[][] icon_cloud; + Vector3[][] icon_magnifier; + Vector3[][] icon_magnifierPlus; + Vector3[][] icon_magnifierMinus; + Vector3[][] icon_timeHourglassCursor; + Vector3[][] icon_cursorHand; + Vector3[][] icon_cursorPointer; + Vector3[][] icon_trashcan; + Vector3[][] icon_switchOnOff; + Vector3[][] icon_playButton; + Vector3[][] icon_pauseButton; + Vector3[][] icon_stopButton; + Vector3[][] icon_playPauseButton; + Vector3[][] icon_heart; + Vector3[][] icon_coin; + Vector3[][] icon_coins; + Vector3[][] icon_moneyBills; + Vector3[][] icon_moneyBag; + Vector3[][] icon_chestTreasureBox_closed; + Vector3[][] icon_lootbox; + Vector3[][] icon_crown; + Vector3[][] icon_trophy; + Vector3[][] icon_awardMedal; + Vector3[][] icon_sword; + Vector3[][] icon_shield; + Vector3[][] icon_gun; + Vector3[][] icon_bullet; + Vector3[][] icon_rocket; + Vector3[][] icon_crosshair; + Vector3[][] icon_arrow; + Vector3[][] icon_arrowBow; + Vector3[][] icon_bomb; + Vector3[][] icon_shovel; + Vector3[][] icon_hammer; + Vector3[][] icon_axe; + Vector3[][] icon_magnet; + Vector3[][] icon_compass; + Vector3[][] icon_fuelStation; + Vector3[][] icon_fuelCan; + Vector3[][] icon_lockLocked; + Vector3[][] icon_lockUnlocked; + Vector3[][] icon_key; + Vector3[][] icon_gemDiamond; + Vector3[][] icon_gold; + Vector3[][] icon_potion; + Vector3[][] icon_presentGift; + Vector3[][] icon_death; + Vector3[][] icon_map; + Vector3[][] icon_mushroom; + Vector3[][] icon_star; + Vector3[][] icon_pill; + Vector3[][] icon_health; + Vector3[][] icon_foodPlate; + Vector3[][] icon_foodMeat; + Vector3[][] icon_flag; + Vector3[][] icon_flagChequered; + Vector3[][] icon_ball; + Vector3[][] icon_dice; + Vector3[][] icon_joystick; + Vector3[][] icon_gamepad; + Vector3[][] icon_jigsawPuzzle; + Vector3[][] icon_fish; + Vector3[][] icon_car; + Vector3[][] icon_tree; + Vector3[][] icon_palm; + Vector3[][] icon_leaf; + Vector3[][] icon_nukeNuclearWarning; + Vector3[][] icon_biohazardWarning; + Vector3[][] icon_fireWarning; + Vector3[][] icon_warning; + Vector3[][] icon_emergencyExit; + Vector3[][] icon_sun; + Vector3[][] icon_rain; + Vector3[][] icon_wind; + Vector3[][] icon_snow; + Vector3[][] icon_lightning; + Vector3[][] icon_fire; + Vector3[][] icon_unitSquare; + Vector3[][] icon_unitSquareIncl1Right; + Vector3[][] icon_unitSquareIncl2Right; + Vector3[][] icon_unitSquareIncl3Right; + Vector3[][] icon_unitSquareIncl4Right; + Vector3[][] icon_unitSquareIncl5Right; + Vector3[][] icon_unitSquareIncl6Right; + Vector3[][] icon_unitSquareCrossed; + Vector3[][] icon_unitCircle; + Vector3[][] icon_animal; + Vector3[][] icon_bird; + Vector3[][] icon_humanMale; + Vector3[][] icon_humanFemale; + Vector3[][] icon_bombExplosion; + Vector3[][] icon_tower; + Vector3[][] icon_circleDotFilled; + Vector3[][] icon_circleDotUnfilled; + Vector3[][] icon_logMessage; + Vector3[][] icon_logMessageError; + Vector3[][] icon_logMessageException; + Vector3[][] icon_logMessageAssertion; + Vector3[][] icon_up_oneStroke; + Vector3[][] icon_up_twoStroke; + Vector3[][] icon_up_threeStroke; + Vector3[][] icon_down_oneStroke; + Vector3[][] icon_down_twoStroke; + Vector3[][] icon_down_threeStroke; + Vector3[][] icon_left_oneStroke; + Vector3[][] icon_left_twoStroke; + Vector3[][] icon_left_threeStroke; + Vector3[][] icon_right_oneStroke; + Vector3[][] icon_right_twoStroke; + Vector3[][] icon_right_threeStroke; + Vector3[][] icon_fist; + Vector3[][] icon_boxingGlove; + Vector3[][] icon_stars5Rate; + Vector3[][] icon_stars3; + Vector3[][] icon_shootingStar; + Vector3[][] icon_moonHalf; + Vector3[][] icon_moonFullPlanet; + Vector3[][] icon_leftHandRule; + Vector3[][] icon_rightHandRule; + Vector3[][] icon_megaphone; + Vector3[][] icon_arrowLeft; + Vector3[][] icon_arrowRight; + Vector3[][] icon_arrowUp; + Vector3[][] icon_arrowDown; + Vector3[][] icon_healthBox; + Vector3[][] icon_iceIcicle; + Vector3[][] icon_pickAxe; + Vector3[][] icon_audioSpeakerMute; + Vector3[][] icon_chestTreasureBox_open; + Vector3[][] icon_doorClosed; + + public Vector3[][] GetPointsArray(char requestedChar, out bool charIsMissing) + { + charIsMissing = false; + switch (requestedChar) + { + //small letters: + case 'a': + return Char_a(); + + case 'b': + return Char_b(); + + case 'c': + return Char_c(); + + case 'd': + return Char_d(); + + case 'e': + return Char_e(); + + case 'f': + return Char_f(); + + case 'g': + return Char_g(); + + case 'h': + return Char_h(); + + case 'i': + return Char_i(); + + case 'j': + return Char_j(); + + case 'k': + return Char_k(); + + case 'l': + return Char_l(); + + case 'm': + return Char_m(); + + case 'n': + return Char_n(); + + case 'o': + return Char_o(); + + case 'p': + return Char_p(); + + case 'q': + return Char_q(); + + case 'r': + return Char_r(); + + case 's': + return Char_s(); + + case 't': + return Char_t(); + + case 'u': + return Char_u(); + + case 'v': + return Char_v(); + + case 'w': + return Char_w(); + + case 'x': + return Char_x(); + + case 'y': + return Char_y(); + + case 'z': + return Char_z(); + + case 'ä': + return Char_ae(); + + case 'ö': + return Char_oe(); + + case 'ü': + return Char_ue(); + + //capital letters: + case 'A': + return Char_A(); + + case 'B': + return Char_B(); + + case 'C': + return Char_C(); + + case 'D': + return Char_D(); + + case 'E': + return Char_E(); + + case 'F': + return Char_F(); + + case 'G': + return Char_G(); + + case 'H': + return Char_H(); + + case 'I': + return Char_I(); + + case 'J': + return Char_J(); + + case 'K': + return Char_K(); + + case 'L': + return Char_L(); + + case 'M': + return Char_M(); + + case 'N': + return Char_N(); + + case 'O': + return Char_O(); + + case 'P': + return Char_P(); + + case 'Q': + return Char_Q(); + + case 'R': + return Char_R(); + + case 'S': + return Char_S(); + + case 'T': + return Char_T(); + + case 'U': + return Char_U(); + + case 'V': + return Char_V(); + + case 'W': + return Char_W(); + + case 'X': + return Char_X(); + + case 'Y': + return Char_Y(); + + case 'Z': + return Char_Z(); + + case 'Ä': + return Char_AE(); + + case 'Ö': + return Char_OE(); + + case 'Ü': + return Char_UE(); + + //numbers: + case '0': + return Char_0(); + + case '1': + return Char_1(); + + case '2': + return Char_2(); + + case '3': + return Char_3(); + + case '4': + return Char_4(); + + case '5': + return Char_5(); + + case '6': + return Char_6(); + + case '7': + return Char_7(); + + case '8': + return Char_8(); + + case '9': + return Char_9(); + + //special chars: + case ' ': + return Char_space(); + + case '$': + return Char_dollar(); + + case '€': + return Char_euro(); + + case '#': + return Char_hashtag(); + + case '!': + return Char_exclamationMark(); + + case '?': + return Char_questionMark(); + + case '\'': + return Char_quote(); + + case '\"': + return Char_doublequote(); + + case '+': + return Char_plus(); + + case '-': + return Char_minus(); + + case ',': + return Char_comma(); + + case '*': + return Char_asterisk(); + + case '_': + return Char_underscore(); + + case '.': + return Char_period(); + + case '/': + return Char_forwardslash(); + + case '\\': + return Char_backwardslash(); + + case ':': + return Char_colon(); + + case ';': + return Char_semicolon(); + + case '<': + return Char_lessthan(); + + case '=': + return Char_equals(); + + case '>': + return Char_greaterthan(); + + case '%': + return Char_percent(); + + case '&': + return Char_ampersand(); + + case '(': + return Char_openbracket(); + + case ')': + return Char_closebracket(); + + case '[': + return Char_opensquarebracket(); + + case ']': + return Char_closesquarebracket(); + + case '{': + return Char_leftbrace(); + + case '}': + return Char_rightbrace(); + + case '|': + return Char_verticalbar(); + + case '@': + return Char_at(); + + case '^': + return Char_caret(); + + case '~': + return Char_tilde(); + + case '°': + return Char_degree(); + + case '§': + return Char_section(); + + default: + charIsMissing = true; + return Char_unknown(); + } + } + + public Vector3[][] GetPointsArray(string iconName, out bool charIsMissing) + { + charIsMissing = false; + switch (iconName) + { + case "profileFoto": + return Icon_profileFoto(); + + case "imageLandscape": + return Icon_imageLandscape(); + + case "homeHouse": + return Icon_homeHouse(); + + case "dataDisc": + return Icon_dataDisc(); + + case "saveData": + return Icon_saveData(); + + case "loadData": + return Icon_loadData(); + + case "speechBubble": + return Icon_speechBubble(); + + case "speechBubbleEmpty": + return Icon_speechBubbleEmpty(); + + case "thumbUp": + return Icon_thumbUp(); + + case "thumbDown": + return Icon_thumbDown(); + + case "lightBulbOn": + return Icon_lightBulbOn(); + + case "lightBulbOff": + return Icon_lightBulbOff(); + + case "videoCamera": + return Icon_videoCamera(); + + case "camera": + return Icon_camera(); + + case "music": + return Icon_music(); + + case "audioSpeaker": + return Icon_audioSpeaker(); + + case "microphone": + return Icon_microphone(); + + case "wlan_wifi": + return Icon_wlan_wifi(); + + case "share": + return Icon_share(); + + case "timeClock": + return Icon_timeClock(); + + case "telephone": + return Icon_telephone(); + + case "doorOpen": + return Icon_doorOpen(); + + case "doorEnter": + return Icon_doorEnter(); + + case "doorLeave": + return Icon_doorLeave(); + + case "locationPin": + return Icon_locationPin(); + + case "folder": + return Icon_folder(); + + case "saveToFolder": + return Icon_saveToFolder(); + + case "loadFromFolder": + return Icon_loadFromFolder(); + + case "optionsSettingsGear": + return Icon_optionsSettingsGear(); + + case "adjustOptionsSettings": + return Icon_adjustOptionsSettings(); + + case "pen": + return Icon_pen(); + + case "questionMark": + return Icon_questionMark(); + + case "exclamationMark": + return Icon_exclamationMark(); + + case "shoppingCart": + return Icon_shoppingCart(); + + case "checkmarkChecked": + return Icon_checkmarkChecked(); + + case "checkmarkUnchecked": + return Icon_checkmarkUnchecked(); + + case "battery": + return Icon_battery(); + + case "cloud": + return Icon_cloud(); + + case "magnifier": + return Icon_magnifier(); + + case "magnifierPlus": + return Icon_magnifierPlus(); + + case "magnifierMinus": + return Icon_magnifierMinus(); + + case "timeHourglassCursor": + return Icon_timeHourglassCursor(); + + case "cursorHand": + return Icon_cursorHand(); + + case "cursorPointer": + return Icon_cursorPointer(); + + case "trashcan": + return Icon_trashcan(); + + case "switchOnOff": + return Icon_switchOnOff(); + + case "playButton": + return Icon_playButton(); + + case "pauseButton": + return Icon_pauseButton(); + + case "stopButton": + return Icon_stopButton(); + + case "playPauseButton": + return Icon_playPauseButton(); + + case "heart": + return Icon_heart(); + + case "coin": + return Icon_coin(); + + case "coins": + return Icon_coins(); + + case "moneyBills": + return Icon_moneyBills(); + + case "moneyBag": + return Icon_moneyBag(); + + case "chestTreasureBox_closed": + return Icon_chestTreasureBox_closed(); + + case "lootbox": + return Icon_lootbox(); + + case "crown": + return Icon_crown(); + + case "trophy": + return Icon_trophy(); + + case "awardMedal": + return Icon_awardMedal(); + + case "sword": + return Icon_sword(); + + case "shield": + return Icon_shield(); + + case "gun": + return Icon_gun(); + + case "bullet": + return Icon_bullet(); + + case "rocket": + return Icon_rocket(); + + case "crosshair": + return Icon_crosshair(); + + case "arrow": + return Icon_arrow(); + + case "arrowBow": + return Icon_arrowBow(); + + case "bomb": + return Icon_bomb(); + + case "shovel": + return Icon_shovel(); + + case "hammer": + return Icon_hammer(); + + case "axe": + return Icon_axe(); + + case "magnet": + return Icon_magnet(); + + case "compass": + return Icon_compass(); + + case "fuelStation": + return Icon_fuelStation(); + + case "fuelCan": + return Icon_fuelCan(); + + case "lockLocked": + return Icon_lockLocked(); + + case "lockUnlocked": + return Icon_lockUnlocked(); + + case "key": + return Icon_key(); + + case "gemDiamond": + return Icon_gemDiamond(); + + case "gold": + return Icon_gold(); + + case "potion": + return Icon_potion(); + + case "presentGift": + return Icon_presentGift(); + + case "death": + return Icon_death(); + + case "map": + return Icon_map(); + + case "mushroom": + return Icon_mushroom(); + + case "star": + return Icon_star(); + + case "pill": + return Icon_pill(); + + case "health": + return Icon_health(); + + case "foodPlate": + return Icon_foodPlate(); + + case "foodMeat": + return Icon_foodMeat(); + + case "flag": + return Icon_flag(); + + case "flagChequered": + return Icon_flagChequered(); + + case "ball": + return Icon_ball(); + + case "dice": + return Icon_dice(); + + case "joystick": + return Icon_joystick(); + + case "gamepad": + return Icon_gamepad(); + + case "jigsawPuzzle": + return Icon_jigsawPuzzle(); + + case "fish": + return Icon_fish(); + + case "car": + return Icon_car(); + + case "tree": + return Icon_tree(); + + case "palm": + return Icon_palm(); + + case "leaf": + return Icon_leaf(); + + case "nukeNuclearWarning": + return Icon_nukeNuclearWarning(); + + case "biohazardWarning": + return Icon_biohazardWarning(); + + case "fireWarning": + return Icon_fireWarning(); + + case "warning": + return Icon_warning(); + + case "emergencyExit": + return Icon_emergencyExit(); + + case "sun": + return Icon_sun(); + + case "rain": + return Icon_rain(); + + case "wind": + return Icon_wind(); + + case "snow": + return Icon_snow(); + + case "lightning": + return Icon_lightning(); + + case "fire": + return Icon_fire(); + + case "unitSquare": + return Icon_unitSquare(); + + case "unitSquareIncl1Right": + return Icon_unitSquareIncl1Right(); + + case "unitSquareIncl2Right": + return Icon_unitSquareIncl2Right(); + + case "unitSquareIncl3Right": + return Icon_unitSquareIncl3Right(); + + case "unitSquareIncl4Right": + return Icon_unitSquareIncl4Right(); + + case "unitSquareIncl5Right": + return Icon_unitSquareIncl5Right(); + + case "unitSquareIncl6Right": + return Icon_unitSquareIncl6Right(); + + case "unitSquareCrossed": + return Icon_unitSquareCrossed(); + + case "unitCircle": + return Icon_unitCircle(); + + case "animal": + return Icon_animal(); + + case "bird": + return Icon_bird(); + + case "humanMale": + return Icon_humanMale(); + + case "humanFemale": + return Icon_humanFemale(); + + case "bombExplosion": + return Icon_bombExplosion(); + + case "tower": + return Icon_tower(); + + case "circleDotFilled": + return Icon_circleDotFilled(); + + case "circleDotUnfilled": + return Icon_circleDotUnfilled(); + + case "logMessage": + return Icon_logMessage(); + + case "logMessageError": + return Icon_logMessageError(); + + case "logMessageException": + return Icon_logMessageException(); + + case "logMessageAssertion": + return Icon_logMessageAssertion(); + + case "up_oneStroke": + return Icon_up_oneStroke(); + + case "up_twoStroke": + return Icon_up_twoStroke(); + + case "up_threeStroke": + return Icon_up_threeStroke(); + + case "down_oneStroke": + return Icon_down_oneStroke(); + + case "down_twoStroke": + return Icon_down_twoStroke(); + + case "down_threeStroke": + return Icon_down_threeStroke(); + + case "left_oneStroke": + return Icon_left_oneStroke(); + + case "left_twoStroke": + return Icon_left_twoStroke(); + + case "left_threeStroke": + return Icon_left_threeStroke(); + + case "right_oneStroke": + return Icon_right_oneStroke(); + + case "right_twoStroke": + return Icon_right_twoStroke(); + + case "right_threeStroke": + return Icon_right_threeStroke(); + + case "fist": + return Icon_fist(); + + case "boxingGlove": + return Icon_boxingGlove(); + + case "stars5Rate": + return Icon_stars5Rate(); + + case "stars3": + return Icon_stars3(); + + case "shootingStar": + return Icon_shootingStar(); + + case "moonHalf": + return Icon_moonHalf(); + + case "moonFullPlanet": + return Icon_moonFullPlanet(); + + case "leftHandRule": + return Icon_leftHandRule(); + + case "rightHandRule": + return Icon_rightHandRule(); + + case "megaphone": + return Icon_megaphone(); + + case "arrowLeft": + return Icon_arrowLeft(); + + case "arrowRight": + return Icon_arrowRight(); + + case "arrowUp": + return Icon_arrowUp(); + + case "arrowDown": + return Icon_arrowDown(); + + case "healthBox": + return Icon_healthBox(); + + case "iceIcicle": + return Icon_iceIcicle(); + + case "pickAxe": + return Icon_pickAxe(); + + case "audioSpeakerMute": + return Icon_audioSpeakerMute(); + + case "chestTreasureBox_open": + return Icon_chestTreasureBox_open(); + + case "doorClosed": + return Icon_doorClosed(); + + default: + charIsMissing = true; + return Char_unknown(); + } + + } + + public Vector3[][] GetPointsArray(DrawBasics.IconType requestedIcon) + { + switch (requestedIcon) + { + case DrawBasics.IconType.profileFoto: + return Icon_profileFoto(); + + case DrawBasics.IconType.imageLandscape: + return Icon_imageLandscape(); + + case DrawBasics.IconType.homeHouse: + return Icon_homeHouse(); + + case DrawBasics.IconType.dataDisc: + return Icon_dataDisc(); + + case DrawBasics.IconType.saveData: + return Icon_saveData(); + + case DrawBasics.IconType.loadData: + return Icon_loadData(); + + case DrawBasics.IconType.speechBubble: + return Icon_speechBubble(); + + case DrawBasics.IconType.speechBubbleEmpty: + return Icon_speechBubbleEmpty(); + + case DrawBasics.IconType.thumbUp: + return Icon_thumbUp(); + + case DrawBasics.IconType.thumbDown: + return Icon_thumbDown(); + + case DrawBasics.IconType.lightBulbOn: + return Icon_lightBulbOn(); + + case DrawBasics.IconType.lightBulbOff: + return Icon_lightBulbOff(); + + case DrawBasics.IconType.videoCamera: + return Icon_videoCamera(); + + case DrawBasics.IconType.camera: + return Icon_camera(); + + case DrawBasics.IconType.music: + return Icon_music(); + + case DrawBasics.IconType.audioSpeaker: + return Icon_audioSpeaker(); + + case DrawBasics.IconType.microphone: + return Icon_microphone(); + + case DrawBasics.IconType.wlan_wifi: + return Icon_wlan_wifi(); + + case DrawBasics.IconType.share: + return Icon_share(); + + case DrawBasics.IconType.timeClock: + return Icon_timeClock(); + + case DrawBasics.IconType.telephone: + return Icon_telephone(); + + case DrawBasics.IconType.doorOpen: + return Icon_doorOpen(); + + case DrawBasics.IconType.doorEnter: + return Icon_doorEnter(); + + case DrawBasics.IconType.doorLeave: + return Icon_doorLeave(); + + case DrawBasics.IconType.locationPin: + return Icon_locationPin(); + + case DrawBasics.IconType.folder: + return Icon_folder(); + + case DrawBasics.IconType.saveToFolder: + return Icon_saveToFolder(); + + case DrawBasics.IconType.loadFromFolder: + return Icon_loadFromFolder(); + + case DrawBasics.IconType.optionsSettingsGear: + return Icon_optionsSettingsGear(); + + case DrawBasics.IconType.adjustOptionsSettings: + return Icon_adjustOptionsSettings(); + + case DrawBasics.IconType.pen: + return Icon_pen(); + + case DrawBasics.IconType.questionMark: + return Icon_questionMark(); + + case DrawBasics.IconType.exclamationMark: + return Icon_exclamationMark(); + + case DrawBasics.IconType.shoppingCart: + return Icon_shoppingCart(); + + case DrawBasics.IconType.checkmarkChecked: + return Icon_checkmarkChecked(); + + case DrawBasics.IconType.checkmarkUnchecked: + return Icon_checkmarkUnchecked(); + + case DrawBasics.IconType.battery: + return Icon_battery(); + + case DrawBasics.IconType.cloud: + return Icon_cloud(); + + case DrawBasics.IconType.magnifier: + return Icon_magnifier(); + + case DrawBasics.IconType.magnifierPlus: + return Icon_magnifierPlus(); + + case DrawBasics.IconType.magnifierMinus: + return Icon_magnifierMinus(); + + case DrawBasics.IconType.timeHourglassCursor: + return Icon_timeHourglassCursor(); + + case DrawBasics.IconType.cursorHand: + return Icon_cursorHand(); + + case DrawBasics.IconType.cursorPointer: + return Icon_cursorPointer(); + + case DrawBasics.IconType.trashcan: + return Icon_trashcan(); + + case DrawBasics.IconType.switchOnOff: + return Icon_switchOnOff(); + + case DrawBasics.IconType.playButton: + return Icon_playButton(); + + case DrawBasics.IconType.pauseButton: + return Icon_pauseButton(); + + case DrawBasics.IconType.stopButton: + return Icon_stopButton(); + + case DrawBasics.IconType.playPauseButton: + return Icon_playPauseButton(); + + case DrawBasics.IconType.heart: + return Icon_heart(); + + case DrawBasics.IconType.coin: + return Icon_coin(); + + case DrawBasics.IconType.coins: + return Icon_coins(); + + case DrawBasics.IconType.moneyBills: + return Icon_moneyBills(); + + case DrawBasics.IconType.moneyBag: + return Icon_moneyBag(); + + case DrawBasics.IconType.chestTreasureBox_closed: + return Icon_chestTreasureBox_closed(); + + case DrawBasics.IconType.lootbox: + return Icon_lootbox(); + + case DrawBasics.IconType.crown: + return Icon_crown(); + + case DrawBasics.IconType.trophy: + return Icon_trophy(); + + case DrawBasics.IconType.awardMedal: + return Icon_awardMedal(); + + case DrawBasics.IconType.sword: + return Icon_sword(); + + case DrawBasics.IconType.shield: + return Icon_shield(); + + case DrawBasics.IconType.gun: + return Icon_gun(); + + case DrawBasics.IconType.bullet: + return Icon_bullet(); + + case DrawBasics.IconType.rocket: + return Icon_rocket(); + + case DrawBasics.IconType.crosshair: + return Icon_crosshair(); + + case DrawBasics.IconType.arrow: + return Icon_arrow(); + + case DrawBasics.IconType.arrowBow: + return Icon_arrowBow(); + + case DrawBasics.IconType.bomb: + return Icon_bomb(); + + case DrawBasics.IconType.shovel: + return Icon_shovel(); + + case DrawBasics.IconType.hammer: + return Icon_hammer(); + + case DrawBasics.IconType.axe: + return Icon_axe(); + + case DrawBasics.IconType.magnet: + return Icon_magnet(); + + case DrawBasics.IconType.compass: + return Icon_compass(); + + case DrawBasics.IconType.fuelStation: + return Icon_fuelStation(); + + case DrawBasics.IconType.fuelCan: + return Icon_fuelCan(); + + case DrawBasics.IconType.lockLocked: + return Icon_lockLocked(); + + case DrawBasics.IconType.lockUnlocked: + return Icon_lockUnlocked(); + + case DrawBasics.IconType.key: + return Icon_key(); + + case DrawBasics.IconType.gemDiamond: + return Icon_gemDiamond(); + + case DrawBasics.IconType.gold: + return Icon_gold(); + + case DrawBasics.IconType.potion: + return Icon_potion(); + + case DrawBasics.IconType.presentGift: + return Icon_presentGift(); + + case DrawBasics.IconType.death: + return Icon_death(); + + case DrawBasics.IconType.map: + return Icon_map(); + + case DrawBasics.IconType.mushroom: + return Icon_mushroom(); + + case DrawBasics.IconType.star: + return Icon_star(); + + case DrawBasics.IconType.pill: + return Icon_pill(); + + case DrawBasics.IconType.health: + return Icon_health(); + + case DrawBasics.IconType.foodPlate: + return Icon_foodPlate(); + + case DrawBasics.IconType.foodMeat: + return Icon_foodMeat(); + + case DrawBasics.IconType.flag: + return Icon_flag(); + + case DrawBasics.IconType.flagChequered: + return Icon_flagChequered(); + + case DrawBasics.IconType.ball: + return Icon_ball(); + + case DrawBasics.IconType.dice: + return Icon_dice(); + + case DrawBasics.IconType.joystick: + return Icon_joystick(); + + case DrawBasics.IconType.gamepad: + return Icon_gamepad(); + + case DrawBasics.IconType.jigsawPuzzle: + return Icon_jigsawPuzzle(); + + case DrawBasics.IconType.fish: + return Icon_fish(); + + case DrawBasics.IconType.car: + return Icon_car(); + + case DrawBasics.IconType.tree: + return Icon_tree(); + + case DrawBasics.IconType.palm: + return Icon_palm(); + + case DrawBasics.IconType.leaf: + return Icon_leaf(); + + case DrawBasics.IconType.nukeNuclearWarning: + return Icon_nukeNuclearWarning(); + + case DrawBasics.IconType.biohazardWarning: + return Icon_biohazardWarning(); + + case DrawBasics.IconType.fireWarning: + return Icon_fireWarning(); + + case DrawBasics.IconType.warning: + return Icon_warning(); + + case DrawBasics.IconType.emergencyExit: + return Icon_emergencyExit(); + + case DrawBasics.IconType.sun: + return Icon_sun(); + + case DrawBasics.IconType.rain: + return Icon_rain(); + + case DrawBasics.IconType.wind: + return Icon_wind(); + + case DrawBasics.IconType.snow: + return Icon_snow(); + + case DrawBasics.IconType.lightning: + return Icon_lightning(); + + case DrawBasics.IconType.fire: + return Icon_fire(); + + case DrawBasics.IconType.unitSquare: + return Icon_unitSquare(); + + case DrawBasics.IconType.unitSquareIncl1Right: + return Icon_unitSquareIncl1Right(); + + case DrawBasics.IconType.unitSquareIncl2Right: + return Icon_unitSquareIncl2Right(); + + case DrawBasics.IconType.unitSquareIncl3Right: + return Icon_unitSquareIncl3Right(); + + case DrawBasics.IconType.unitSquareIncl4Right: + return Icon_unitSquareIncl4Right(); + + case DrawBasics.IconType.unitSquareIncl5Right: + return Icon_unitSquareIncl5Right(); + + case DrawBasics.IconType.unitSquareIncl6Right: + return Icon_unitSquareIncl6Right(); + + case DrawBasics.IconType.unitSquareCrossed: + return Icon_unitSquareCrossed(); + + case DrawBasics.IconType.unitCircle: + return Icon_unitCircle(); + + case DrawBasics.IconType.animal: + return Icon_animal(); + + case DrawBasics.IconType.bird: + return Icon_bird(); + + case DrawBasics.IconType.humanMale: + return Icon_humanMale(); + + case DrawBasics.IconType.humanFemale: + return Icon_humanFemale(); + + case DrawBasics.IconType.bombExplosion: + return Icon_bombExplosion(); + + case DrawBasics.IconType.tower: + return Icon_tower(); + + case DrawBasics.IconType.circleDotFilled: + return Icon_circleDotFilled(); + + case DrawBasics.IconType.circleDotUnfilled: + return Icon_circleDotUnfilled(); + + case DrawBasics.IconType.logMessage: + return Icon_logMessage(); + + case DrawBasics.IconType.logMessageError: + return Icon_logMessageError(); + + case DrawBasics.IconType.logMessageException: + return Icon_logMessageException(); + + case DrawBasics.IconType.logMessageAssertion: + return Icon_logMessageAssertion(); + + case DrawBasics.IconType.up_oneStroke: + return Icon_up_oneStroke(); + + case DrawBasics.IconType.up_twoStroke: + return Icon_up_twoStroke(); + + case DrawBasics.IconType.up_threeStroke: + return Icon_up_threeStroke(); + + case DrawBasics.IconType.down_oneStroke: + return Icon_down_oneStroke(); + + case DrawBasics.IconType.down_twoStroke: + return Icon_down_twoStroke(); + + case DrawBasics.IconType.down_threeStroke: + return Icon_down_threeStroke(); + + case DrawBasics.IconType.left_oneStroke: + return Icon_left_oneStroke(); + + case DrawBasics.IconType.left_twoStroke: + return Icon_left_twoStroke(); + + case DrawBasics.IconType.left_threeStroke: + return Icon_left_threeStroke(); + + case DrawBasics.IconType.right_oneStroke: + return Icon_right_oneStroke(); + + case DrawBasics.IconType.right_twoStroke: + return Icon_right_twoStroke(); + + case DrawBasics.IconType.right_threeStroke: + return Icon_right_threeStroke(); + + case DrawBasics.IconType.fist: + return Icon_fist(); + + case DrawBasics.IconType.boxingGlove: + return Icon_boxingGlove(); + + case DrawBasics.IconType.stars5Rate: + return Icon_stars5Rate(); + + case DrawBasics.IconType.stars3: + return Icon_stars3(); + + case DrawBasics.IconType.shootingStar: + return Icon_shootingStar(); + + case DrawBasics.IconType.moonHalf: + return Icon_moonHalf(); + + case DrawBasics.IconType.moonFullPlanet: + return Icon_moonFullPlanet(); + + case DrawBasics.IconType.leftHandRule: + return Icon_leftHandRule(); + + case DrawBasics.IconType.rightHandRule: + return Icon_rightHandRule(); + + case DrawBasics.IconType.megaphone: + return Icon_megaphone(); + + case DrawBasics.IconType.arrowLeft: + return Icon_arrowLeft(); + + case DrawBasics.IconType.arrowRight: + return Icon_arrowRight(); + + case DrawBasics.IconType.arrowUp: + return Icon_arrowUp(); + + case DrawBasics.IconType.arrowDown: + return Icon_arrowDown(); + + case DrawBasics.IconType.healthBox: + return Icon_healthBox(); + + case DrawBasics.IconType.iceIcicle: + return Icon_iceIcicle(); + + case DrawBasics.IconType.pickAxe: + return Icon_pickAxe(); + + case DrawBasics.IconType.audioSpeakerMute: + return Icon_audioSpeakerMute(); + + case DrawBasics.IconType.chestTreasureBox_open: + return Icon_chestTreasureBox_open(); + + case DrawBasics.IconType.doorClosed: + return Icon_doorClosed(); + + default: + Debug.LogError("Icon '" + requestedIcon + "' not implemented."); + return Char_unknown(); + } + + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXL_LinesManager.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXL_LinesManager.cs.meta new file mode 100644 index 0000000..2314a3e --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/DrawXXL_LinesManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 410bf39d2f8b8a543b01a7f40cf65b22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/Editor.meta b/Runtime/DrawDebugLibrary/components/internal utilities/Editor.meta new file mode 100644 index 0000000..1ffe17a --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 43995da0c5deada479d25647709b2854 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint.cs new file mode 100644 index 0000000..cb0590a --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint.cs @@ -0,0 +1,628 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + + [Serializable] + public class InternalDXXL_BezierControlAnchorSubPoint : InternalDXXL_BezierControlSubPoint + { + public enum JunctureType { kinked, aligned, mirrored }; + [SerializeField] public JunctureType junctureType; + public enum SourceOf_directionToHelper { independentFromGameobject, gameobjectsForward, gameobjectsUp, gameobjectsRight, gameobjectsBack, gameobjectsDown, gameobjectsLeft }; + public enum SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers { directionFromPointCenterToThisWeightIsIndependentFromTheRotationOfTheGameobjectThatIsBoundToTheCenterPosition, directionFromPointCenterToThisWeightIsTheForwardDirectionOfTheGameobjectThatIsBoundToTheCenterPosition, directionFromPointCenterToThisWeightIsTheUpDirectionOfTheGameobjectThatIsBoundToTheCenterPosition, directionFromPointCenterToThisWeightIsTheRightDirectionOfTheGameobjectThatIsBoundToTheCenterPosition, directionFromPointCenterToThisWeightIsTheBackDirectionOfTheGameobjectThatIsBoundToTheCenterPosition, directionFromPointCenterToThisWeightIsTheDownDirectionOfTheGameobjectThatIsBoundToTheCenterPosition, directionFromPointCenterToThisWeightIsTheLeftDirectionOfTheGameobjectThatIsBoundToTheCenterPosition }; + [SerializeField] public SourceOf_directionToHelper sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked; //-> is only used when a "boundGameobject" is assigned + + public int controlID_ofCustomHandles_sphere; + public int controlID_ofCustomHandles_forwardCone; + public int controlID_ofCustomHandles_backwardCone; + + public Quaternion rotation_ofRotationHandle_thatIsIndependentFromSplineDir_butDefinedByDrawSpaceOrientation; + public Quaternion rotation_ofRotationHandleDuringRotationDragPhases; + public bool recalc_rotation_ofRotationHandleDuringRotationDragPhases_duringNextOnSceneGUI = true; + public Vector3 directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized = Vector3.forward; + public Vector3 directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized = Vector3.back; + public bool recalc_directionForHandles_forwardCone_duringNextOnSceneGUI = true; + public bool recalc_directionForHandles_backwardCone_duringNextOnSceneGUI = true; + + public override void InitializeValuesThatAreIndependentFromOtherSubPoints(InternalDXXL_BezierControlPointTriplet controlPoint_thisSubPointIsPartOf) + { + base.InitializeValuesThatAreIndependentFromOtherSubPoints(controlPoint_thisSubPointIsPartOf); + sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked = SourceOf_directionToHelper.independentFromGameobject; + } + + public InternalDXXL_BezierControlHelperSubPoint GetForwardHelperPoint() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + return bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets[i_ofContainingControlPoint_insideControlPointsList].forwardHelperPoint; + } + + public InternalDXXL_BezierControlHelperSubPoint GetBackwardHelperPoint() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + return bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets[i_ofContainingControlPoint_insideControlPointsList].backwardHelperPoint; + } + + public override void ResetDirectionSourceToIndependent() + { + sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked = SourceOf_directionToHelper.independentFromGameobject; + } + + public override void TryTransferBoundGameobjectsRotationToAnchorPointsDirection() + { + //-> during no-gameobject-assigned-phases the "sourceOf_direction*'s" are forced to "independentFromGameobject", so here only cases where the assignment changed from one gameobject to another gameobject cause an action inside "connectionComponent_onBoundGameobject.Transfer_aTransformDirection_fromBoundGameobject_toSpline()": + connectionComponent_onBoundGameobject.Transfer_aTransformDirection_fromBoundGameobject_toSpline(); + } + + public void ProcessChanging_sourceOfDirectionToHelper(SourceOf_directionToHelper newSourceOfDirection) + { + if (newSourceOfDirection != sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked) + { + sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked = newSourceOfDirection; + if (newSourceOfDirection != SourceOf_directionToHelper.independentFromGameobject) + { + TryTransfer_newTransformDirection_fromBoundGameobject_toSpline_afterDirectionSourceChange(); + } + } + } + + public void TryTransfer_newTransformDirection_fromBoundGameobject_toSpline_afterDirectionSourceChange() + { + SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + connectionComponent_onBoundGameobject.Transfer_aTransformDirection_fromBoundGameobject_toSpline(); + } + } + + public void SetJunctureType(JunctureType newJunctureType) + { + if (newJunctureType != junctureType) + { + JunctureType oldJunctureType = junctureType; + junctureType = newJunctureType; + + if (oldJunctureType == JunctureType.kinked) + { + TrySwitchBothHelpersTo_isUsed(); + //<- if at least one helperPoint was unused before, then the helperPoints are now already cleanly converted to the new juncture type (meaning: they are now "both used", "parallel", "same absDistance from anchor" and "on differnt sides of the anchor") + //-> if both helperPoints were already used before, then the above didn't have any effect, and the following "forcing to parallel/sameAbsDistance" (inside the "newJuncture == nonKinked"-threads) finishes the conversion. This "forcing to parallel/sameAbsDistance" doesn't harm if the two helpers are already "parallel/sameAbsDistance". + } + + if (newJunctureType == JunctureType.kinked) + { + //this "set isUsed-states" is actually only needed for "change AWAY from kinked", and then during non-kinked-phases the isUsed-state will anyway not change so it will arrive at the next "change TO kinked" still with "all are used". But in order to not having to care what happens in non-kinked-phases and still being sure that kinked-phases always start with "all are used" it is explicitly called here. Besides that it may act as double bottom if the states still get confused somehow. + TrySwitchBothHelpersTo_isUsed(); + } + + if (newJunctureType == JunctureType.aligned) + { + MirrorDirection_from_toForward_to_toBackward(); + Get_controlPointTriplet_thisSubPointIsPartOf().alignedHelperPoints_areOnTheSameSideOfTheAnchor = false; //-> this field is only used by "aligned" anchorPoints + } + + if (newJunctureType == JunctureType.mirrored) + { + MirrorDirection_from_toForward_to_toBackward(); + MirrorDistance_from_toForward_to_toBackward(); + } + } + } + + void TrySwitchBothHelpersTo_isUsed() + { + //the order of the helperPointActivation here only matters for cases where BOTH helperPoints have been unused during the kinked-phase and are now set to used, because a non-kinked juncture-phase follows. The first activated helperPoint then dictates the shape of the second activated helperPoint. Therefore "forward" comes first. + if (false == GetForwardHelperPoint().IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + GetForwardHelperPoint().ChangeUsedState(true, false); + } + + if (false == GetBackwardHelperPoint().IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + GetBackwardHelperPoint().ChangeUsedState(true, false); + } + } + + void MirrorDirection_from_toForward_to_toBackward() + { + GetBackwardHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(-GetForwardHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(), true, null); + } + + void MirrorDistance_from_toForward_to_toBackward() + { + GetBackwardHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(GetForwardHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(), true, null); + } + + public Vector3 Get_aDirection_inUnitsOfGlobalSpace_normalized(bool requestedDirection_isForward_notBackward) + { + if (requestedDirection_isForward_notBackward) + { + return Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + } + else + { + return Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + } + } + + public Vector3 Get_aDirection_inUnitsOfActiveDrawSpace_normalized(bool requestedDirection_isForward_notBackward) + { + if (requestedDirection_isForward_notBackward) + { + return Get_direction_toForward_inUnitsOfActiveDrawSpace_normalized(); + } + else + { + return Get_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(); + } + } + + public Vector3 Get_direction_toForward_inUnitsOfGlobalSpace_normalized() + { + return GetForwardHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + } + + public Vector3 Get_direction_toForward_inUnitsOfActiveDrawSpace_normalized() + { + return GetForwardHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(); + } + + public Vector3 Get_direction_toBackward_inUnitsOfGlobalSpace_normalized() + { + return GetBackwardHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + } + + public Vector3 Get_direction_toBackward_inUnitsOfActiveDrawSpace_normalized() + { + return GetBackwardHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(); + } + + public void Set_aDirection_inUnitsOfGlobalSpace_normalized(bool requestedDirection_isForward_notBackward, Vector3 newDirection_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (requestedDirection_isForward_notBackward) + { + Set_direction_toForward_inUnitsOfGlobalSpace_normalized(newDirection_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + else + { + Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(newDirection_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + public void Set_aDirection_inUnitsOfActiveDrawSpace_normalized(bool requestedDirection_isForward_notBackward, Vector3 newDirection_inUnitsOfActiveDrawSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (requestedDirection_isForward_notBackward) + { + Set_direction_toForward_inUnitsOfActiveDrawSpace_normalized(newDirection_inUnitsOfActiveDrawSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + else + { + Set_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(newDirection_inUnitsOfActiveDrawSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + public override JunctureType GetJunctureType() + { + return junctureType; + } + + public override InternalDXXL_BezierControlHelperSubPoint GetForwardHelper() + { + return GetForwardHelperPoint(); + } + + public override InternalDXXL_BezierControlHelperSubPoint GetBackwardHelper() + { + return GetBackwardHelperPoint(); + } + + public override SourceOf_directionToHelper Get_sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked() + { + return sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked; + } + + public bool CheckIf_boundGameobjectInfluencesRotation() + { + SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + if (junctureType == JunctureType.kinked) + { + if (GetBackwardHelperPoint().isUsed == true) + { + if (GetBackwardHelperPoint().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != SourceOf_directionToHelper.independentFromGameobject) + { + return true; + } + } + + if (GetForwardHelperPoint().isUsed == true) + { + if (GetForwardHelperPoint().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != SourceOf_directionToHelper.independentFromGameobject) + { + return true; + } + } + } + else + { + return (sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked != SourceOf_directionToHelper.independentFromGameobject); + } + } + return false; + } + + public override void Set_direction_toForward_inUnitsOfGlobalSpace_normalized(Vector3 newDirection_toForward_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + GetForwardHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(newDirection_toForward_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void Set_direction_toForward_inUnitsOfActiveDrawSpace_normalized(Vector3 newDirection_toForward_inUnitsOfActiveDrawSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + GetForwardHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(newDirection_toForward_inUnitsOfActiveDrawSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public override void Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(Vector3 newDirection_toBackward_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + GetBackwardHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(newDirection_toBackward_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void Set_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(Vector3 newDirection_toBackward_inUnitsOfActiveDrawSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + GetBackwardHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(newDirection_toBackward_inUnitsOfActiveDrawSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void TryPassOnNew_directionToHelper_unifiedTowardsForwardForCaseNonKinked_inUnitsOfGlobalSpace_normalized_toBoundGameobject(Vector3 newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked != SourceOf_directionToHelper.independentFromGameobject) + { + connectionComponent_onBoundGameobject.Transfer_newDirectionToAHelperPointInUnitsOfGlobalSpaceNormalized_fromSpline_toBoundGameobject(newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized, sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + public Vector3 ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(Vector3 givenDirectionToHelper) + { + if ((junctureType == JunctureType.aligned) && Get_controlPointTriplet_thisSubPointIsPartOf().alignedHelperPoints_areOnTheSameSideOfTheAnchor) + { + return givenDirectionToHelper; + } + else + { + return (-givenDirectionToHelper); + } + } + + public void AddRotation_toForwardDirection(Quaternion rotationIncrement, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector3 new_direction_toForward_inUnitsOfGlobalSpace_normalized = rotationIncrement * Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + Set_direction_toForward_inUnitsOfGlobalSpace_normalized(new_direction_toForward_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void AddRotation_toBackwardDirection(Quaternion rotationIncrement, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector3 new_direction_toBackward_inUnitsOfGlobalSpace_normalized = rotationIncrement * Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(new_direction_toBackward_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public override void SetPos_inUnitsOfGlobalSpace(Vector3 newPos_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector3 offset_fromPrevious_toNewPosition = SetPos_inUnitsOfGlobalSpace_butIgnoreDependentValues_nonRecursively(newPos_inUnitsOfGlobalSpace, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + if (updateDependentValuesOnControlPointTriplet) + { + if ((junctureType == JunctureType.kinked) && (Get_controlPointTriplet_thisSubPointIsPartOf().IsEndPointToVoid_atStartOrEndOfAnUnclosedSpline() == false)) + { + if (GetForwardHelperPoint().isUsed == true) + { + if (GetForwardHelperPoint().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture == SourceOf_directionToHelper.independentFromGameobject) + { + Vector3 newDirection_fromAnchorPoint_toForwardHelper_inUnitsOfGlobalSpace_notNormalized = GetForwardHelperPoint().GetPos_inUnitsOfGlobalSpace() - newPos_inUnitsOfGlobalSpace; + float newAbsDistance_toForwardHelper_inUnitsOfGlobalSpace = newDirection_fromAnchorPoint_toForwardHelper_inUnitsOfGlobalSpace_notNormalized.magnitude; + GetForwardHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistance_toForwardHelper_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (UtilitiesDXXL_Math.ApproximatelyZero(newAbsDistance_toForwardHelper_inUnitsOfGlobalSpace) == false) //-> no change of the direction for zero-distances + { + Vector3 newDirection_fromAnchorPoint_toForwardHelper_inUnitsOfGlobalSpace_normalized = newDirection_fromAnchorPoint_toForwardHelper_inUnitsOfGlobalSpace_notNormalized / newAbsDistance_toForwardHelper_inUnitsOfGlobalSpace; + Set_direction_toForward_inUnitsOfGlobalSpace_normalized(newDirection_fromAnchorPoint_toForwardHelper_inUnitsOfGlobalSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + else + { + GetForwardHelperPoint().AddPosOffset_inUnitsOfGlobalSpace(offset_fromPrevious_toNewPosition, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + if (GetBackwardHelperPoint().isUsed == true) + { + if (GetBackwardHelperPoint().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture == SourceOf_directionToHelper.independentFromGameobject) + { + Vector3 newDirection_fromAnchorPoint_toBackwardHelper_inUnitsOfGlobalSpace_notNormalized = GetBackwardHelperPoint().GetPos_inUnitsOfGlobalSpace() - newPos_inUnitsOfGlobalSpace; + float newAbsDistance_toBackwardHelper_inUnitsOfGlobalSpace = newDirection_fromAnchorPoint_toBackwardHelper_inUnitsOfGlobalSpace_notNormalized.magnitude; + GetBackwardHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistance_toBackwardHelper_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (UtilitiesDXXL_Math.ApproximatelyZero(newAbsDistance_toBackwardHelper_inUnitsOfGlobalSpace) == false) //-> no change of the direction for zero-distances + { + Vector3 newDirection_fromAnchorPoint_toBackwardHelper_inUnitsOfGlobalSpace_normalized = newDirection_fromAnchorPoint_toBackwardHelper_inUnitsOfGlobalSpace_notNormalized / newAbsDistance_toBackwardHelper_inUnitsOfGlobalSpace; + Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(newDirection_fromAnchorPoint_toBackwardHelper_inUnitsOfGlobalSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + else + { + GetBackwardHelperPoint().AddPosOffset_inUnitsOfGlobalSpace(offset_fromPrevious_toNewPosition, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + else + { + //-> the helperPoints have always "isUsed=true" here, since the junctureType is "not kinked". Reminder: endPoints of non-closed splines are always forced to "kinked" and therefore also don't arrive here + GetForwardHelperPoint().AddPosOffset_inUnitsOfGlobalSpace(offset_fromPrevious_toNewPosition, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + GetBackwardHelperPoint().AddPosOffset_inUnitsOfGlobalSpace(offset_fromPrevious_toNewPosition, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + + public InternalDXXL_BezierControlHelperSubPoint GetAHelperPoint(bool requestedHelperPoint_isForward_notBackward) + { + if (requestedHelperPoint_isForward_notBackward) + { + return GetForwardHelperPoint(); + } + else + { + return GetBackwardHelperPoint(); + } + } + + public override InternalDXXL_BezierControlSubPoint GetNextSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return GetForwardHelperPoint(); + } + + public override InternalDXXL_BezierControlSubPoint GetPreviousSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return GetBackwardHelperPoint(); + } + + public override InternalDXXL_BezierControlSubPoint GetNextUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (GetForwardHelperPoint().isUsed) + { + return GetForwardHelperPoint(); + } + else + { + InternalDXXL_BezierControlPointTriplet next_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetNextControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (next_controlPoint != null) + { + if (next_controlPoint.backwardHelperPoint.isUsed) + { + return next_controlPoint.backwardHelperPoint; + } + else + { + return next_controlPoint.anchorPoint; + } + } + else + { + return null; + } + } + } + + public override InternalDXXL_BezierControlSubPoint GetPreviousUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (GetBackwardHelperPoint().isUsed) + { + return GetBackwardHelperPoint(); + } + else + { + InternalDXXL_BezierControlPointTriplet previous_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetPreviousControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (previous_controlPoint != null) + { + if (previous_controlPoint.forwardHelperPoint.isUsed) + { + return previous_controlPoint.forwardHelperPoint; + } + else + { + return previous_controlPoint.anchorPoint; + } + } + else + { + return null; + } + } + } + + public override Vector3 GetDirectionAlongSplineForwardBasedOnNeighborPoints_inUnitsOfGlobalSpace() + { + if (GetForwardHelperPoint().isUsed) + { + return Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + } + else + { + if (GetBackwardHelperPoint().isUsed) + { + return (-Get_direction_toBackward_inUnitsOfGlobalSpace_normalized()); + } + else + { + InternalDXXL_BezierControlSubPoint nextUsedNonSuperimposedSubPointAlongSplineDir = GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + if (nextUsedNonSuperimposedSubPointAlongSplineDir != null) + { + return (nextUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace() - GetPos_inUnitsOfGlobalSpace()); + } + else + { + InternalDXXL_BezierControlSubPoint previousUsedNonSuperimposedSubPointAlongSplineDir = GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + if (previousUsedNonSuperimposedSubPointAlongSplineDir != null) + { + return (GetPos_inUnitsOfGlobalSpace() - previousUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace()); + } + else + { + return bezierSplineDrawer_thisSubPointIsPartOf.Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + } + } + } + } + + public override bool IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid() + { + return false; + } + + public static SourceOf_directionToHelper ConvertDirectionSource_fromWordedVersion_toUsedVersion(SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers wordedVersion_toConvert) + { + switch (wordedVersion_toConvert) + { + case SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsIndependentFromTheRotationOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper.independentFromGameobject; + case SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheForwardDirectionOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper.gameobjectsForward; + case SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheUpDirectionOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper.gameobjectsUp; + case SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheRightDirectionOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper.gameobjectsRight; + case SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheBackDirectionOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper.gameobjectsBack; + case SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheDownDirectionOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper.gameobjectsDown; + case SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheLeftDirectionOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper.gameobjectsLeft; + default: + return SourceOf_directionToHelper.independentFromGameobject; + } + } + + public static SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers ConvertDirectionSource_fromUsedVersion_toWordedVersion(SourceOf_directionToHelper usedVersion_toConvert) + { + switch (usedVersion_toConvert) + { + case SourceOf_directionToHelper.independentFromGameobject: + return SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsIndependentFromTheRotationOfTheGameobjectThatIsBoundToTheCenterPosition; + case SourceOf_directionToHelper.gameobjectsForward: + return SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheForwardDirectionOfTheGameobjectThatIsBoundToTheCenterPosition; + case SourceOf_directionToHelper.gameobjectsUp: + return SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheUpDirectionOfTheGameobjectThatIsBoundToTheCenterPosition; + case SourceOf_directionToHelper.gameobjectsRight: + return SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheRightDirectionOfTheGameobjectThatIsBoundToTheCenterPosition; + case SourceOf_directionToHelper.gameobjectsBack: + return SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheBackDirectionOfTheGameobjectThatIsBoundToTheCenterPosition; + case SourceOf_directionToHelper.gameobjectsDown: + return SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheDownDirectionOfTheGameobjectThatIsBoundToTheCenterPosition; + case SourceOf_directionToHelper.gameobjectsLeft: + return SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheLeftDirectionOfTheGameobjectThatIsBoundToTheCenterPosition; + default: + return SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsIndependentFromTheRotationOfTheGameobjectThatIsBoundToTheCenterPosition; + } + } + + SourceOf_directionToHelper sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked_afterInspectorInput; + JunctureType junctureType_afterInspectorInput; + + public void DrawValuesToInspector(Rect rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings) + { + FillingIsUsedFieldsWithDefaultValues_forInspector(); + + float currentHeightOffset = 0.0f; + DrawPositionLine_forInspector(RecalcCurrentRect_forInspector(rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, currentHeightOffset), new GUIContent("Position", Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector())); + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawBoundGameobjectLine_forInspector(RecalcCurrentRect_forInspector(rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, currentHeightOffset), new GUIContent("Bind to gameobject")); + TryDrawDirectionSourceLine_forInspector(ref currentHeightOffset, rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings); + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawJunctureTypeLine_forInspector(rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, currentHeightOffset); + } + + void FillingIsUsedFieldsWithDefaultValues_forInspector() + { + //This is for cases where the fields are not displayed or greyed out. They are used for an "hasChanged"-check afterwards: + position_inUnitsOfActiveDrawSpace_afterInspectorInput = position_inUnitsOfActiveDrawSpace; + boundGameobject_afterInspectorInput = boundGameobject; + sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked_afterInspectorInput = sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked; + junctureType_afterInspectorInput = junctureType; + } + + void TryDrawDirectionSourceLine_forInspector(ref float currentHeightOffset, Rect rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings) + { +#if UNITY_EDITOR + if (boundGameobject != null) //-> could be improved: there is no check whether the "boundGameobject" is "inactive" or the connection component on it is "disabled". Also "GetPropertyHeightForInspectorList()" may be affected by a fix. + { + if (junctureType != JunctureType.kinked) + { + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked_afterInspectorInput = (SourceOf_directionToHelper)UnityEditor.EditorGUI.EnumPopup(RecalcCurrentRect_forInspector(rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, currentHeightOffset), new GUIContent("Direction Source"), sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked); + } + } +#endif + } + + void DrawJunctureTypeLine_forInspector(Rect rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, float currentHeightOffset) + { +#if UNITY_EDITOR + bool isEndPointToVoid_atStartOrEndOfAnUnclosedSpline = Get_controlPointTriplet_thisSubPointIsPartOf().IsEndPointToVoid_atStartOrEndOfAnUnclosedSpline(); + + string tooltip_forJunctureType; + if (isEndPointToVoid_atStartOrEndOfAnUnclosedSpline) + { + tooltip_forJunctureType = "Not adjustable at end points of non-ring splines."; + } + else + { + tooltip_forJunctureType = ""; + } + + UnityEditor.EditorGUI.BeginDisabledGroup(isEndPointToVoid_atStartOrEndOfAnUnclosedSpline); //note: end points of non-closed splines are always forced to "kinked" so that their helperPoints can be deactivated/activated. + junctureType_afterInspectorInput = (JunctureType)UnityEditor.EditorGUI.EnumPopup(RecalcCurrentRect_forInspector(rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, currentHeightOffset), new GUIContent("Juncture type", tooltip_forJunctureType), junctureType); + UnityEditor.EditorGUI.EndDisabledGroup(); +#endif + } + + public bool TryApplyChangesAfterInspectorInput() + { + //The checks here are more reliable than "EditorGUI.BeginChangeCheck/EndChangeCheck()", which also reports "change" only due to mouse selection, even when the value didn't change yet. + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreExactlyEqual(position_inUnitsOfActiveDrawSpace_afterInspectorInput, position_inUnitsOfActiveDrawSpace) == false) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Position", true, true); + SetPos_inUnitsOfActiveDrawSpace(position_inUnitsOfActiveDrawSpace_afterInspectorInput, true, null); + return true; + } + + if (boundGameobject_afterInspectorInput != boundGameobject) + { + //bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Gameobject Ref", true, true); //not needed here, because it is cared for inside "ProcessNewGameobjectAssignment" + ProcessNewGameobjectAssignment(boundGameobject_afterInspectorInput); + return true; + } + + if (sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked_afterInspectorInput != sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Direction Source", true, true); + ProcessChanging_sourceOfDirectionToHelper(sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked_afterInspectorInput); + return true; + } + + if (junctureType_afterInspectorInput != junctureType) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Juncture", true, true); + SetJunctureType(junctureType_afterInspectorInput); + return true; + } + + return false; + } + + public override float GetPropertyHeightForInspectorList() + { + int linesForDirectionSource = ((boundGameobject != null) && (junctureType != JunctureType.kinked)) ? 1 : 0; + float height_forAllContentLines = (3.0f + linesForDirectionSource) * UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + return height_forAllContentLines; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint.cs.meta new file mode 100644 index 0000000..a2bb49f --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de19abe59c0664449963ce0339d4e666 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint2D.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint2D.cs new file mode 100644 index 0000000..3b42310 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint2D.cs @@ -0,0 +1,620 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + + [Serializable] + public class InternalDXXL_BezierControlAnchorSubPoint2D : InternalDXXL_BezierControlSubPoint2D + { + [SerializeField] public InternalDXXL_BezierControlAnchorSubPoint.JunctureType junctureType; + public enum SourceOf_directionToHelper2D { independentFromGameobject, gameobjectsUp, gameobjectsRight, gameobjectsDown, gameobjectsLeft }; + public enum SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers { directionFromPointCenterToThisWeightIsIndependentFromTheRotationOfTheGameobjectThatIsBoundToTheCenterPosition, directionFromPointCenterToThisWeightIsTheUpDirectionOfTheGameobjectThatIsBoundToTheCenterPosition, directionFromPointCenterToThisWeightIsTheRightDirectionOfTheGameobjectThatIsBoundToTheCenterPosition, directionFromPointCenterToThisWeightIsTheDownDirectionOfTheGameobjectThatIsBoundToTheCenterPosition, directionFromPointCenterToThisWeightIsTheLeftDirectionOfTheGameobjectThatIsBoundToTheCenterPosition }; + [SerializeField] public SourceOf_directionToHelper2D sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked; //-> is only used when a "boundGameobject" is assigned + + public int controlID_ofCustomHandles_sphere; + public int controlID_ofCustomHandles_forwardCone; + public int controlID_ofCustomHandles_backwardCone; + + public int controlID_ofUnityStyleRotationHandle2D; + + public Quaternion rotation_ofRotationHandleDuringRotationDragPhases; + public bool recalc_rotation_ofRotationHandleDuringRotationDragPhases_duringNextOnSceneGUI = true; + public Vector3 directionForHandles_forwardCone_inUnitsOfGlobalSpace_normalized = Vector3.right; + public Vector3 directionForHandles_backwardCone_inUnitsOfGlobalSpace_normalized = Vector3.left; + public bool recalc_directionForHandles_forwardCone_duringNextOnSceneGUI = true; + public bool recalc_directionForHandles_backwardCone_duringNextOnSceneGUI = true; + + public override void InitializeValuesThatAreIndependentFromOtherSubPoints(InternalDXXL_BezierControlPointTriplet2D controlPoint_thisSubPointIsPartOf) + { + base.InitializeValuesThatAreIndependentFromOtherSubPoints(controlPoint_thisSubPointIsPartOf); + sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked = SourceOf_directionToHelper2D.independentFromGameobject; + } + + public InternalDXXL_BezierControlHelperSubPoint2D GetForwardHelperPoint() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + return bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets[i_ofContainingControlPoint_insideControlPointsList].forwardHelperPoint; + } + + public InternalDXXL_BezierControlHelperSubPoint2D GetBackwardHelperPoint() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + return bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets[i_ofContainingControlPoint_insideControlPointsList].backwardHelperPoint; + } + + public override void ResetDirectionSourceToIndependent() + { + sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked = SourceOf_directionToHelper2D.independentFromGameobject; + } + + public override void TryTransferBoundGameobjectsRotationToAnchorPointsDirection() + { + //-> during no-gameobject-assigned-phases the "sourceOf_direction*'s" are forced to "independentFromGameobject", so here only cases where the assignment changed from one gameobject to another gameobject cause an action inside "connectionComponent_onBoundGameobject.Transfer_aTransformDirection_fromBoundGameobject_toSpline()": + connectionComponent_onBoundGameobject.Transfer_aTransformDirection_fromBoundGameobject_toSpline(); + } + + public void ProcessChanging_sourceOfDirectionToHelper(SourceOf_directionToHelper2D newSourceOfDirection) + { + if (newSourceOfDirection != sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked) + { + sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked = newSourceOfDirection; + if (newSourceOfDirection != SourceOf_directionToHelper2D.independentFromGameobject) + { + TryTransfer_newTransformDirection_fromBoundGameobject_toSpline_afterDirectionSourceChange(); + } + } + } + + public void TryTransfer_newTransformDirection_fromBoundGameobject_toSpline_afterDirectionSourceChange() + { + SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + connectionComponent_onBoundGameobject.Transfer_aTransformDirection_fromBoundGameobject_toSpline(); + } + } + + public void SetJunctureType(InternalDXXL_BezierControlAnchorSubPoint.JunctureType newJunctureType) + { + if (newJunctureType != junctureType) + { + InternalDXXL_BezierControlAnchorSubPoint.JunctureType oldJunctureType = junctureType; + junctureType = newJunctureType; + + if (oldJunctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + TrySwitchBothHelpersTo_isUsed(); + //<- if at least one helperPoint was unused before, then the helperPoints are now already cleanly converted to the new juncture type (meaning: they are now "both used", "parallel", "same absDistance from anchor" and "on differnt sides of the anchor") + //-> if both helperPoints were already used before, then the above didn't have any effect, and the following "forcing to parallel/sameAbsDistance" (inside the "newJuncture == nonKinked"-threads) finishes the conversion. This "forcing to parallel/sameAbsDistance" doesn't harm if the two helpers are already "parallel/sameAbsDistance". + } + + if (newJunctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + //this "set isUsed-states" is actually only needed for "change AWAY from kinked", and then during non-kinked-phases the isUsed-state will anyway not change so it will arrive at the next "change TO kinked" still with "all are used". But in order to not having to care what happens in non-kinked-phases and still being sure that kinked-phases always start with "all are used" it is explicitly called here. Besides that it may act as double bottom if the states still get confused somehow. + TrySwitchBothHelpersTo_isUsed(); + } + + if (newJunctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned) + { + MirrorDirection_from_toForward_to_toBackward(); + Get_controlPointTriplet_thisSubPointIsPartOf().alignedHelperPoints_areOnTheSameSideOfTheAnchor = false; //-> this field is only used by "aligned" anchorPoints + } + + if (newJunctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + MirrorDirection_from_toForward_to_toBackward(); + MirrorDistance_from_toForward_to_toBackward(); + } + } + } + + void TrySwitchBothHelpersTo_isUsed() + { + //the order of the helperPointActivation here only matters for cases where BOTH helperPoints have been unused during the kinked-phase and are now set to used, because a non-kinked juncture-phase follows. The first activated helperPoint then dictates the shape of the second activated helperPoint. Therefore "forward" comes first. + if (false == GetForwardHelperPoint().IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + GetForwardHelperPoint().ChangeUsedState(true, false); + } + + if (false == GetBackwardHelperPoint().IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + GetBackwardHelperPoint().ChangeUsedState(true, false); + } + } + + void MirrorDirection_from_toForward_to_toBackward() + { + GetBackwardHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(-GetForwardHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(), true, null); + } + + void MirrorDistance_from_toForward_to_toBackward() + { + GetBackwardHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(GetForwardHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(), true, null); + } + + public Vector2 Get_aDirection_inUnitsOfGlobalSpace_normalized(bool requestedDirection_isForward_notBackward) + { + if (requestedDirection_isForward_notBackward) + { + return Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + } + else + { + return Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + } + } + + public Vector2 Get_aDirection_inUnitsOfActiveDrawSpace_normalized(bool requestedDirection_isForward_notBackward) + { + if (requestedDirection_isForward_notBackward) + { + return Get_direction_toForward_inUnitsOfActiveDrawSpace_normalized(); + } + else + { + return Get_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(); + } + } + + public Vector2 Get_direction_toForward_inUnitsOfGlobalSpace_normalized() + { + return GetForwardHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + } + + public Vector2 Get_direction_toForward_inUnitsOfActiveDrawSpace_normalized() + { + return GetForwardHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(); + } + + public Vector2 Get_direction_toBackward_inUnitsOfGlobalSpace_normalized() + { + return GetBackwardHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + } + + public Vector2 Get_direction_toBackward_inUnitsOfActiveDrawSpace_normalized() + { + return GetBackwardHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(); + } + + public void Set_aDirection_inUnitsOfGlobalSpace_normalized(bool requestedDirection_isForward_notBackward, Vector2 newDirection_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (requestedDirection_isForward_notBackward) + { + Set_direction_toForward_inUnitsOfGlobalSpace_normalized(newDirection_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + else + { + Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(newDirection_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + public void Set_aDirection_inUnitsOfActiveDrawSpace_normalized(bool requestedDirection_isForward_notBackward, Vector2 newDirection_inUnitsOfActiveDrawSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (requestedDirection_isForward_notBackward) + { + Set_direction_toForward_inUnitsOfActiveDrawSpace_normalized(newDirection_inUnitsOfActiveDrawSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + else + { + Set_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(newDirection_inUnitsOfActiveDrawSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + public override InternalDXXL_BezierControlAnchorSubPoint.JunctureType GetJunctureType() + { + return junctureType; + } + + public override InternalDXXL_BezierControlHelperSubPoint2D GetForwardHelper() + { + return GetForwardHelperPoint(); + } + + public override InternalDXXL_BezierControlHelperSubPoint2D GetBackwardHelper() + { + return GetBackwardHelperPoint(); + } + + public override SourceOf_directionToHelper2D Get_sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked() + { + return sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked; + } + + public bool CheckIf_boundGameobjectInfluencesRotation() + { + SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + if (junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + if (GetBackwardHelperPoint().isUsed == true) + { + if (GetBackwardHelperPoint().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != SourceOf_directionToHelper2D.independentFromGameobject) + { + return true; + } + } + + if (GetForwardHelperPoint().isUsed == true) + { + if (GetForwardHelperPoint().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != SourceOf_directionToHelper2D.independentFromGameobject) + { + return true; + } + } + } + else + { + return (sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked != SourceOf_directionToHelper2D.independentFromGameobject); + } + } + return false; + } + + public override void Set_direction_toForward_inUnitsOfGlobalSpace_normalized(Vector2 newDirection_toForward_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + GetForwardHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(newDirection_toForward_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void Set_direction_toForward_inUnitsOfActiveDrawSpace_normalized(Vector2 newDirection_toForward_inUnitsOfActiveDrawSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + GetForwardHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(newDirection_toForward_inUnitsOfActiveDrawSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public override void Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(Vector2 newDirection_toBackward_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + GetBackwardHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(newDirection_toBackward_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void Set_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(Vector2 newDirection_toBackward_inUnitsOfActiveDrawSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + GetBackwardHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(newDirection_toBackward_inUnitsOfActiveDrawSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void TryPassOnNew_directionToHelper_unifiedTowardsForwardForCaseNonKinked_inUnitsOfGlobalSpace_normalized_toBoundGameobject(Vector2 newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked != SourceOf_directionToHelper2D.independentFromGameobject) + { + connectionComponent_onBoundGameobject.Transfer_newDirectionToAHelperPointInUnitsOfGlobalSpaceNormalized_fromSpline_toBoundGameobject(newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized, sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + public Vector2 ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(Vector2 givenDirectionToHelper) + { + if ((junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned) && Get_controlPointTriplet_thisSubPointIsPartOf().alignedHelperPoints_areOnTheSameSideOfTheAnchor) + { + return givenDirectionToHelper; + } + else + { + return (-givenDirectionToHelper); + } + } + + public void AddRotation_toForwardDirection(Quaternion rotationIncrement, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector3 new_direction_toForward_inUnitsOfGlobalSpace_normalized = rotationIncrement * Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + Set_direction_toForward_inUnitsOfGlobalSpace_normalized(new_direction_toForward_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void AddRotation_toBackwardDirection(Quaternion rotationIncrement, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector3 new_direction_toBackward_inUnitsOfGlobalSpace_normalized = rotationIncrement * Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(new_direction_toBackward_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public override void SetPos_inUnitsOfGlobalSpace(Vector2 newPos_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector2 offset_fromPrevious_toNewPosition = SetPos_inUnitsOfGlobalSpace_butIgnoreDependentValues_nonRecursively(newPos_inUnitsOfGlobalSpace, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + if (updateDependentValuesOnControlPointTriplet) + { + if ((junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) && (Get_controlPointTriplet_thisSubPointIsPartOf().IsEndPointToVoid_atStartOrEndOfAnUnclosedSpline() == false)) + { + if (GetForwardHelperPoint().isUsed == true) + { + if (GetForwardHelperPoint().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture == SourceOf_directionToHelper2D.independentFromGameobject) + { + Vector2 newDirection_fromAnchorPoint_toForwardHelper_inUnitsOfGlobalSpace_notNormalized = GetForwardHelperPoint().GetPos_inUnitsOfGlobalSpace() - newPos_inUnitsOfGlobalSpace; + float newAbsDistance_toForwardHelper_inUnitsOfGlobalSpace = newDirection_fromAnchorPoint_toForwardHelper_inUnitsOfGlobalSpace_notNormalized.magnitude; + GetForwardHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistance_toForwardHelper_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (UtilitiesDXXL_Math.ApproximatelyZero(newAbsDistance_toForwardHelper_inUnitsOfGlobalSpace) == false) //-> no change of the direction for zero-distances + { + Vector2 newDirection_fromAnchorPoint_toForwardHelper_inUnitsOfGlobalSpace_normalized = newDirection_fromAnchorPoint_toForwardHelper_inUnitsOfGlobalSpace_notNormalized / newAbsDistance_toForwardHelper_inUnitsOfGlobalSpace; + Set_direction_toForward_inUnitsOfGlobalSpace_normalized(newDirection_fromAnchorPoint_toForwardHelper_inUnitsOfGlobalSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + else + { + GetForwardHelperPoint().AddPosOffset_inUnitsOfGlobalSpace(offset_fromPrevious_toNewPosition, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + if (GetBackwardHelperPoint().isUsed == true) + { + if (GetBackwardHelperPoint().sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture == SourceOf_directionToHelper2D.independentFromGameobject) + { + Vector2 newDirection_fromAnchorPoint_toBackwardHelper_inUnitsOfGlobalSpace_notNormalized = GetBackwardHelperPoint().GetPos_inUnitsOfGlobalSpace() - newPos_inUnitsOfGlobalSpace; + float newAbsDistance_toBackwardHelper_inUnitsOfGlobalSpace = newDirection_fromAnchorPoint_toBackwardHelper_inUnitsOfGlobalSpace_notNormalized.magnitude; + GetBackwardHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistance_toBackwardHelper_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (UtilitiesDXXL_Math.ApproximatelyZero(newAbsDistance_toBackwardHelper_inUnitsOfGlobalSpace) == false) //-> no change of the direction for zero-distances + { + Vector2 newDirection_fromAnchorPoint_toBackwardHelper_inUnitsOfGlobalSpace_normalized = newDirection_fromAnchorPoint_toBackwardHelper_inUnitsOfGlobalSpace_notNormalized / newAbsDistance_toBackwardHelper_inUnitsOfGlobalSpace; + Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(newDirection_fromAnchorPoint_toBackwardHelper_inUnitsOfGlobalSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + else + { + GetBackwardHelperPoint().AddPosOffset_inUnitsOfGlobalSpace(offset_fromPrevious_toNewPosition, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + else + { + //-> the helperPoints have always "isUsed=true" here, since the junctureType is "not kinked". Reminder: endPoints of non-closed splines are always forced to "kinked" and therefore also don't arrive here + GetForwardHelperPoint().AddPosOffset_inUnitsOfGlobalSpace(offset_fromPrevious_toNewPosition, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + GetBackwardHelperPoint().AddPosOffset_inUnitsOfGlobalSpace(offset_fromPrevious_toNewPosition, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + + public InternalDXXL_BezierControlHelperSubPoint2D GetAHelperPoint(bool requestedHelperPoint_isForward_notBackward) + { + if (requestedHelperPoint_isForward_notBackward) + { + return GetForwardHelperPoint(); + } + else + { + return GetBackwardHelperPoint(); + } + } + + public override InternalDXXL_BezierControlSubPoint2D GetNextSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return GetForwardHelperPoint(); + } + + public override InternalDXXL_BezierControlSubPoint2D GetPreviousSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return GetBackwardHelperPoint(); + } + + public override InternalDXXL_BezierControlSubPoint2D GetNextUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (GetForwardHelperPoint().isUsed) + { + return GetForwardHelperPoint(); + } + else + { + InternalDXXL_BezierControlPointTriplet2D next_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetNextControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (next_controlPoint != null) + { + if (next_controlPoint.backwardHelperPoint.isUsed) + { + return next_controlPoint.backwardHelperPoint; + } + else + { + return next_controlPoint.anchorPoint; + } + } + else + { + return null; + } + } + } + + public override InternalDXXL_BezierControlSubPoint2D GetPreviousUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (GetBackwardHelperPoint().isUsed) + { + return GetBackwardHelperPoint(); + } + else + { + InternalDXXL_BezierControlPointTriplet2D previous_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetPreviousControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (previous_controlPoint != null) + { + if (previous_controlPoint.forwardHelperPoint.isUsed) + { + return previous_controlPoint.forwardHelperPoint; + } + else + { + return previous_controlPoint.anchorPoint; + } + } + else + { + return null; + } + } + } + + public override Vector2 GetDirectionAlongSplineForwardBasedOnNeighborPoints_inUnitsOfGlobalSpace() + { + if (GetForwardHelperPoint().isUsed) + { + return Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + } + else + { + if (GetBackwardHelperPoint().isUsed) + { + return (-Get_direction_toBackward_inUnitsOfGlobalSpace_normalized()); + } + else + { + InternalDXXL_BezierControlSubPoint2D nextUsedNonSuperimposedSubPointAlongSplineDir = GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + if (nextUsedNonSuperimposedSubPointAlongSplineDir != null) + { + return (nextUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace() - GetPos_inUnitsOfGlobalSpace()); + } + else + { + InternalDXXL_BezierControlSubPoint2D previousUsedNonSuperimposedSubPointAlongSplineDir = GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + if (previousUsedNonSuperimposedSubPointAlongSplineDir != null) + { + return (GetPos_inUnitsOfGlobalSpace() - previousUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace()); + } + else + { + return bezierSplineDrawer_thisSubPointIsPartOf.Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + } + } + } + } + + public override bool IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid() + { + return false; + } + + public static SourceOf_directionToHelper2D ConvertDirectionSource_fromWordedVersion_toUsedVersion(SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers wordedVersion_toConvert) + { + switch (wordedVersion_toConvert) + { + case SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsIndependentFromTheRotationOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper2D.independentFromGameobject; + case SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheUpDirectionOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper2D.gameobjectsUp; + case SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheRightDirectionOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper2D.gameobjectsRight; + case SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheDownDirectionOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper2D.gameobjectsDown; + case SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheLeftDirectionOfTheGameobjectThatIsBoundToTheCenterPosition: + return SourceOf_directionToHelper2D.gameobjectsLeft; + default: + return SourceOf_directionToHelper2D.independentFromGameobject; + } + } + + public static SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers ConvertDirectionSource_fromUsedVersion_toWordedVersion(SourceOf_directionToHelper2D usedVersion_toConvert) + { + switch (usedVersion_toConvert) + { + case SourceOf_directionToHelper2D.independentFromGameobject: + return SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsIndependentFromTheRotationOfTheGameobjectThatIsBoundToTheCenterPosition; + case SourceOf_directionToHelper2D.gameobjectsUp: + return SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheUpDirectionOfTheGameobjectThatIsBoundToTheCenterPosition; + case SourceOf_directionToHelper2D.gameobjectsRight: + return SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheRightDirectionOfTheGameobjectThatIsBoundToTheCenterPosition; + case SourceOf_directionToHelper2D.gameobjectsDown: + return SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheDownDirectionOfTheGameobjectThatIsBoundToTheCenterPosition; + case SourceOf_directionToHelper2D.gameobjectsLeft: + return SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsTheLeftDirectionOfTheGameobjectThatIsBoundToTheCenterPosition; + default: + return SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers.directionFromPointCenterToThisWeightIsIndependentFromTheRotationOfTheGameobjectThatIsBoundToTheCenterPosition; + } + } + + SourceOf_directionToHelper2D sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked_afterInspectorInput; + InternalDXXL_BezierControlAnchorSubPoint.JunctureType junctureType_afterInspectorInput; + + public void DrawValuesToInspector(Rect rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings) + { + FillingIsUsedFieldsWithDefaultValues_forInspector(); + + float currentHeightOffset = 0.0f; + DrawPositionLine_forInspector(RecalcCurrentRect_forInspector(rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, currentHeightOffset), new GUIContent("Position", Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector())); + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawBoundGameobjectLine_forInspector(RecalcCurrentRect_forInspector(rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, currentHeightOffset), new GUIContent("Bind to gameobject")); + TryDrawDirectionSourceLine_forInspector(ref currentHeightOffset, rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings); + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawJunctureTypeLine_forInspector(rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, currentHeightOffset); + } + + void FillingIsUsedFieldsWithDefaultValues_forInspector() + { + //This is for cases where the fields are not displayed or greyed out. They are used for an "hasChanged"-check afterwards: + position_inUnitsOfActiveDrawSpace_afterInspectorInput = position_inUnitsOfActiveDrawSpace; + boundGameobject_afterInspectorInput = boundGameobject; + sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked_afterInspectorInput = sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked; + junctureType_afterInspectorInput = junctureType; + } + + void TryDrawDirectionSourceLine_forInspector(ref float currentHeightOffset, Rect rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings) + { +#if UNITY_EDITOR + if (boundGameobject != null) //-> could be improved: there is no check whether the "boundGameobject" is "inactive" or the connection component on it is "disabled". Also "GetPropertyHeightForInspectorList()" may be affected by a fix. + { + if (junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked_afterInspectorInput = (SourceOf_directionToHelper2D)UnityEditor.EditorGUI.EnumPopup(RecalcCurrentRect_forInspector(rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, currentHeightOffset), new GUIContent("Direction Source"), sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked); + } + } +#endif + } + + void DrawJunctureTypeLine_forInspector(Rect rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, float currentHeightOffset) + { +#if UNITY_EDITOR + bool isEndPointToVoid_atStartOrEndOfAnUnclosedSpline = Get_controlPointTriplet_thisSubPointIsPartOf().IsEndPointToVoid_atStartOrEndOfAnUnclosedSpline(); + + string tooltip_forJunctureType; + if (isEndPointToVoid_atStartOrEndOfAnUnclosedSpline) + { + tooltip_forJunctureType = "Not adjustable at end points of non-ring splines."; + } + else + { + tooltip_forJunctureType = ""; + } + + UnityEditor.EditorGUI.BeginDisabledGroup(isEndPointToVoid_atStartOrEndOfAnUnclosedSpline); //note: end points of non-closed splines are always forced to "kinked" so that their helperPoints can be deactivated/activated. + junctureType_afterInspectorInput = (InternalDXXL_BezierControlAnchorSubPoint.JunctureType)UnityEditor.EditorGUI.EnumPopup(RecalcCurrentRect_forInspector(rectForOnlyTheContentLines_alreadyClearedFromAnyColorBoxPaddings, currentHeightOffset), new GUIContent("Juncture type", tooltip_forJunctureType), junctureType); + UnityEditor.EditorGUI.EndDisabledGroup(); +#endif + } + + public bool TryApplyChangesAfterInspectorInput() + { + //The checks here are more reliable than "EditorGUI.BeginChangeCheck/EndChangeCheck()", which also reports "change" only due to mouse selection, even when the value didn't change yet. + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreExactlyEqual(position_inUnitsOfActiveDrawSpace_afterInspectorInput, position_inUnitsOfActiveDrawSpace) == false) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Position", true, true); + SetPos_inUnitsOfActiveDrawSpace(position_inUnitsOfActiveDrawSpace_afterInspectorInput, true, null); + return true; + } + + if (boundGameobject_afterInspectorInput != boundGameobject) + { + //bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Gameobject Ref", true, true); //not needed here, because it is cared for inside "ProcessNewGameobjectAssignment" + ProcessNewGameobjectAssignment(boundGameobject_afterInspectorInput); + return true; + } + + if (sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked_afterInspectorInput != sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Direction Source", true, true); + ProcessChanging_sourceOfDirectionToHelper(sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked_afterInspectorInput); + return true; + } + + if (junctureType_afterInspectorInput != junctureType) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Juncture", true, true); + SetJunctureType(junctureType_afterInspectorInput); + return true; + } + + return false; + } + + public override float GetPropertyHeightForInspectorList() + { + int linesForDirectionSource = ((boundGameobject != null) && (junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked)) ? 1 : 0; + float height_forAllContentLines = (3.0f + linesForDirectionSource) * UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + return height_forAllContentLines; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint2D.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint2D.cs.meta new file mode 100644 index 0000000..324c20c --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlAnchorSubPoint2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 96c4eb1b6ea5e484283989bd614eeefb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint.cs new file mode 100644 index 0000000..5f6bec5 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint.cs @@ -0,0 +1,1008 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + + [Serializable] + public class InternalDXXL_BezierControlHelperSubPoint : InternalDXXL_BezierControlSubPoint + { + public static float alpha_ofInspectorBackgroundColor_highlighted = 1.0f; + public static float alpha_ofInspectorBackgroundColor_nonHighlighted = 0.5f; + + [SerializeField] public bool isOutfoldedInInspector = false; + [SerializeField] Vector3 direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized; + [SerializeField] Vector3 direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized; + [SerializeField] public InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture; //-> is only used when a "boundGameobject" is assigned at the mountingAnchor + [SerializeField] public float absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace; + [SerializeField] float absDistanceToAnchorPoint_inUnitsOfGlobalSpace; + + public bool isForward_notBackward; + + public int controlID_ofCustomHandles_sphere; + public int controlID_ofCustomHandles_coneAlongLineWithAnchor; + public int controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper; + public int controlID_ofCustomHandles_cylinderAlongLineWithAnchor; + public int controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper; + + public Vector3 directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = Vector3.forward; + public Vector3 directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = Vector3.back; + public InternalDXXL_Plane camPlane_inclinedIntoHandlesDir_inUnitsOfGlobalSpace = new InternalDXXL_Plane(); + public bool recalc_directionForHandles_alongLineWithMountingAnchor_duringNextOnSceneGUI = true; + public bool recalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_duringNextOnSceneGUI = true; + public bool recalc_handlesPlanesThatShouldntBeRecalcedDuringDrag_duringNextOnSceneGUI = true; + [SerializeField] Vector3 positionOfAnchor_inMomentOfDeactivationOfThisHelper_inUnitsOfGlobalSpace; + + public override void InitializeValuesThatAreIndependentFromOtherSubPoints(InternalDXXL_BezierControlPointTriplet controlPoint_thisSubPointIsPartOf) + { + base.InitializeValuesThatAreIndependentFromOtherSubPoints(controlPoint_thisSubPointIsPartOf); + sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture = InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject; + } + + public InternalDXXL_BezierControlAnchorSubPoint GetMountingAnchorPoint() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + return bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets[i_ofContainingControlPoint_insideControlPointsList].anchorPoint; + } + + public InternalDXXL_BezierControlHelperSubPoint GetOppositeHelperPoint() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + return bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets[i_ofContainingControlPoint_insideControlPointsList].GetAHelperPoint(!isForward_notBackward); + } + + public void ChangeUsedState(bool newStateOf_isUsed, bool stateChangeComesFromUserInputViaInspectorsIsUsedBoolCheckboxOnKinkedTriplet) + { + if (newStateOf_isUsed != isUsed) + { + isUsed = newStateOf_isUsed; + if (newStateOf_isUsed == true) + { + ProcessActivation(stateChangeComesFromUserInputViaInspectorsIsUsedBoolCheckboxOnKinkedTriplet); + } + else + { + ProcessDeactivation(); + } + } + } + + void ProcessActivation(bool stateChangeComesFromUserInputViaInspectorsIsUsedBoolCheckboxOnKinkedTriplet) + { + if (stateChangeComesFromUserInputViaInspectorsIsUsedBoolCheckboxOnKinkedTriplet) + { + //-> "junctureType == kinked" is guaranteed here + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(positionOfAnchor_inMomentOfDeactivationOfThisHelper_inUnitsOfGlobalSpace, GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace())) + { + SetInitialPos_viaRestoringValuesFromPreDeactivation(); + } + else + { + SetInitialPos_withoutKnowledgeOfPreDeactivationPos(); + } + } + else + { + SetInitialPos_withoutKnowledgeOfPreDeactivationPos(); + } + } + + void ProcessDeactivation() + { + positionOfAnchor_inMomentOfDeactivationOfThisHelper_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace(); + } + + void SetInitialPos_viaRestoringValuesFromPreDeactivation() + { + //This restoration allows: + //-> ticking the used state in the inspector testwise off an on without losing the values + //-> special moves like temporarily decactivating a helperPoint, so that only the other helperPoint is affected by the rotationHandle of the anchorPoint. + + //The only case where this happens is: "junctureType=kinked", and the helper has been manually deactivated during this "kinked"-phase + //The condition that the mountingAnchor shouldn't have changed it's position since the deactivation has this effect: + //-> If the spline shape changed a lot during the inactive-phase then the reactivation could cause irritation because the spline shape can then immediately be unintendedly warped and stretched across the whole scene. + //-> As a side effect the re-activated helper forgets his former state also if the helper only changed slightly. It would actually be a welcomed functionality that in such cases the helper would restore its former position, but it is sacrified for for the prevention of the aforementioned irration. + + this.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + GetMountingAnchorPoint().SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (GetMountingAnchorPoint().boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled && (sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject)) + { + //restoring the position based on the distance and direction: + float newAbsDistance_inUnitsOfGlobalSpace; + if (this.boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + //the "thisHelper.boundGameobject" may have changed it's position during the unused-phase. But since "mountingAnchor.boundGameobject" dictates a "direction" only the DISTANCE from "thisHelper.boundGameobject" is used, not the POSITION: + newAbsDistance_inUnitsOfGlobalSpace = (GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() - this.GetPos_inUnitsOfGlobalSpace()).magnitude; + } + else + { + newAbsDistance_inUnitsOfGlobalSpace = absDistanceToAnchorPoint_inUnitsOfGlobalSpace; + } + + Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistance_inUnitsOfGlobalSpace, true, this.boundGameobject); //-> "this.boundGameobject" can also be "null" here, which does not harm + GetMountingAnchorPoint().connectionComponent_onBoundGameobject.Transfer_aTransformDirection_fromBoundGameobject_toSpline(); + } + else + { + //restoring the direction and distance based on the position: + if (this.boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + connectionComponent_onBoundGameobject.Transfer_position_fromBoundGameobject_toSpline(); + } + else + { + //-> this doesn't change the position, but refreshes the dependent values ("direction" and "distance"): + SetPos_inUnitsOfGlobalSpace(GetPos_inUnitsOfGlobalSpace(), true, null); //-> this is actually not be necessary here, because the direction and distance cannot be different from what they were onSetUnused, since the anchorPos stayed the same. It acts here as double bottom if somehow the states got confused. + } + } + } + + void SetInitialPos_withoutKnowledgeOfPreDeactivationPos() + { + Vector3 initialDirection_inUnitsOfGlobalSpace_normalized; + float initialAbsDistance_inUnitsOfGlobalSpace; + if (GetOppositeHelperPoint().isUsed == true) + { + initialDirection_inUnitsOfGlobalSpace_normalized = (-GetOppositeHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized()); + if ((UtilitiesDXXL_Math.ApproximatelyZero(GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace()) == false) || (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored)) + { + initialAbsDistance_inUnitsOfGlobalSpace = GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + } + else + { + initialAbsDistance_inUnitsOfGlobalSpace = Get_initialAbsDistance_inUnitsOfGlobalSpace_fromGlobalSettingsForNewlyCreatedPoints(); + } + } + else + { + initialDirection_inUnitsOfGlobalSpace_normalized = Get_initialDirection_inUnitsOfGlobalSpace_normalized_caseNoInformationFromOppositeHelper(); + initialAbsDistance_inUnitsOfGlobalSpace = Get_initialAbsDistance_inUnitsOfGlobalSpace_fromGlobalSettingsForNewlyCreatedPoints(); + } + SetInitialPos(initialDirection_inUnitsOfGlobalSpace_normalized, initialAbsDistance_inUnitsOfGlobalSpace); + } + + void SetInitialPos(Vector3 initialDirection_inUnitsOfGlobalSpace_normalized, float initialAbsDistance_inUnitsOfGlobalSpace) + { + Vector3 initialPosition_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() + initialDirection_inUnitsOfGlobalSpace_normalized * initialAbsDistance_inUnitsOfGlobalSpace; + SetPos_inUnitsOfGlobalSpace(initialPosition_inUnitsOfGlobalSpace, true, null); + } + + float Get_initialAbsDistance_inUnitsOfGlobalSpace_fromGlobalSettingsForNewlyCreatedPoints() + { + if (isForward_notBackward) + { + return bezierSplineDrawer_thisSubPointIsPartOf.TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(bezierSplineDrawer_thisSubPointIsPartOf.forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace); + } + else + { + return bezierSplineDrawer_thisSubPointIsPartOf.TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(bezierSplineDrawer_thisSubPointIsPartOf.backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace); + } + } + + Vector3 Get_initialDirection_inUnitsOfGlobalSpace_normalized_caseNoInformationFromOppositeHelper() + { + InternalDXXL_BezierControlSubPoint nextUsedNonSuperimposed_subPoint; + InternalDXXL_BezierControlSubPoint previousUsedNonSuperimposed_subPoint; + if (isForward_notBackward) + { + nextUsedNonSuperimposed_subPoint = GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + previousUsedNonSuperimposed_subPoint = GetOppositeHelperPoint().GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + } + else + { + nextUsedNonSuperimposed_subPoint = GetOppositeHelperPoint().GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + previousUsedNonSuperimposed_subPoint = GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + } + + if (nextUsedNonSuperimposed_subPoint == null) + { + return GetForwardRespBackward_ofActiveDrawSpace_normalized(); + } + else + { + if (previousUsedNonSuperimposed_subPoint == null) + { + return GetForwardRespBackward_ofActiveDrawSpace_normalized(); + } + else + { + if (Get_controlPointTriplet_thisSubPointIsPartOf().IsPartOfThisTriplet(nextUsedNonSuperimposed_subPoint)) + { + return GetForwardRespBackward_ofActiveDrawSpace_normalized(); + } + else + { + if (Get_controlPointTriplet_thisSubPointIsPartOf().IsPartOfThisTriplet(previousUsedNonSuperimposed_subPoint)) + { + return GetForwardRespBackward_ofActiveDrawSpace_normalized(); + } + else + { + Vector3 previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace = nextUsedNonSuperimposed_subPoint.GetPos_inUnitsOfGlobalSpace() - previousUsedNonSuperimposed_subPoint.GetPos_inUnitsOfGlobalSpace(); + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace) < 0.0001f) + { + return GetForwardRespBackward_ofActiveDrawSpace_normalized(); + } + else + { + Vector3 previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace_normalized)) + { + return GetForwardRespBackward_ofActiveDrawSpace_normalized(); + } + else + { + return TryFlipVectorForBackwardHelpers(previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace_normalized); + } + } + } + } + } + } + } + + Vector3 GetForwardRespBackward_ofActiveDrawSpace_normalized() + { + return TryFlipVectorForBackwardHelpers(bezierSplineDrawer_thisSubPointIsPartOf.Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized()); + } + + Vector3 TryFlipVectorForBackwardHelpers(Vector3 vectorToTryFlip) + { + if (isForward_notBackward) + { + return vectorToTryFlip; + } + else + { + return (-vectorToTryFlip); + } + } + + public override void ResetDirectionSourceToIndependent() + { + sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture = InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject; + } + + public void ProcessChanging_sourceOfDirectionFromAnchor(InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper newSourceOfDirection) + { + if (newSourceOfDirection != sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture) + { + sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture = newSourceOfDirection; + if (newSourceOfDirection != InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject) + { + GetMountingAnchorPoint().TryTransfer_newTransformDirection_fromBoundGameobject_toSpline_afterDirectionSourceChange(); + } + } + } + + public float Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace() + { + return absDistanceToAnchorPoint_inUnitsOfGlobalSpace; + } + + public float Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace() + { + return absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace; + } + + public void Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(float new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (UtilitiesDXXL_Math.FloatIsValid(new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace)) + { + new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace = Mathf.Max(0.0f, new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace); + absDistanceToAnchorPoint_inUnitsOfGlobalSpace = new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace; + absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace = bezierSplineDrawer_thisSubPointIsPartOf.TransformLength_fromGlobalSpace_toUnitsOfActiveDrawSpace(new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace); + TryUpdateDependentValues_after_onSetAbsDistanceToAnchorPointInUnitsOfGlobalSpace(new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + void TryUpdateDependentValues_after_onSetAbsDistanceToAnchorPointInUnitsOfGlobalSpace(float new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (updateDependentValuesOnControlPointTriplet) + { + Vector3 vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace = Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized() * new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace; + Vector3 newPosition_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() + vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace; + SetPos_inUnitsOfGlobalSpace(newPosition_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetOppositeHelperPoint().isUsed) + { + if (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + GetOppositeHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + Vector3 newPosition_ofOppositeHelperPoint_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() - vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace; + GetOppositeHelperPoint().SetPos_inUnitsOfGlobalSpace(newPosition_ofOppositeHelperPoint_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + } + + public void Set_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(float new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (UtilitiesDXXL_Math.FloatIsValid(new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace)) + { + new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace = Mathf.Max(0.0f, new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace); + absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace = new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace; + absDistanceToAnchorPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_thisSubPointIsPartOf.TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace); + TryUpdateDependentValues_after_onSetAbsDistanceToAnchorPointInUnitsOfActiveDrawSpace(new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + void TryUpdateDependentValues_after_onSetAbsDistanceToAnchorPointInUnitsOfActiveDrawSpace(float new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (updateDependentValuesOnControlPointTriplet) + { + Vector3 vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfActiveDrawSpace = Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized() * new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace; + Vector3 newPosition_inUnitsOfActiveDrawSpace = GetMountingAnchorPoint().GetPos_inUnitsOfActiveDrawSpace() + vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfActiveDrawSpace; + SetPos_inUnitsOfActiveDrawSpace(newPosition_inUnitsOfActiveDrawSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetOppositeHelperPoint().isUsed) + { + if (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + GetOppositeHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + Vector3 newPosition_ofOppositeHelperPoint_inUnitsOfActiveDrawSpace = GetMountingAnchorPoint().GetPos_inUnitsOfActiveDrawSpace() - vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfActiveDrawSpace; + GetOppositeHelperPoint().SetPos_inUnitsOfActiveDrawSpace(newPosition_ofOppositeHelperPoint_inUnitsOfActiveDrawSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + } + + public override void SetPos_inUnitsOfGlobalSpace(Vector3 newPos_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + SetPos_inUnitsOfGlobalSpace_butIgnoreDependentValues_nonRecursively(newPos_inUnitsOfGlobalSpace, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (updateDependentValuesOnControlPointTriplet) + { + Vector3 newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_notNormalized = newPos_inUnitsOfGlobalSpace - GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace(); + float newAbsDistance_toAnchorPoint_inUnitsOfGlobalSpace = newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_notNormalized.magnitude; + Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistance_toAnchorPoint_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + Vector3 newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_normalized; + if (UtilitiesDXXL_Math.ApproximatelyZero(newAbsDistance_toAnchorPoint_inUnitsOfGlobalSpace)) + { + //-> no change of the direction: + newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_normalized = GetMountingAnchorPoint().Get_aDirection_inUnitsOfGlobalSpace_normalized(isForward_notBackward); + } + else + { + newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_normalized = newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_notNormalized / newAbsDistance_toAnchorPoint_inUnitsOfGlobalSpace; + } + Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetOppositeHelperPoint().isUsed) + { + if (GetMountingAnchorPoint().junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + Vector3 newDirection_fromAnchorPoint_toOtherHelperPoint_inUnitsOfGlobalSpace_normalized = GetMountingAnchorPoint().ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_normalized); + GetOppositeHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(newDirection_fromAnchorPoint_toOtherHelperPoint_inUnitsOfGlobalSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + GetOppositeHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistance_toAnchorPoint_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + Vector3 newPos_ofOppositeHelperPoint_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() + GetOppositeHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized() * GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + GetOppositeHelperPoint().SetPos_inUnitsOfGlobalSpace(newPos_ofOppositeHelperPoint_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + } + + public Vector3 Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized() + { + return direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized; + } + + public Vector3 Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized() + { + return direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized; + } + + public void Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(Vector3 newDirection_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Set_direction_toThisHelper_fromAnchor_inBothSpaces_butDefinedViaGlobalSpace_normalized(newDirection_inUnitsOfGlobalSpace_normalized); + TryPassOnNew_direction_toThisHelper_inUnitsOfGlobalSpace_normalized_toBoundGameobject(newDirection_inUnitsOfGlobalSpace_normalized, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + TryUpdateDependentValues_after_onSetDirectionToThisHelperInUnitsOfGlobalSpace(newDirection_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + void Set_direction_toThisHelper_fromAnchor_inBothSpaces_butDefinedViaGlobalSpace_normalized(Vector3 newDirection_inUnitsOfGlobalSpace_normalized) + { + direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized = newDirection_inUnitsOfGlobalSpace_normalized; + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized = bezierSplineDrawer_thisSubPointIsPartOf.TransformDirection_fromGlobalSpace_toUnitsOfActiveDrawSpace(newDirection_inUnitsOfGlobalSpace_normalized); + } + + void TryUpdateDependentValues_after_onSetDirectionToThisHelperInUnitsOfGlobalSpace(Vector3 newDirection_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (updateDependentValuesOnControlPointTriplet) + { + Vector3 newPos_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() + newDirection_inUnitsOfGlobalSpace_normalized * Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + SetPos_inUnitsOfGlobalSpace(newPos_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetOppositeHelperPoint().isUsed) + { + if (GetMountingAnchorPoint().junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + Vector3 newDirection_toOppositeHelper_inUnitsOfGlobalSpace_normalized = ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(newDirection_inUnitsOfGlobalSpace_normalized); + GetOppositeHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(newDirection_toOppositeHelper_inUnitsOfGlobalSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + Vector3 newPosOfOppositeHelper_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() + newDirection_toOppositeHelper_inUnitsOfGlobalSpace_normalized * GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + GetOppositeHelperPoint().SetPos_inUnitsOfGlobalSpace(newPosOfOppositeHelper_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + } + + public void Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(Vector3 newDirection_inUnitsOfActiveDrawSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Set_direction_toThisHelper_fromAnchor_inBothSpaces_butDefinedViaActiveDrawSpace_normalized(newDirection_inUnitsOfActiveDrawSpace_normalized); + //"direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized" has been set right before inside "Set_direction_toThisHelper_fromAnchor_inBothSpaces_butDefinedViaActiveDrawSpace_normalized()" and therefore is guaranteed available here + TryPassOnNew_direction_toThisHelper_inUnitsOfGlobalSpace_normalized_toBoundGameobject(direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + TryUpdateDependentValues_after_onSetDirectionToThisHelperInUnitsOfActiveDrawSpace(newDirection_inUnitsOfActiveDrawSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + void Set_direction_toThisHelper_fromAnchor_inBothSpaces_butDefinedViaActiveDrawSpace_normalized(Vector3 newDirection_inUnitsOfActiveDrawSpace_normalized) + { + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized = newDirection_inUnitsOfActiveDrawSpace_normalized; + direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_thisSubPointIsPartOf.TransformDirection_fromUnitsOfActiveDrawSpace_toGlobalSpace(newDirection_inUnitsOfActiveDrawSpace_normalized); + } + + public void TryUpdateDependentValues_after_onSetDirectionToThisHelperInUnitsOfActiveDrawSpace(Vector3 newDirection_inUnitsOfActiveDrawSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (updateDependentValuesOnControlPointTriplet) + { + Vector3 newPos_inUnitsOfActiveDrawSpace = GetMountingAnchorPoint().GetPos_inUnitsOfActiveDrawSpace() + newDirection_inUnitsOfActiveDrawSpace_normalized * Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + SetPos_inUnitsOfActiveDrawSpace(newPos_inUnitsOfActiveDrawSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetOppositeHelperPoint().isUsed) + { + if (GetMountingAnchorPoint().junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + Vector3 newDirection_toOppositeHelper_inUnitsOfActiveDrawSpace_normalized = ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(newDirection_inUnitsOfActiveDrawSpace_normalized); + GetOppositeHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(newDirection_toOppositeHelper_inUnitsOfActiveDrawSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + Vector3 newPosOfOppositeHelper_inUnitsOfActiveDrawSpace = GetMountingAnchorPoint().GetPos_inUnitsOfActiveDrawSpace() + newDirection_toOppositeHelper_inUnitsOfActiveDrawSpace_normalized * GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + GetOppositeHelperPoint().SetPos_inUnitsOfActiveDrawSpace(newPosOfOppositeHelper_inUnitsOfActiveDrawSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + } + + public void TryPassOnNew_direction_toThisHelper_inUnitsOfGlobalSpace_normalized_toBoundGameobject(Vector3 newDirection_inUnitsOfGlobalSpace_normalized, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + GetMountingAnchorPoint().SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (GetMountingAnchorPoint().boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + if (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + if (sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject) + { + GetMountingAnchorPoint().connectionComponent_onBoundGameobject.Transfer_newDirectionToAHelperPointInUnitsOfGlobalSpaceNormalized_fromSpline_toBoundGameobject(newDirection_inUnitsOfGlobalSpace_normalized, sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + else + { + Vector3 newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized = newDirection_inUnitsOfGlobalSpace_normalized; + if (isForward_notBackward == false) + { + newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized = ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized); + } + GetMountingAnchorPoint().TryPassOnNew_directionToHelper_unifiedTowardsForwardForCaseNonKinked_inUnitsOfGlobalSpace_normalized_toBoundGameobject(newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + + public Vector3 ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(Vector3 givenDirectionToHelper) + { + return GetMountingAnchorPoint().ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(givenDirectionToHelper); + } + + public override InternalDXXL_BezierControlSubPoint GetNextSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (isForward_notBackward) + { + InternalDXXL_BezierControlPointTriplet next_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetNextControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (next_controlPoint != null) + { + return next_controlPoint.backwardHelperPoint; + } + else + { + return null; + } + } + else + { + return GetMountingAnchorPoint(); + } + } + + public override InternalDXXL_BezierControlSubPoint GetPreviousSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (isForward_notBackward) + { + return GetMountingAnchorPoint(); + } + else + { + InternalDXXL_BezierControlPointTriplet previous_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetPreviousControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (previous_controlPoint != null) + { + return previous_controlPoint.forwardHelperPoint; + } + else + { + return null; + } + } + } + + public override InternalDXXL_BezierControlSubPoint GetNextUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (isForward_notBackward) + { + InternalDXXL_BezierControlPointTriplet next_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetNextControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (next_controlPoint != null) + { + if (next_controlPoint.backwardHelperPoint.isUsed) + { + return next_controlPoint.backwardHelperPoint; + } + else + { + return next_controlPoint.anchorPoint; + } + } + else + { + return null; + } + } + else + { + return GetMountingAnchorPoint(); + } + } + + public override InternalDXXL_BezierControlSubPoint GetPreviousUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (isForward_notBackward) + { + return GetMountingAnchorPoint(); + } + else + { + InternalDXXL_BezierControlPointTriplet previous_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetPreviousControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (previous_controlPoint != null) + { + if (previous_controlPoint.forwardHelperPoint.isUsed) + { + return previous_controlPoint.forwardHelperPoint; + } + else + { + return previous_controlPoint.anchorPoint; + } + } + else + { + return null; + } + } + } + + public override Vector3 GetDirectionAlongSplineForwardBasedOnNeighborPoints_inUnitsOfGlobalSpace() + { + if (isForward_notBackward) + { + return Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + } + else + { + return (-Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized()); + } + } + + public InternalDXXL_BezierControlPointTriplet Get_neighboringControlPoint(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return (isForward_notBackward ? Get_controlPointTriplet_thisSubPointIsPartOf().GetNextControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) : Get_controlPointTriplet_thisSubPointIsPartOf().GetPreviousControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet)); + } + + public InternalDXXL_BezierControlHelperSubPoint Get_neighboringHelperPoint_ofNeighboringControlPoint(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + InternalDXXL_BezierControlPointTriplet neighboringControlPoint = Get_neighboringControlPoint(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (neighboringControlPoint == null) + { + return null; + } + else + { + InternalDXXL_BezierControlHelperSubPoint neighboringHelperPoint_ofNeighboringControlPoint = neighboringControlPoint.GetAHelperPoint(!isForward_notBackward); + if (neighboringHelperPoint_ofNeighboringControlPoint.isUsed) + { + return neighboringHelperPoint_ofNeighboringControlPoint; + } + else + { + return null; + } + } + } + + public override bool IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid() + { + bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid; + if (isForward_notBackward) + { + isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid = ((bezierSplineDrawer_thisSubPointIsPartOf.gapFromEndToStart_isClosed == false) && Get_controlPointTriplet_thisSubPointIsPartOf().IsLastControlPoint()); + } + else + { + isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid = ((bezierSplineDrawer_thisSubPointIsPartOf.gapFromEndToStart_isClosed == false) && Get_controlPointTriplet_thisSubPointIsPartOf().IsFirstControlPoint()); + } + + if (isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid) { isUsed = false; } //-> this setting of "isUsed" is actually not be necessary here. It acts here as double bottom if somehow the states got confused. + return isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid; + } + + bool isUsed_afterInspectorInput; + Vector3 direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput; + InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture_afterInspectorInput; + float absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput; + bool closeGapState_afterInspectorInput; + + public void DrawValuesToInspector(Rect rect_ofEnclosingColorSubBox) + { +#if UNITY_EDITOR + FillingIsUsedFieldsWithDefaultValues_forInspector(); + + bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid = IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid(); + bool anchorHasKinkedJunctureType = (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + + DrawBackgroundColor_forInspector(rect_ofEnclosingColorSubBox); + + Rect reducedRectForOnlyContentLines = new Rect(rect_ofEnclosingColorSubBox.x + Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields(), rect_ofEnclosingColorSubBox.y + Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields(), rect_ofEnclosingColorSubBox.width - 2.0f * Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields(), rect_ofEnclosingColorSubBox.height - 2.0f * Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields()); + float currentHeightOffset = 0.0f; + float horizShiftOffset_ofIsUsedCheckbox = 7.0f * UnityEditor.EditorGUIUtility.singleLineHeight; + float width_ofCheckBox = 0.75f * UnityEditor.EditorGUIUtility.singleLineHeight; + + DrawHeadline_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, horizShiftOffset_ofIsUsedCheckbox, width_ofCheckBox, isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, anchorHasKinkedJunctureType); + DrawCollapsableArea_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, anchorHasKinkedJunctureType); +#endif + } + + void FillingIsUsedFieldsWithDefaultValues_forInspector() + { + //This is for cases where the fields are not displayed or greyed out. They are used for an "hasChanged"-check afterwards: + isUsed_afterInspectorInput = isUsed; + position_inUnitsOfActiveDrawSpace_afterInspectorInput = position_inUnitsOfActiveDrawSpace; + boundGameobject_afterInspectorInput = boundGameobject; + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput = direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized; + sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture_afterInspectorInput = sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture; + absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput = absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace; + closeGapState_afterInspectorInput = bezierSplineDrawer_thisSubPointIsPartOf.gapFromEndToStart_isClosed; + } + + void DrawBackgroundColor_forInspector(Rect rect_ofEnclosingColorSubBox) + { +#if UNITY_EDITOR + float alphaFactor_ofBackgroundColor = Get_controlPointTriplet_thisSubPointIsPartOf().isHighlighted ? alpha_ofInspectorBackgroundColor_highlighted : alpha_ofInspectorBackgroundColor_nonHighlighted; + Color backgroundColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_thisSubPointIsPartOf.color_ofHelperPoints, alphaFactor_ofBackgroundColor); + UnityEditor.EditorGUI.DrawRect(rect_ofEnclosingColorSubBox, backgroundColor); +#endif + } + + void DrawHeadline_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, float horizShiftOffset_ofIsUsedCheckbox, float width_ofCheckBox, bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, bool anchorHasKinkedJunctureType) + { + DrawIsUsedCheckbox_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, horizShiftOffset_ofIsUsedCheckbox, width_ofCheckBox, isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, anchorHasKinkedJunctureType); + TryDrawCloseGapCheckbox_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, width_ofCheckBox); + DrawHeadlineTextWithFoldout_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, horizShiftOffset_ofIsUsedCheckbox, isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, anchorHasKinkedJunctureType); + } + + void DrawIsUsedCheckbox_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, float horizShiftOffset_ofIsUsedCheckbox, float width_ofCheckBox, bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, bool anchorHasKinkedJunctureType) + { +#if UNITY_EDITOR + //no tooltip can be used here because this would require also a mainTextField, which this checkbox doesn't have. Instead the tooltip of the foldout (which also contains the headline text) beside this checkbox is intentionally misused to explain the checkbox meaning. + Rect rect_of_isUsedCheckbox = new Rect(reducedRectForOnlyContentLines.x + horizShiftOffset_ofIsUsedCheckbox, reducedRectForOnlyContentLines.y + currentHeightOffset, width_ofCheckBox, UnityEditor.EditorGUIUtility.singleLineHeight); + if (isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid) + { + //always "off": + UnityEditor.EditorGUI.BeginDisabledGroup(true); + UnityEditor.EditorGUI.Toggle(rect_of_isUsedCheckbox, false); + UnityEditor.EditorGUI.EndDisabledGroup(); + } + else + { + if (anchorHasKinkedJunctureType) + { + isUsed_afterInspectorInput = UnityEditor.EditorGUI.Toggle(rect_of_isUsedCheckbox, GUIContent.none, isUsed); + } + else + { + //always "on": + UnityEditor.EditorGUI.BeginDisabledGroup(true); + UnityEditor.EditorGUI.Toggle(rect_of_isUsedCheckbox, true); + UnityEditor.EditorGUI.EndDisabledGroup(); + } + } +#endif + } + + void TryDrawCloseGapCheckbox_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, float width_ofCheckBox) + { + if (isForward_notBackward) + { + if (Get_controlPointTriplet_thisSubPointIsPartOf().IsLastControlPoint()) + { + DrawCloseGapCheckbox_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, width_ofCheckBox, "Close the gap from this last forward control point of the spline and connect it to the start of the spline to get a closed ring curve."); + } + } + else + { + if (Get_controlPointTriplet_thisSubPointIsPartOf().IsFirstControlPoint()) + { + DrawCloseGapCheckbox_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, width_ofCheckBox, "Close the gap from this first backward control point of the spline and connect it to the end of the spline to get a closed ring curve."); + } + } + } + + void DrawCloseGapCheckbox_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, float width_ofCheckBox, string tooltip) + { +#if UNITY_EDITOR + float width_ofCloseGapLabel = 4.2f * UnityEditor.EditorGUIUtility.singleLineHeight; + + Rect rect_of_closeGapCheckbox = new Rect(reducedRectForOnlyContentLines.x + reducedRectForOnlyContentLines.width - width_ofCheckBox, reducedRectForOnlyContentLines.y + currentHeightOffset, width_ofCheckBox, UnityEditor.EditorGUIUtility.singleLineHeight); + closeGapState_afterInspectorInput = UnityEditor.EditorGUI.Toggle(rect_of_closeGapCheckbox, bezierSplineDrawer_thisSubPointIsPartOf.gapFromEndToStart_isClosed); + + Rect rect_of_closeGapLabel = new Rect(reducedRectForOnlyContentLines.x + reducedRectForOnlyContentLines.width - width_ofCloseGapLabel, reducedRectForOnlyContentLines.y + currentHeightOffset, width_ofCloseGapLabel, UnityEditor.EditorGUIUtility.singleLineHeight); + UnityEditor.EditorGUI.LabelField(rect_of_closeGapLabel, new GUIContent("Close ring", tooltip)); +#endif + } + + void DrawHeadlineTextWithFoldout_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, float horizShiftOffset_ofIsUsedCheckbox, bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, bool anchorHasKinkedJunctureType) + { +#if UNITY_EDITOR + GUIStyle style_ofHeadline = new GUIStyle(UnityEditor.EditorStyles.foldout); + style_ofHeadline.richText = true; + Color color_ofHeadline_nonAccentuated = bezierSplineDrawer_thisSubPointIsPartOf.color_ofHelperPoints; + Color color_ofHeadline_accentuated = ((color_ofHeadline_nonAccentuated.grayscale < 0.175f) ? Color.Lerp(color_ofHeadline_nonAccentuated, Color.white, 0.9f) : Color.Lerp(color_ofHeadline_nonAccentuated, Color.black, 0.7f)); + if (isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid) + { + color_ofHeadline_accentuated = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofHeadline_accentuated, 0.5f); + } + + string headlineText; + if (isForward_notBackward) + { + headlineText = " Forward Weight"; + } + else + { + headlineText = " Backward Weight"; + } + + float horizShiftOffset_ofFoldoutHeadline = 0.65f * UnityEditor.EditorGUIUtility.singleLineHeight; + Rect rect_of_foldoutHeadline = new Rect(reducedRectForOnlyContentLines.x + horizShiftOffset_ofFoldoutHeadline, reducedRectForOnlyContentLines.y + currentHeightOffset, horizShiftOffset_ofIsUsedCheckbox - horizShiftOffset_ofFoldoutHeadline, UnityEditor.EditorGUIUtility.singleLineHeight); + + //the tooltip for the foldoutWithText is intentionally misused here and doesn't explain the foldout itself, but the "isUsed"-checkbox right beside the text + if (isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid) + { + UnityEditor.EditorGUI.BeginDisabledGroup(true); + UnityEditor.EditorGUI.Foldout(rect_of_foldoutHeadline, false, new GUIContent(headlineText, "Only available for closed ring splines."), true, style_ofHeadline); + UnityEditor.EditorGUI.EndDisabledGroup(); + } + else + { + GUIContent guiContent_ofFoldoutHeadline; + if (anchorHasKinkedJunctureType) + { + guiContent_ofFoldoutHeadline = new GUIContent(headlineText); + } + else + { + guiContent_ofFoldoutHeadline = new GUIContent(headlineText, "Can only be deactivated for kinked juncture type."); + } + isOutfoldedInInspector = UnityEditor.EditorGUI.Foldout(rect_of_foldoutHeadline, isOutfoldedInInspector, guiContent_ofFoldoutHeadline, true, style_ofHeadline); + } +#endif + } + + void DrawCollapsableArea_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, bool anchorHasKinkedJunctureType) + { +#if UNITY_EDITOR + if (isOutfoldedInInspector && (isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid == false)) + { + bool greyOutValues = (isUsed == false); + if (greyOutValues) { UnityEditor.EditorGUI.BeginDisabledGroup(true); } + + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawPositionLine_forInspector(reducedRectForOnlyContentLines, currentHeightOffset); + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawBoundGameobjectLine_forInspector(reducedRectForOnlyContentLines, currentHeightOffset); + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawDirectionLine_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, anchorHasKinkedJunctureType); + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawDistanceLine_forInspector(reducedRectForOnlyContentLines, currentHeightOffset); + + if (greyOutValues) { UnityEditor.EditorGUI.EndDisabledGroup(); } + } +#endif + } + + void DrawPositionLine_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset) + { +#if UNITY_EDITOR + string label_of_position = "Position"; + if (isUsed) + { + DrawPositionLine_forInspector(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_position, Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector())); + } + else + { + UnityEditor.EditorGUI.Vector3Field(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_position), new Vector3(float.NaN, float.NaN, float.NaN)); + } +#endif + } + + void DrawBoundGameobjectLine_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset) + { +#if UNITY_EDITOR + string label_of_bindToGameobject = "Bind to gameobject"; + if (isUsed) + { + DrawBoundGameobjectLine_forInspector(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_bindToGameobject)); + } + else + { + UnityEditor.EditorGUI.ObjectField(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_bindToGameobject), null, typeof(UnityEngine.GameObject), true); + } +#endif + } + + void DrawDirectionLine_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, bool anchorHasKinkedJunctureType) + { +#if UNITY_EDITOR + string label_ofDirection; + if (Get_controlPointTriplet_thisSubPointIsPartOf().isHighlighted) + { + label_ofDirection = "Direction from point center to this weight"; + } + else + { + label_ofDirection = "Direction from point center to this weight"; //-> Could adapt the color to the semitransparent triplet main color, but in most cases then the readability is bad. + } + + if (isUsed) + { + string tooltip_ofDirection; + bool anchorHasBoundGameobject = (GetMountingAnchorPoint().boundGameobject != null); //-> could be improved: there is no check whether the "boundGameobject" is "inactive" or the connection component on it is "disabled". + + if (anchorHasBoundGameobject && anchorHasKinkedJunctureType) + { + tooltip_ofDirection = "This line displays the normalized direction from the center point to this weight point." + Environment.NewLine + Environment.NewLine + "For kinked juncture types this direction can be bound individually per weight side to the rotation of the gameobject at the center position." + Environment.NewLine + Environment.NewLine + "Note that the gameobject mentioned in the direction source picker dropdown menu is the gameobject that is bound to the CENTER position, not the one bound to this WEIGHT position." + Environment.NewLine + Environment.NewLine + Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector(); + } + else + { + tooltip_ofDirection = "This is normalized. " + Environment.NewLine + "Value input will be changed so that the overall vector stays normalized." + Environment.NewLine + Environment.NewLine + Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector(); + } + + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput = Draw_Vector3Field_withoutLineBreak_forInspector(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), out Rect rectForOnlyThePrefixLabel, new GUIContent(label_ofDirection, tooltip_ofDirection), direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized, true); + + if (anchorHasBoundGameobject && anchorHasKinkedJunctureType) + { + float portionOPrefixLabelSpace_thatIsFilledByEnumPopup = 1.0f; + Rect rect_forDirectionSourceEnumPopup = new Rect(rectForOnlyThePrefixLabel.x + (1.0f - portionOPrefixLabelSpace_thatIsFilledByEnumPopup) * rectForOnlyThePrefixLabel.width, rectForOnlyThePrefixLabel.y, rectForOnlyThePrefixLabel.width * portionOPrefixLabelSpace_thatIsFilledByEnumPopup, UnityEditor.EditorGUIUtility.singleLineHeight); + + InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers wordedDirectionSource_beforeInput = InternalDXXL_BezierControlAnchorSubPoint.ConvertDirectionSource_fromUsedVersion_toWordedVersion(sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture); + InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers wordedDirectionSource_afterInput = (InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper_wordedForInspectorDisplayAtHelpers)UnityEditor.EditorGUI.EnumPopup(rect_forDirectionSourceEnumPopup, GUIContent.none, wordedDirectionSource_beforeInput); + sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture_afterInspectorInput = InternalDXXL_BezierControlAnchorSubPoint.ConvertDirectionSource_fromWordedVersion_toUsedVersion(wordedDirectionSource_afterInput); + } + } + else + { + UnityEditor.EditorGUI.Vector3Field(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), label_ofDirection, new Vector3(float.NaN, float.NaN, float.NaN)); + } +#endif + } + + void DrawDistanceLine_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset) + { +#if UNITY_EDITOR + string label_of_distance = "Distance"; + if (isUsed) + { + absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput = UnityEditor.EditorGUI.FloatField(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_distance, Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector()), absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace); + } + else + { + UnityEditor.EditorGUI.FloatField(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_distance), float.NaN); + } +#endif + } + + public bool TryApplyChangesAfterInspectorInput() + { + //The checks here are more reliable than "EditorGUI.BeginChangeCheck/EndChangeCheck()", which also reports "change" only due to mouse selection, even when the value didn't change yet. + + if (isUsed_afterInspectorInput != isUsed) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Toggle Spline Weight", false, false); + ChangeUsedState(isUsed_afterInspectorInput, true); + return true; + } + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreExactlyEqual(position_inUnitsOfActiveDrawSpace_afterInspectorInput, position_inUnitsOfActiveDrawSpace) == false) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Position", true, true); + SetPos_inUnitsOfActiveDrawSpace(position_inUnitsOfActiveDrawSpace_afterInspectorInput, true, null); + return true; + } + + if (boundGameobject_afterInspectorInput != boundGameobject) + { + //bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Gameobject Ref", true, true); //not needed here, because it is cared for inside "ProcessNewGameobjectAssignment" + ProcessNewGameobjectAssignment(boundGameobject_afterInspectorInput); + return true; + } + + if (direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput != direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Direction", true, true); + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput.Normalize(); + Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput, true, null); + return true; + } + + if (sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture_afterInspectorInput != sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Direction Source", true, true); + ProcessChanging_sourceOfDirectionFromAnchor(sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture_afterInspectorInput); + return true; + } + + if (absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput != absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace) + { + absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput = Mathf.Max(absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput, 0.0f); + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Distance", true, true); + Set_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput, true, null); + return true; + } + + if (closeGapState_afterInspectorInput != bezierSplineDrawer_thisSubPointIsPartOf.gapFromEndToStart_isClosed) + { + bezierSplineDrawer_thisSubPointIsPartOf.ChangeCloseGapState(closeGapState_afterInspectorInput); + return true; + } + + return false; + } + + public override float GetPropertyHeightForInspectorList() + { +#if UNITY_EDITOR + if (isOutfoldedInInspector && (IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid() == false)) + { + float height_forAllContentLines = 5.0f * UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + return (Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields() + height_forAllContentLines + Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields()); + } + else + { + return (Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields() + UnityEditor.EditorGUIUtility.singleLineHeight + Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields()); + } +#else + return 16.0f; //-> not used +#endif + } + + public static float Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields() + { +#if UNITY_EDITOR + return (0.2f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint.cs.meta new file mode 100644 index 0000000..5928588 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0bc7695778ef65743b49c30705043aab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint2D.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint2D.cs new file mode 100644 index 0000000..9e37a72 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint2D.cs @@ -0,0 +1,1020 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + + [Serializable] + public class InternalDXXL_BezierControlHelperSubPoint2D : InternalDXXL_BezierControlSubPoint2D + { + [SerializeField] public bool isOutfoldedInInspector = false; + [SerializeField] Vector2 direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized; + [SerializeField] Vector2 direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized; + [SerializeField] public InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture; //-> is only used when a "boundGameobject" is assigned at the mountingAnchor + [SerializeField] public float absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace; + [SerializeField] float absDistanceToAnchorPoint_inUnitsOfGlobalSpace; + + public bool isForward_notBackward; + + public int controlID_ofCustomHandles_sphere; + public int controlID_ofCustomHandles_coneAlongLineWithAnchor; + public int controlID_ofCustomHandles_coneAlongLineWithNeighborsHelper; + public int controlID_ofCustomHandles_cylinderAlongLineWithAnchor; + public int controlID_ofCustomHandles_cylinderAlongLineWithNeighborsHelper; + + public Vector2 directionForHandles_alongLineWithMountingAnchor_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = Vector2.right; + public Vector2 directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_toForwardDirOfWholeSpline_inUnitsOfGlobalSpace_normalized = Vector2.left; + public bool recalc_directionForHandles_alongLineWithMountingAnchor_duringNextOnSceneGUI = true; + public bool recalc_directionForHandles_alongLineWithNeighboringHelperOfNeighboringControlPoint_duringNextOnSceneGUI = true; + [SerializeField] Vector2 positionOfAnchor_inMomentOfDeactivationOfThisHelper_inUnitsOfGlobalSpace; + + public override void InitializeValuesThatAreIndependentFromOtherSubPoints(InternalDXXL_BezierControlPointTriplet2D controlPoint_thisSubPointIsPartOf) + { + base.InitializeValuesThatAreIndependentFromOtherSubPoints(controlPoint_thisSubPointIsPartOf); + sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture = InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject; + } + + public InternalDXXL_BezierControlAnchorSubPoint2D GetMountingAnchorPoint() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + return bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets[i_ofContainingControlPoint_insideControlPointsList].anchorPoint; + } + + public InternalDXXL_BezierControlHelperSubPoint2D GetOppositeHelperPoint() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + return bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets[i_ofContainingControlPoint_insideControlPointsList].GetAHelperPoint(!isForward_notBackward); + } + + public void ChangeUsedState(bool newStateOf_isUsed, bool stateChangeComesFromUserInputViaInspectorsIsUsedBoolCheckboxOnKinkedTriplet) + { + if (newStateOf_isUsed != isUsed) + { + isUsed = newStateOf_isUsed; + if (newStateOf_isUsed == true) + { + ProcessActivation(stateChangeComesFromUserInputViaInspectorsIsUsedBoolCheckboxOnKinkedTriplet); + } + else + { + ProcessDeactivation(); + } + } + } + + void ProcessActivation(bool stateChangeComesFromUserInputViaInspectorsIsUsedBoolCheckboxOnKinkedTriplet) + { + if (stateChangeComesFromUserInputViaInspectorsIsUsedBoolCheckboxOnKinkedTriplet) + { + //-> "junctureType == kinked" is guaranteed here + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(positionOfAnchor_inMomentOfDeactivationOfThisHelper_inUnitsOfGlobalSpace, GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace())) + { + SetInitialPos_viaRestoringValuesFromPreDeactivation(); + } + else + { + SetInitialPos_withoutKnowledgeOfPreDeactivationPos(); + } + } + else + { + SetInitialPos_withoutKnowledgeOfPreDeactivationPos(); + } + } + + void ProcessDeactivation() + { + positionOfAnchor_inMomentOfDeactivationOfThisHelper_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace(); + } + + void SetInitialPos_viaRestoringValuesFromPreDeactivation() + { + //This restoration allows: + //-> ticking the used state in the inspector testwise off an on without losing the values + //-> special moves like temporarily decactivating a helperPoint, so that only the other helperPoint is affected by the rotationHandle of the anchorPoint. + + //The only case where this happens is: "junctureType=kinked", and the helper has been manually deactivated during this "kinked"-phase + //The condition that the mountingAnchor shouldn't have changed it's position since the deactivation has this effect: + //-> If the spline shape changed a lot during the inactive-phase then the reactivation could cause irritation because the spline shape can then immediately be unintendedly warped and stretched across the whole scene. + //-> As a side effect the re-activated helper forgets his former state also if the helper only changed slightly. It would actually be a welcomed functionality that in such cases the helper would restore its former position, but it is sacrified for for the prevention of the aforementioned irration. + + this.SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + GetMountingAnchorPoint().SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (GetMountingAnchorPoint().boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled && (sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject)) + { + //restoring the position based on the distance and direction: + float newAbsDistance_inUnitsOfGlobalSpace; + if (this.boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + //the "thisHelper.boundGameobject" may have changed it's position during the unused-phase. But since "mountingAnchor.boundGameobject" dictates a "direction" only the DISTANCE from "thisHelper.boundGameobject" is used, not the POSITION: + newAbsDistance_inUnitsOfGlobalSpace = (GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() - this.GetPos_inUnitsOfGlobalSpace()).magnitude; + } + else + { + newAbsDistance_inUnitsOfGlobalSpace = absDistanceToAnchorPoint_inUnitsOfGlobalSpace; + } + + Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistance_inUnitsOfGlobalSpace, true, this.boundGameobject); //-> "this.boundGameobject" can also be "null" here, which does not harm + GetMountingAnchorPoint().connectionComponent_onBoundGameobject.Transfer_aTransformDirection_fromBoundGameobject_toSpline(); + } + else + { + //restoring the direction and distance based on the position: + if (this.boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + connectionComponent_onBoundGameobject.Transfer_position_fromBoundGameobject_toSpline(); + } + else + { + //-> this doesn't change the position, but refreshes the dependent values ("direction" and "distance"): + SetPos_inUnitsOfGlobalSpace(GetPos_inUnitsOfGlobalSpace(), true, null); //-> this is actually not be necessary here, because the direction and distance cannot be different from what they were onSetUnused, since the anchorPos stayed the same. It acts here as double bottom if somehow the states got confused. + } + } + } + + void SetInitialPos_withoutKnowledgeOfPreDeactivationPos() + { + Vector2 initialDirection_inUnitsOfGlobalSpace_normalized; + float initialAbsDistance_inUnitsOfGlobalSpace; + if (GetOppositeHelperPoint().isUsed == true) + { + initialDirection_inUnitsOfGlobalSpace_normalized = (-GetOppositeHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized()); + if ((UtilitiesDXXL_Math.ApproximatelyZero(GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace()) == false) || (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored)) + { + initialAbsDistance_inUnitsOfGlobalSpace = GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + } + else + { + initialAbsDistance_inUnitsOfGlobalSpace = Get_initialAbsDistance_inUnitsOfGlobalSpace_fromGlobalSettingsForNewlyCreatedPoints(); + } + } + else + { + initialDirection_inUnitsOfGlobalSpace_normalized = Get_initialDirection_inUnitsOfGlobalSpace_normalized_caseNoInformationFromOppositeHelper(); + initialAbsDistance_inUnitsOfGlobalSpace = Get_initialAbsDistance_inUnitsOfGlobalSpace_fromGlobalSettingsForNewlyCreatedPoints(); + } + SetInitialPos(initialDirection_inUnitsOfGlobalSpace_normalized, initialAbsDistance_inUnitsOfGlobalSpace); + } + + void SetInitialPos(Vector2 initialDirection_inUnitsOfGlobalSpace_normalized, float initialAbsDistance_inUnitsOfGlobalSpace) + { + Vector2 initialPosition_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() + initialDirection_inUnitsOfGlobalSpace_normalized * initialAbsDistance_inUnitsOfGlobalSpace; + SetPos_inUnitsOfGlobalSpace(initialPosition_inUnitsOfGlobalSpace, true, null); + } + + float Get_initialAbsDistance_inUnitsOfGlobalSpace_fromGlobalSettingsForNewlyCreatedPoints() + { + if (isForward_notBackward) + { + return bezierSplineDrawer_thisSubPointIsPartOf.TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(bezierSplineDrawer_thisSubPointIsPartOf.forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace); + } + else + { + return bezierSplineDrawer_thisSubPointIsPartOf.TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(bezierSplineDrawer_thisSubPointIsPartOf.backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace); + } + } + + Vector2 Get_initialDirection_inUnitsOfGlobalSpace_normalized_caseNoInformationFromOppositeHelper() + { + InternalDXXL_BezierControlSubPoint2D nextUsedNonSuperimposed_subPoint; + InternalDXXL_BezierControlSubPoint2D previousUsedNonSuperimposed_subPoint; + if (isForward_notBackward) + { + nextUsedNonSuperimposed_subPoint = GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + previousUsedNonSuperimposed_subPoint = GetOppositeHelperPoint().GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + } + else + { + nextUsedNonSuperimposed_subPoint = GetOppositeHelperPoint().GetNextUsedNonSuperimposedSubPointAlongSplineDir(false); + previousUsedNonSuperimposed_subPoint = GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(false); + } + + if (nextUsedNonSuperimposed_subPoint == null) + { + return GetRightRespLeft_ofActiveDrawSpace_normalized(); + } + else + { + if (previousUsedNonSuperimposed_subPoint == null) + { + return GetRightRespLeft_ofActiveDrawSpace_normalized(); + } + else + { + if (Get_controlPointTriplet_thisSubPointIsPartOf().IsPartOfThisTriplet(nextUsedNonSuperimposed_subPoint)) + { + return GetRightRespLeft_ofActiveDrawSpace_normalized(); + } + else + { + if (Get_controlPointTriplet_thisSubPointIsPartOf().IsPartOfThisTriplet(previousUsedNonSuperimposed_subPoint)) + { + return GetRightRespLeft_ofActiveDrawSpace_normalized(); + } + else + { + Vector2 previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace = nextUsedNonSuperimposed_subPoint.GetPos_inUnitsOfGlobalSpace() - previousUsedNonSuperimposed_subPoint.GetPos_inUnitsOfGlobalSpace(); + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace) < 0.0001f) + { + return GetRightRespLeft_ofActiveDrawSpace_normalized(); + } + else + { + Vector2 previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace_normalized)) + { + return GetRightRespLeft_ofActiveDrawSpace_normalized(); + } + else + { + return TryFlipVectorForBackwardHelpers(previousUsedSubpoint_to_nextUsedSubpoint_inUnitsOfGlobalSpace_normalized); + } + } + } + } + } + } + } + + Vector2 GetRightRespLeft_ofActiveDrawSpace_normalized() + { + return TryFlipVectorForBackwardHelpers(bezierSplineDrawer_thisSubPointIsPartOf.Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized()); + } + + Vector2 TryFlipVectorForBackwardHelpers(Vector2 vectorToTryFlip) + { + if (isForward_notBackward) + { + return vectorToTryFlip; + } + else + { + return (-vectorToTryFlip); + } + } + + public override void ResetDirectionSourceToIndependent() + { + sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture = InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject; + } + + public void ProcessChanging_sourceOfDirectionFromAnchor(InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D newSourceOfDirection) + { + if (newSourceOfDirection != sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture) + { + sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture = newSourceOfDirection; + if (newSourceOfDirection != InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject) + { + GetMountingAnchorPoint().TryTransfer_newTransformDirection_fromBoundGameobject_toSpline_afterDirectionSourceChange(); + } + } + } + + public float Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace() + { + return absDistanceToAnchorPoint_inUnitsOfGlobalSpace; + } + + public float Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace() + { + return absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace; + } + + public void Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(float new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (UtilitiesDXXL_Math.FloatIsValid(new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace)) + { + new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace = Mathf.Max(0.0f, new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace); + absDistanceToAnchorPoint_inUnitsOfGlobalSpace = new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace; + absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace = bezierSplineDrawer_thisSubPointIsPartOf.TransformLength_fromGlobalSpace_toUnitsOfActiveDrawSpace(new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace); + TryUpdateDependentValues_after_onSetAbsDistanceToAnchorPointInUnitsOfGlobalSpace(new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + void TryUpdateDependentValues_after_onSetAbsDistanceToAnchorPointInUnitsOfGlobalSpace(float new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (updateDependentValuesOnControlPointTriplet) + { + Vector2 vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace = Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized() * new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace; + Vector2 newPosition_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() + vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace; + SetPos_inUnitsOfGlobalSpace(newPosition_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetOppositeHelperPoint().isUsed) + { + if (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + GetOppositeHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(new_absDistanceToAnchorPoint_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + Vector2 newPosition_ofOppositeHelperPoint_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() - vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace; + GetOppositeHelperPoint().SetPos_inUnitsOfGlobalSpace(newPosition_ofOppositeHelperPoint_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + } + + public void Set_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(float new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (UtilitiesDXXL_Math.FloatIsValid(new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace)) + { + new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace = Mathf.Max(0.0f, new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace); + absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace = new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace; + absDistanceToAnchorPoint_inUnitsOfGlobalSpace = bezierSplineDrawer_thisSubPointIsPartOf.TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace); + TryUpdateDependentValues_after_onSetAbsDistanceToAnchorPointInUnitsOfActiveDrawSpace(new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + + void TryUpdateDependentValues_after_onSetAbsDistanceToAnchorPointInUnitsOfActiveDrawSpace(float new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (updateDependentValuesOnControlPointTriplet) + { + Vector2 vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfActiveDrawSpace = Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized() * new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace; + Vector2 newPosition_inUnitsOfActiveDrawSpace = GetMountingAnchorPoint().GetPos_inUnitsOfActiveDrawSpace() + vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfActiveDrawSpace; + SetPos_inUnitsOfActiveDrawSpace(newPosition_inUnitsOfActiveDrawSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetOppositeHelperPoint().isUsed) + { + if (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + GetOppositeHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(new_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + Vector2 newPosition_ofOppositeHelperPoint_inUnitsOfActiveDrawSpace = GetMountingAnchorPoint().GetPos_inUnitsOfActiveDrawSpace() - vector_fromMountingAnchorPoint_toThisHelperPoint_inUnitsOfActiveDrawSpace; + GetOppositeHelperPoint().SetPos_inUnitsOfActiveDrawSpace(newPosition_ofOppositeHelperPoint_inUnitsOfActiveDrawSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + } + + public override void SetPos_inUnitsOfGlobalSpace(Vector2 newPos_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + SetPos_inUnitsOfGlobalSpace_butIgnoreDependentValues_nonRecursively(newPos_inUnitsOfGlobalSpace, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (updateDependentValuesOnControlPointTriplet) + { + Vector2 newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_notNormalized = newPos_inUnitsOfGlobalSpace - GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace(); + float newAbsDistance_toAnchorPoint_inUnitsOfGlobalSpace = newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_notNormalized.magnitude; + Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistance_toAnchorPoint_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + Vector2 newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_normalized; + if (UtilitiesDXXL_Math.ApproximatelyZero(newAbsDistance_toAnchorPoint_inUnitsOfGlobalSpace)) + { + //-> no change of the direction: + newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_normalized = GetMountingAnchorPoint().Get_aDirection_inUnitsOfGlobalSpace_normalized(isForward_notBackward); + } + else + { + newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_normalized = newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_notNormalized / newAbsDistance_toAnchorPoint_inUnitsOfGlobalSpace; + } + Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetOppositeHelperPoint().isUsed) + { + if (GetMountingAnchorPoint().junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + Vector2 newDirection_fromAnchorPoint_toOtherHelperPoint_inUnitsOfGlobalSpace_normalized = GetMountingAnchorPoint().ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(newDirection_fromAnchorPoint_toThisHelperPoint_inUnitsOfGlobalSpace_normalized); + GetOppositeHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(newDirection_fromAnchorPoint_toOtherHelperPoint_inUnitsOfGlobalSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.mirrored) + { + GetOppositeHelperPoint().Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(newAbsDistance_toAnchorPoint_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + Vector2 newPos_ofOppositeHelperPoint_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() + GetOppositeHelperPoint().Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized() * GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + GetOppositeHelperPoint().SetPos_inUnitsOfGlobalSpace(newPos_ofOppositeHelperPoint_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + } + + public Vector2 Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized() + { + return direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized; + } + + public Vector2 Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized() + { + return direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized; + } + + public void Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(Vector2 newDirection_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Set_direction_toThisHelper_fromAnchor_inBothSpaces_butDefinedViaGlobalSpace_normalized(newDirection_inUnitsOfGlobalSpace_normalized); + TryPassOnNew_direction_toThisHelper_inUnitsOfGlobalSpace_normalized_toBoundGameobject(newDirection_inUnitsOfGlobalSpace_normalized, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + TryUpdateDependentValues_after_onSetDirectionToThisHelperInUnitsOfGlobalSpace(newDirection_inUnitsOfGlobalSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + void Set_direction_toThisHelper_fromAnchor_inBothSpaces_butDefinedViaGlobalSpace_normalized(Vector2 newDirection_inUnitsOfGlobalSpace_normalized) + { + direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized = newDirection_inUnitsOfGlobalSpace_normalized; + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized = bezierSplineDrawer_thisSubPointIsPartOf.TransformDirection_fromGlobalSpace_toUnitsOfActiveDrawSpace(newDirection_inUnitsOfGlobalSpace_normalized); + + //normalization because: + //-> if the spline component carrying gameobject or a parent has a non-z-rotation, then the normalized return value of "TransformDirection_fromGlobalSpace_toUnitsOfActiveDrawSpace" has non-0 in the z-component. After the z-component is discarded the normalization is lost + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized)) + { + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized = GetRightRespLeft_ofActiveDrawSpace_normalized(); + } + + } + + void TryUpdateDependentValues_after_onSetDirectionToThisHelperInUnitsOfGlobalSpace(Vector2 newDirection_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (updateDependentValuesOnControlPointTriplet) + { + Vector2 newPos_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() + newDirection_inUnitsOfGlobalSpace_normalized * Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + SetPos_inUnitsOfGlobalSpace(newPos_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetOppositeHelperPoint().isUsed) + { + if (GetMountingAnchorPoint().junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + Vector2 newDirection_toOppositeHelper_inUnitsOfGlobalSpace_normalized = ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(newDirection_inUnitsOfGlobalSpace_normalized); + GetOppositeHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(newDirection_toOppositeHelper_inUnitsOfGlobalSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + Vector2 newPosOfOppositeHelper_inUnitsOfGlobalSpace = GetMountingAnchorPoint().GetPos_inUnitsOfGlobalSpace() + newDirection_toOppositeHelper_inUnitsOfGlobalSpace_normalized * GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + GetOppositeHelperPoint().SetPos_inUnitsOfGlobalSpace(newPosOfOppositeHelper_inUnitsOfGlobalSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + } + + public void Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(Vector2 newDirection_inUnitsOfActiveDrawSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Set_direction_toThisHelper_fromAnchor_inBothSpaces_butDefinedViaActiveDrawSpace_normalized(newDirection_inUnitsOfActiveDrawSpace_normalized); + //"direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized" has been set right before inside "Set_direction_toThisHelper_fromAnchor_inBothSpaces_butDefinedViaActiveDrawSpace_normalized()" and therefore is guaranteed available here + TryPassOnNew_direction_toThisHelper_inUnitsOfGlobalSpace_normalized_toBoundGameobject(direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + TryUpdateDependentValues_after_onSetDirectionToThisHelperInUnitsOfActiveDrawSpace(newDirection_inUnitsOfActiveDrawSpace_normalized, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + void Set_direction_toThisHelper_fromAnchor_inBothSpaces_butDefinedViaActiveDrawSpace_normalized(Vector2 newDirection_inUnitsOfActiveDrawSpace_normalized) + { + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized = newDirection_inUnitsOfActiveDrawSpace_normalized; + direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized = bezierSplineDrawer_thisSubPointIsPartOf.TransformDirection_fromUnitsOfActiveDrawSpace_toGlobalSpace(newDirection_inUnitsOfActiveDrawSpace_normalized); + + //normalization because: + //-> if the spline component carrying gameobject or a parent has a non-z-rotation, then the normalized return value of "TransformDirection_fromUnitsOfActiveDrawSpace_toGlobalSpace" has non-0 in the z-component. After the z-component is discarded the normalization is lost + direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized)) + { + direction_toThisHelper_fromAnchor_inUnitsOfGlobalSpace_normalized = GetRightRespLeft_ofActiveDrawSpace_normalized(); + } + } + + public void TryUpdateDependentValues_after_onSetDirectionToThisHelperInUnitsOfActiveDrawSpace(Vector2 newDirection_inUnitsOfActiveDrawSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + if (updateDependentValuesOnControlPointTriplet) + { + Vector2 newPos_inUnitsOfActiveDrawSpace = GetMountingAnchorPoint().GetPos_inUnitsOfActiveDrawSpace() + newDirection_inUnitsOfActiveDrawSpace_normalized * Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + SetPos_inUnitsOfActiveDrawSpace(newPos_inUnitsOfActiveDrawSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + if (GetOppositeHelperPoint().isUsed) + { + if (GetMountingAnchorPoint().junctureType != InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + Vector2 newDirection_toOppositeHelper_inUnitsOfActiveDrawSpace_normalized = ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(newDirection_inUnitsOfActiveDrawSpace_normalized); + GetOppositeHelperPoint().Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(newDirection_toOppositeHelper_inUnitsOfActiveDrawSpace_normalized, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + + Vector2 newPosOfOppositeHelper_inUnitsOfActiveDrawSpace = GetMountingAnchorPoint().GetPos_inUnitsOfActiveDrawSpace() + newDirection_toOppositeHelper_inUnitsOfActiveDrawSpace_normalized * GetOppositeHelperPoint().Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + GetOppositeHelperPoint().SetPos_inUnitsOfActiveDrawSpace(newPosOfOppositeHelper_inUnitsOfActiveDrawSpace, false, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + } + + public void TryPassOnNew_direction_toThisHelper_inUnitsOfGlobalSpace_normalized_toBoundGameobject(Vector2 newDirection_inUnitsOfGlobalSpace_normalized, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + GetMountingAnchorPoint().SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (GetMountingAnchorPoint().boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + if (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked) + { + if (sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture != InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject) + { + GetMountingAnchorPoint().connectionComponent_onBoundGameobject.Transfer_newDirectionToAHelperPointInUnitsOfGlobalSpaceNormalized_fromSpline_toBoundGameobject(newDirection_inUnitsOfGlobalSpace_normalized, sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + else + { + Vector2 newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized = newDirection_inUnitsOfGlobalSpace_normalized; + if (isForward_notBackward == false) + { + newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized = ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized); + } + GetMountingAnchorPoint().TryPassOnNew_directionToHelper_unifiedTowardsForwardForCaseNonKinked_inUnitsOfGlobalSpace_normalized_toBoundGameobject(newDirection_unifiedToForward_inUnitsOfGlobalSpace_normalized, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + } + } + + public Vector2 ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(Vector2 givenDirectionToHelper) + { + return GetMountingAnchorPoint().ConvertGivenDirectionToHelper_to_alingedDirectionToOtherHelper(givenDirectionToHelper); + } + + public override InternalDXXL_BezierControlSubPoint2D GetNextSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (isForward_notBackward) + { + InternalDXXL_BezierControlPointTriplet2D next_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetNextControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (next_controlPoint != null) + { + return next_controlPoint.backwardHelperPoint; + } + else + { + return null; + } + } + else + { + return GetMountingAnchorPoint(); + } + } + + public override InternalDXXL_BezierControlSubPoint2D GetPreviousSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (isForward_notBackward) + { + return GetMountingAnchorPoint(); + } + else + { + InternalDXXL_BezierControlPointTriplet2D previous_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetPreviousControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (previous_controlPoint != null) + { + return previous_controlPoint.forwardHelperPoint; + } + else + { + return null; + } + } + } + + public override InternalDXXL_BezierControlSubPoint2D GetNextUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (isForward_notBackward) + { + InternalDXXL_BezierControlPointTriplet2D next_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetNextControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (next_controlPoint != null) + { + if (next_controlPoint.backwardHelperPoint.isUsed) + { + return next_controlPoint.backwardHelperPoint; + } + else + { + return next_controlPoint.anchorPoint; + } + } + else + { + return null; + } + } + else + { + return GetMountingAnchorPoint(); + } + } + + public override InternalDXXL_BezierControlSubPoint2D GetPreviousUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + if (isForward_notBackward) + { + return GetMountingAnchorPoint(); + } + else + { + InternalDXXL_BezierControlPointTriplet2D previous_controlPoint = Get_controlPointTriplet_thisSubPointIsPartOf().GetPreviousControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (previous_controlPoint != null) + { + if (previous_controlPoint.forwardHelperPoint.isUsed) + { + return previous_controlPoint.forwardHelperPoint; + } + else + { + return previous_controlPoint.anchorPoint; + } + } + else + { + return null; + } + } + } + + public override Vector2 GetDirectionAlongSplineForwardBasedOnNeighborPoints_inUnitsOfGlobalSpace() + { + if (isForward_notBackward) + { + return Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(); + } + else + { + return (-Get_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized()); + } + } + + public InternalDXXL_BezierControlPointTriplet2D Get_neighboringControlPoint(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return (isForward_notBackward ? Get_controlPointTriplet_thisSubPointIsPartOf().GetNextControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) : Get_controlPointTriplet_thisSubPointIsPartOf().GetPreviousControlPointTripletAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet)); + } + + public InternalDXXL_BezierControlHelperSubPoint2D Get_neighboringHelperPoint_ofNeighboringControlPoint(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + InternalDXXL_BezierControlPointTriplet2D neighboringControlPoint = Get_neighboringControlPoint(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + if (neighboringControlPoint == null) + { + return null; + } + else + { + InternalDXXL_BezierControlHelperSubPoint2D neighboringHelperPoint_ofNeighboringControlPoint = neighboringControlPoint.GetAHelperPoint(!isForward_notBackward); + if (neighboringHelperPoint_ofNeighboringControlPoint.isUsed) + { + return neighboringHelperPoint_ofNeighboringControlPoint; + } + else + { + return null; + } + } + } + + public override bool IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid() + { + bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid; + if (isForward_notBackward) + { + isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid = ((bezierSplineDrawer_thisSubPointIsPartOf.gapFromEndToStart_isClosed == false) && Get_controlPointTriplet_thisSubPointIsPartOf().IsLastControlPoint()); + } + else + { + isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid = ((bezierSplineDrawer_thisSubPointIsPartOf.gapFromEndToStart_isClosed == false) && Get_controlPointTriplet_thisSubPointIsPartOf().IsFirstControlPoint()); + } + + if (isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid) { isUsed = false; } //-> this setting of "isUsed" is actually not be necessary here. It acts here as double bottom if somehow the states got confused. + return isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid; + } + + bool isUsed_afterInspectorInput; + Vector2 direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput; + InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture_afterInspectorInput; + float absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput; + bool closeGapState_afterInspectorInput; + + public void DrawValuesToInspector(Rect rect_ofEnclosingColorSubBox) + { +#if UNITY_EDITOR + FillingIsUsedFieldsWithDefaultValues_forInspector(); + + bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid = IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid(); + bool anchorHasKinkedJunctureType = (GetMountingAnchorPoint().junctureType == InternalDXXL_BezierControlAnchorSubPoint.JunctureType.kinked); + + DrawBackgroundColor_forInspector(rect_ofEnclosingColorSubBox); + + Rect reducedRectForOnlyContentLines = new Rect(rect_ofEnclosingColorSubBox.x + Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields(), rect_ofEnclosingColorSubBox.y + Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields(), rect_ofEnclosingColorSubBox.width - 2.0f * Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields(), rect_ofEnclosingColorSubBox.height - 2.0f * Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields()); + float currentHeightOffset = 0.0f; + float horizShiftOffset_ofIsUsedCheckbox = 7.0f * UnityEditor.EditorGUIUtility.singleLineHeight; + float width_ofCheckBox = 0.75f * UnityEditor.EditorGUIUtility.singleLineHeight; + + DrawHeadline_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, horizShiftOffset_ofIsUsedCheckbox, width_ofCheckBox, isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, anchorHasKinkedJunctureType); + DrawCollapsableArea_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, anchorHasKinkedJunctureType); +#endif + } + + void FillingIsUsedFieldsWithDefaultValues_forInspector() + { + //This is for cases where the fields are not displayed or greyed out. They are used for an "hasChanged"-check afterwards: + isUsed_afterInspectorInput = isUsed; + position_inUnitsOfActiveDrawSpace_afterInspectorInput = position_inUnitsOfActiveDrawSpace; + boundGameobject_afterInspectorInput = boundGameobject; + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput = direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized; + sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture_afterInspectorInput = sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture; + absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput = absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace; + closeGapState_afterInspectorInput = bezierSplineDrawer_thisSubPointIsPartOf.gapFromEndToStart_isClosed; + } + + void DrawBackgroundColor_forInspector(Rect rect_ofEnclosingColorSubBox) + { +#if UNITY_EDITOR + float alphaFactor_ofBackgroundColor = Get_controlPointTriplet_thisSubPointIsPartOf().isHighlighted ? InternalDXXL_BezierControlHelperSubPoint.alpha_ofInspectorBackgroundColor_highlighted : InternalDXXL_BezierControlHelperSubPoint.alpha_ofInspectorBackgroundColor_nonHighlighted; + Color backgroundColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_thisSubPointIsPartOf.color_ofHelperPoints, alphaFactor_ofBackgroundColor); + UnityEditor.EditorGUI.DrawRect(rect_ofEnclosingColorSubBox, backgroundColor); +#endif + } + + void DrawHeadline_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, float horizShiftOffset_ofIsUsedCheckbox, float width_ofCheckBox, bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, bool anchorHasKinkedJunctureType) + { + DrawIsUsedCheckbox_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, horizShiftOffset_ofIsUsedCheckbox, width_ofCheckBox, isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, anchorHasKinkedJunctureType); + TryDrawCloseGapCheckbox_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, width_ofCheckBox); + DrawHeadlineTextWithFoldout_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, horizShiftOffset_ofIsUsedCheckbox, isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, anchorHasKinkedJunctureType); + } + + void DrawIsUsedCheckbox_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, float horizShiftOffset_ofIsUsedCheckbox, float width_ofCheckBox, bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, bool anchorHasKinkedJunctureType) + { +#if UNITY_EDITOR + //no tooltip can be used here because this would require also a mainTextField, which this checkbox doesn't have. Instead the tooltip of the foldout (which also contains the headline text) beside this checkbox is intentionally misused to explain the checkbox meaning. + Rect rect_of_isUsedCheckbox = new Rect(reducedRectForOnlyContentLines.x + horizShiftOffset_ofIsUsedCheckbox, reducedRectForOnlyContentLines.y + currentHeightOffset, width_ofCheckBox, UnityEditor.EditorGUIUtility.singleLineHeight); + if (isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid) + { + //always "off": + UnityEditor.EditorGUI.BeginDisabledGroup(true); + UnityEditor.EditorGUI.Toggle(rect_of_isUsedCheckbox, false); + UnityEditor.EditorGUI.EndDisabledGroup(); + } + else + { + if (anchorHasKinkedJunctureType) + { + isUsed_afterInspectorInput = UnityEditor.EditorGUI.Toggle(rect_of_isUsedCheckbox, GUIContent.none, isUsed); + } + else + { + //always "on": + UnityEditor.EditorGUI.BeginDisabledGroup(true); + UnityEditor.EditorGUI.Toggle(rect_of_isUsedCheckbox, true); + UnityEditor.EditorGUI.EndDisabledGroup(); + } + } +#endif + } + + void TryDrawCloseGapCheckbox_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, float width_ofCheckBox) + { + if (isForward_notBackward) + { + if (Get_controlPointTriplet_thisSubPointIsPartOf().IsLastControlPoint()) + { + DrawCloseGapCheckbox_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, width_ofCheckBox, "Close the gap from this last forward control point of the spline and connect it to the start of the spline to get a closed ring curve."); + } + } + else + { + if (Get_controlPointTriplet_thisSubPointIsPartOf().IsFirstControlPoint()) + { + DrawCloseGapCheckbox_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, width_ofCheckBox, "Close the gap from this first backward control point of the spline and connect it to the end of the spline to get a closed ring curve."); + } + } + } + + void DrawCloseGapCheckbox_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, float width_ofCheckBox, string tooltip) + { +#if UNITY_EDITOR + float width_ofCloseGapLabel = 4.2f * UnityEditor.EditorGUIUtility.singleLineHeight; + + Rect rect_of_closeGapCheckbox = new Rect(reducedRectForOnlyContentLines.x + reducedRectForOnlyContentLines.width - width_ofCheckBox, reducedRectForOnlyContentLines.y + currentHeightOffset, width_ofCheckBox, UnityEditor.EditorGUIUtility.singleLineHeight); + closeGapState_afterInspectorInput = UnityEditor.EditorGUI.Toggle(rect_of_closeGapCheckbox, bezierSplineDrawer_thisSubPointIsPartOf.gapFromEndToStart_isClosed); + + Rect rect_of_closeGapLabel = new Rect(reducedRectForOnlyContentLines.x + reducedRectForOnlyContentLines.width - width_ofCloseGapLabel, reducedRectForOnlyContentLines.y + currentHeightOffset, width_ofCloseGapLabel, UnityEditor.EditorGUIUtility.singleLineHeight); + UnityEditor.EditorGUI.LabelField(rect_of_closeGapLabel, new GUIContent("Close ring", tooltip)); +#endif + } + + void DrawHeadlineTextWithFoldout_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, float horizShiftOffset_ofIsUsedCheckbox, bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, bool anchorHasKinkedJunctureType) + { +#if UNITY_EDITOR + GUIStyle style_ofHeadline = new GUIStyle(UnityEditor.EditorStyles.foldout); + style_ofHeadline.richText = true; + Color color_ofHeadline_nonAccentuated = bezierSplineDrawer_thisSubPointIsPartOf.color_ofHelperPoints; + Color color_ofHeadline_accentuated = ((color_ofHeadline_nonAccentuated.grayscale < 0.175f) ? Color.Lerp(color_ofHeadline_nonAccentuated, Color.white, 0.9f) : Color.Lerp(color_ofHeadline_nonAccentuated, Color.black, 0.7f)); + if (isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid) + { + color_ofHeadline_accentuated = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofHeadline_accentuated, 0.5f); + } + + string headlineText; + if (isForward_notBackward) + { + headlineText = " Forward Weight"; + } + else + { + headlineText = " Backward Weight"; + } + + float horizShiftOffset_ofFoldoutHeadline = 0.65f * UnityEditor.EditorGUIUtility.singleLineHeight; + Rect rect_of_foldoutHeadline = new Rect(reducedRectForOnlyContentLines.x + horizShiftOffset_ofFoldoutHeadline, reducedRectForOnlyContentLines.y + currentHeightOffset, horizShiftOffset_ofIsUsedCheckbox - horizShiftOffset_ofFoldoutHeadline, UnityEditor.EditorGUIUtility.singleLineHeight); + + //the tooltip for the foldoutWithText is intentionally misused here and doesn't explain the foldout itself, but the "isUsed"-checkbox right beside the text + if (isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid) + { + UnityEditor.EditorGUI.BeginDisabledGroup(true); + UnityEditor.EditorGUI.Foldout(rect_of_foldoutHeadline, false, new GUIContent(headlineText, "Only available for closed ring splines."), true, style_ofHeadline); + UnityEditor.EditorGUI.EndDisabledGroup(); + } + else + { + GUIContent guiContent_ofFoldoutHeadline; + if (anchorHasKinkedJunctureType) + { + guiContent_ofFoldoutHeadline = new GUIContent(headlineText); + } + else + { + guiContent_ofFoldoutHeadline = new GUIContent(headlineText, "Can only be deactivated for kinked juncture type."); + } + isOutfoldedInInspector = UnityEditor.EditorGUI.Foldout(rect_of_foldoutHeadline, isOutfoldedInInspector, guiContent_ofFoldoutHeadline, true, style_ofHeadline); + } +#endif + } + + void DrawCollapsableArea_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, bool isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid, bool anchorHasKinkedJunctureType) + { +#if UNITY_EDITOR + if (isOutfoldedInInspector && (isUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid == false)) + { + bool greyOutValues = (isUsed == false); + if (greyOutValues) { UnityEditor.EditorGUI.BeginDisabledGroup(true); } + + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawPositionLine_forInspector(reducedRectForOnlyContentLines, currentHeightOffset); + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawBoundGameobjectLine_forInspector(reducedRectForOnlyContentLines, currentHeightOffset); + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawDirectionLine_forInspector(reducedRectForOnlyContentLines, currentHeightOffset, anchorHasKinkedJunctureType); + currentHeightOffset += UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + DrawDistanceLine_forInspector(reducedRectForOnlyContentLines, currentHeightOffset); + + if (greyOutValues) { UnityEditor.EditorGUI.EndDisabledGroup(); } + } +#endif + } + + void DrawPositionLine_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset) + { +#if UNITY_EDITOR + string label_of_position = "Position"; + if (isUsed) + { + DrawPositionLine_forInspector(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_position, Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector())); + } + else + { + UnityEditor.EditorGUI.Vector2Field(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_position), new Vector2(float.NaN, float.NaN)); + } +#endif + } + + void DrawBoundGameobjectLine_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset) + { +#if UNITY_EDITOR + string label_of_bindToGameobject = "Bind to gameobject"; + if (isUsed) + { + DrawBoundGameobjectLine_forInspector(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_bindToGameobject)); + } + else + { + UnityEditor.EditorGUI.ObjectField(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_bindToGameobject), null, typeof(UnityEngine.GameObject), true); + } +#endif + } + + void DrawDirectionLine_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset, bool anchorHasKinkedJunctureType) + { +#if UNITY_EDITOR + string label_ofDirection; + if (Get_controlPointTriplet_thisSubPointIsPartOf().isHighlighted) + { + label_ofDirection = "Direction from point center to this weight"; + } + else + { + label_ofDirection = "Direction from point center to this weight"; //-> Could adapt the color to the semitransparent triplet main color, but in most cases then the readability is bad. + } + + if (isUsed) + { + string tooltip_ofDirection; + bool anchorHasBoundGameobject = (GetMountingAnchorPoint().boundGameobject != null); //-> could be improved: there is no check whether the "boundGameobject" is "inactive" or the connection component on it is "disabled". + + if (anchorHasBoundGameobject && anchorHasKinkedJunctureType) + { + tooltip_ofDirection = "This line displays the normalized direction from the center point to this weight point." + Environment.NewLine + Environment.NewLine + "For kinked juncture types this direction can be bound individually per weight side to the rotation of the gameobject at the center position." + Environment.NewLine + Environment.NewLine + "Note that the gameobject mentioned in the direction source picker dropdown menu is the gameobject that is bound to the CENTER position, not the one bound to this WEIGHT position." + Environment.NewLine + Environment.NewLine + Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector(); + } + else + { + tooltip_ofDirection = "This is normalized. " + Environment.NewLine + "Value input will be changed so that the overall vector stays normalized." + Environment.NewLine + Environment.NewLine + Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector(); + } + + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput = Draw_Vector2Field_withoutLineBreak_forInspector(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), out Rect rectForOnlyThePrefixLabel, new GUIContent(label_ofDirection, tooltip_ofDirection), direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized, true); + + if (anchorHasBoundGameobject && anchorHasKinkedJunctureType) + { + float portionOPrefixLabelSpace_thatIsFilledByEnumPopup = 1.0f; + Rect rect_forDirectionSourceEnumPopup = new Rect(rectForOnlyThePrefixLabel.x + (1.0f - portionOPrefixLabelSpace_thatIsFilledByEnumPopup) * rectForOnlyThePrefixLabel.width, rectForOnlyThePrefixLabel.y, rectForOnlyThePrefixLabel.width * portionOPrefixLabelSpace_thatIsFilledByEnumPopup, UnityEditor.EditorGUIUtility.singleLineHeight); + + InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers wordedDirectionSource_beforeInput = InternalDXXL_BezierControlAnchorSubPoint2D.ConvertDirectionSource_fromUsedVersion_toWordedVersion(sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture); + InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers wordedDirectionSource_afterInput = (InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D_wordedForInspectorDisplayAtHelpers)UnityEditor.EditorGUI.EnumPopup(rect_forDirectionSourceEnumPopup, GUIContent.none, wordedDirectionSource_beforeInput); + sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture_afterInspectorInput = InternalDXXL_BezierControlAnchorSubPoint2D.ConvertDirectionSource_fromWordedVersion_toUsedVersion(wordedDirectionSource_afterInput); + } + } + else + { + UnityEditor.EditorGUI.Vector2Field(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), label_ofDirection, new Vector2(float.NaN, float.NaN)); + } +#endif + } + + void DrawDistanceLine_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset) + { +#if UNITY_EDITOR + string label_of_distance = "Distance"; + if (isUsed) + { + absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput = UnityEditor.EditorGUI.FloatField(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_distance, Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector()), absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace); + } + else + { + UnityEditor.EditorGUI.FloatField(RecalcCurrentRect_forInspector(reducedRectForOnlyContentLines, currentHeightOffset), new GUIContent(label_of_distance), float.NaN); + } +#endif + } + + public bool TryApplyChangesAfterInspectorInput() + { + //The checks here are more reliable than "EditorGUI.BeginChangeCheck/EndChangeCheck()", which also reports "change" only due to mouse selection, even when the value didn't change yet. + + if (isUsed_afterInspectorInput != isUsed) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Toggle Spline Weight", false, false); + ChangeUsedState(isUsed_afterInspectorInput, true); + return true; + } + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreExactlyEqual(position_inUnitsOfActiveDrawSpace_afterInspectorInput, position_inUnitsOfActiveDrawSpace) == false) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Position", true, true); + SetPos_inUnitsOfActiveDrawSpace(position_inUnitsOfActiveDrawSpace_afterInspectorInput, true, null); + return true; + } + + if (boundGameobject_afterInspectorInput != boundGameobject) + { + //bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Gameobject Ref", true, true); //not needed here, because it is cared for inside "ProcessNewGameobjectAssignment" + ProcessNewGameobjectAssignment(boundGameobject_afterInspectorInput); + return true; + } + + if (direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput != direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Direction", true, true); + direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput.Normalize(); + Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfActiveDrawSpace_normalized(direction_toThisHelper_fromAnchor_inUnitsOfActiveDrawSpace_normalized_afterInspectorInput, true, null); + return true; + } + + if (sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture_afterInspectorInput != sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture) + { + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Direction Source", true, true); + ProcessChanging_sourceOfDirectionFromAnchor(sourceOf_directionFromAnchorToThisHelper_caseKinkedJuncture_afterInspectorInput); + return true; + } + + if (absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput != absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace) + { + absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput = Mathf.Max(absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput, 0.0f); + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo("Change Spline Distance", true, true); + Set_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace_afterInspectorInput, true, null); + return true; + } + + if (closeGapState_afterInspectorInput != bezierSplineDrawer_thisSubPointIsPartOf.gapFromEndToStart_isClosed) + { + bezierSplineDrawer_thisSubPointIsPartOf.ChangeCloseGapState(closeGapState_afterInspectorInput); + return true; + } + + return false; + } + + public override float GetPropertyHeightForInspectorList() + { +#if UNITY_EDITOR + if (isOutfoldedInInspector && (IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid() == false)) + { + float height_forAllContentLines = 5.0f * UtilitiesDXXL_Components.Get_inspector_singleLineHeightInclSpacingBetweenLines(); + return (Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields() + height_forAllContentLines + Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields()); + } + else + { + return (Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields() + UnityEditor.EditorGUIUtility.singleLineHeight + Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields()); + } +#else + return 16.0f; //-> not used +#endif + } + + public static float Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields() + { +#if UNITY_EDITOR + return (0.2f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint2D.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint2D.cs.meta new file mode 100644 index 0000000..91daa68 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlHelperSubPoint2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ad7d7ad7f6e25d744a6e1788d616441c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet.cs new file mode 100644 index 0000000..c3fe6a4 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet.cs @@ -0,0 +1,796 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + + [Serializable] + public class InternalDXXL_BezierControlPointTriplet + { + public static float alpha_ofInspectorBackgroundColor_highlighted = 1.0f; + public static float alpha_ofInspectorBackgroundColor_nonHighlighted = 0.5f; + + public bool isHighlighted; + public int i_ofThisPoint_insideControlPointsList; + public BezierSplineDrawer bezierSplineDrawer_thisPointIsPartOf; + + [SerializeField] public bool alignedHelperPoints_areOnTheSameSideOfTheAnchor; + [SerializeField] public float progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + + public InternalDXXL_BezierControlAnchorSubPoint anchorPoint; + public InternalDXXL_BezierControlHelperSubPoint forwardHelperPoint; + public InternalDXXL_BezierControlHelperSubPoint backwardHelperPoint; + + InternalDXXL_BezierPointShapeConfig pointShape_afterSpaceChange_inUnitsOfGlobalSpace; + InternalDXXL_BezierPointShapeConfig pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace; + + public Rect inspectorRect_reservedForThisTriplet; + public bool minusButtonAtThisListItem_hasBeenClickedInInspector = false; + + public void Initialize(BezierSplineDrawer containingSplineDrawer, Vector3 initialPos_inUnitsOfGlobalSpace, Vector3 initialForwardDir_inUnitsOfGlobalSpace_normalized, InternalDXXL_BezierControlAnchorSubPoint.JunctureType junctureType) + { + bezierSplineDrawer_thisPointIsPartOf = containingSplineDrawer; + + isHighlighted = false; //-> the caller has to decide whether and take care of highlighting newly created control points after this initialization + + alignedHelperPoints_areOnTheSameSideOfTheAnchor = false; + progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment = 0.5f; + + anchorPoint = new InternalDXXL_BezierControlAnchorSubPoint(); + anchorPoint.InitializeValuesThatAreIndependentFromOtherSubPoints(this); + anchorPoint.subPointType = InternalDXXL_BezierControlSubPoint.SubPointType.anchor; + anchorPoint.isUsed = true; + anchorPoint.junctureType = junctureType; + anchorPoint.SetPos_inUnitsOfGlobalSpace(initialPos_inUnitsOfGlobalSpace, false, null); + + forwardHelperPoint = new InternalDXXL_BezierControlHelperSubPoint(); + forwardHelperPoint.InitializeValuesThatAreIndependentFromOtherSubPoints(this); + forwardHelperPoint.subPointType = InternalDXXL_BezierControlSubPoint.SubPointType.forwardHelper; + forwardHelperPoint.isForward_notBackward = true; + forwardHelperPoint.isUsed = true; + forwardHelperPoint.Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(initialForwardDir_inUnitsOfGlobalSpace_normalized, false, null); + float initial_forwardWeightDistance_inUnitsOfGlobalSpace = bezierSplineDrawer_thisPointIsPartOf.TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(bezierSplineDrawer_thisPointIsPartOf.forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace); + Vector3 initialPos_ofForwardHelperPoint_inUnitsOfGlobalSpace = initialPos_inUnitsOfGlobalSpace + initialForwardDir_inUnitsOfGlobalSpace_normalized * initial_forwardWeightDistance_inUnitsOfGlobalSpace; + forwardHelperPoint.SetPos_inUnitsOfGlobalSpace(initialPos_ofForwardHelperPoint_inUnitsOfGlobalSpace, false, null); + forwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(initial_forwardWeightDistance_inUnitsOfGlobalSpace, false, null); + + backwardHelperPoint = new InternalDXXL_BezierControlHelperSubPoint(); + backwardHelperPoint.InitializeValuesThatAreIndependentFromOtherSubPoints(this); + backwardHelperPoint.subPointType = InternalDXXL_BezierControlSubPoint.SubPointType.backwardHelper; + backwardHelperPoint.isForward_notBackward = false; + backwardHelperPoint.isUsed = true; + backwardHelperPoint.Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(-initialForwardDir_inUnitsOfGlobalSpace_normalized, false, null); + float initial_backwardWeightDistance_inUnitsOfGlobalSpace = bezierSplineDrawer_thisPointIsPartOf.TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(bezierSplineDrawer_thisPointIsPartOf.backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace); + Vector3 initialPos_ofBackwardHelperPoint_inUnitsOfGlobalSpace = initialPos_inUnitsOfGlobalSpace - initialForwardDir_inUnitsOfGlobalSpace_normalized * initial_backwardWeightDistance_inUnitsOfGlobalSpace; + backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(initialPos_ofBackwardHelperPoint_inUnitsOfGlobalSpace, false, null); + backwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(initial_backwardWeightDistance_inUnitsOfGlobalSpace, false, null); + } + + public void ReassignIndexInsideControlPointsList(int new_i) + { + i_ofThisPoint_insideControlPointsList = new_i; + + if (anchorPoint != null) //-> skipping newly created points (whose sub points don't exist yet). They get the value in the "controlPointTriplet.Initialize()" function + { + anchorPoint.ReassignIndexInsideControlPointsList(new_i); + } + + if (forwardHelperPoint != null) //-> skipping newly created points (whose sub points don't exist yet). They get the value in the "controlPointTriplet.Initialize()" function + { + forwardHelperPoint.ReassignIndexInsideControlPointsList(new_i); + } + + if (backwardHelperPoint != null) //-> skipping newly created points (whose sub points don't exist yet). They get the value in the "controlPointTriplet.Initialize()" function + { + backwardHelperPoint.ReassignIndexInsideControlPointsList(new_i); + } + } + + public InternalDXXL_BezierControlHelperSubPoint GetAHelperPoint(bool requestedHelperPoint_isForward_notBackward) + { + if (requestedHelperPoint_isForward_notBackward) + { + return forwardHelperPoint; + } + else + { + return backwardHelperPoint; + } + } + + public InternalDXXL_BezierControlSubPoint GetASubPoint(InternalDXXL_BezierControlSubPoint.SubPointType typeOfRequestedSubPoint) + { + switch (typeOfRequestedSubPoint) + { + case InternalDXXL_BezierControlSubPoint.SubPointType.backwardHelper: + return backwardHelperPoint; + case InternalDXXL_BezierControlSubPoint.SubPointType.anchor: + return anchorPoint; + case InternalDXXL_BezierControlSubPoint.SubPointType.forwardHelper: + return forwardHelperPoint; + default: + return anchorPoint; + } + } + + public bool IsFirstControlPoint() + { + return bezierSplineDrawer_thisPointIsPartOf.IsFirstControlPoint(this); + } + + public bool IsLastControlPoint() + { + return bezierSplineDrawer_thisPointIsPartOf.IsLastControlPoint(this); + } + + public InternalDXXL_BezierControlPointTriplet GetNextControlPointTripletAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return bezierSplineDrawer_thisPointIsPartOf.GetNextControlPointTriplet(this, allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + + public InternalDXXL_BezierControlPointTriplet GetPreviousControlPointTripletAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return bezierSplineDrawer_thisPointIsPartOf.GetPreviousControlPointTriplet(this, allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + + public void Save_currentPosConfigInUnitsOfGlobalSpace_as_posConfigAfterSpaceChangeInUnitsOfGlobalSpace() + { + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.anchorPos = anchorPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toForward_normalized = anchorPoint.Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toBackward_normalized = anchorPoint.Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.forwardHelperPos = forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToForwardAnchorPoint = forwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.backwardHelperPos = backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToBackwardAnchorPoint = backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + } + + public void Save_currentPosConfigInUnitsOfActiveDrawSpace_as_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace() + { + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.anchorPos = anchorPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toForward_normalized = anchorPoint.Get_direction_toForward_inUnitsOfActiveDrawSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toBackward_normalized = anchorPoint.Get_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.forwardHelperPos = forwardHelperPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToForwardAnchorPoint = forwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.backwardHelperPos = backwardHelperPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToBackwardAnchorPoint = backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + } + + public void Save_currentPosConfigInUnitsOfActiveDrawSpace_as_posConfigAfterSpaceChangeInUnitsOfGlobalSpace() + { + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.anchorPos = anchorPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toForward_normalized = anchorPoint.Get_direction_toForward_inUnitsOfActiveDrawSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toBackward_normalized = anchorPoint.Get_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.forwardHelperPos = forwardHelperPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToForwardAnchorPoint = forwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.backwardHelperPos = backwardHelperPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToBackwardAnchorPoint = backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + } + + public void Save_currentPosConfigInUnitsOfGlobalSpace_as_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace() + { + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.anchorPos = anchorPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toForward_normalized = anchorPoint.Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toBackward_normalized = anchorPoint.Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.forwardHelperPos = forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToForwardAnchorPoint = forwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.backwardHelperPos = backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToBackwardAnchorPoint = backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + } + + public void ApplySaved_posConfigAfterSpaceChangeInUnitsOfGlobalSpace() + { + anchorPoint.SetPos_inUnitsOfGlobalSpace(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.anchorPos, false, null); + anchorPoint.Set_direction_toForward_inUnitsOfGlobalSpace_normalized(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toForward_normalized, false, null); + anchorPoint.Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toBackward_normalized, false, null); + forwardHelperPoint.SetPos_inUnitsOfGlobalSpace(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.forwardHelperPos, false, null); + forwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToForwardAnchorPoint, false, null); + backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.backwardHelperPos, false, null); + backwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToBackwardAnchorPoint, false, null); + } + + public void ApplySaved_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace() + { + anchorPoint.SetPos_inUnitsOfActiveDrawSpace(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.anchorPos, false, null); + anchorPoint.Set_direction_toForward_inUnitsOfActiveDrawSpace_normalized(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toForward_normalized, false, null); + anchorPoint.Set_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toBackward_normalized, false, null); + forwardHelperPoint.SetPos_inUnitsOfActiveDrawSpace(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.forwardHelperPos, false, null); + forwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToForwardAnchorPoint, false, null); + backwardHelperPoint.SetPos_inUnitsOfActiveDrawSpace(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.backwardHelperPos, false, null); + backwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToBackwardAnchorPoint, false, null); + } + + public bool IsEndPointToVoid_atStartOrEndOfAnUnclosedSpline() + { + if (bezierSplineDrawer_thisPointIsPartOf.gapFromEndToStart_isClosed == false) + { + if (IsFirstControlPoint() || IsLastControlPoint()) + { + return true; + } + } + return false; + } + + public bool IsPartOfThisTriplet(InternalDXXL_BezierControlSubPoint subPointToCheckIfItIsPartOfThisTriplet) + { + if (subPointToCheckIfItIsPartOfThisTriplet == backwardHelperPoint) + { + return true; + } + + if (subPointToCheckIfItIsPartOfThisTriplet == anchorPoint) + { + return true; + } + + if (subPointToCheckIfItIsPartOfThisTriplet == forwardHelperPoint) + { + return true; + } + + return false; + } + + public bool CheckIf_foldableHelperPoints_areUnfolded_inTheInspectorList() + { + if (backwardHelperPoint.IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + //-> not foldable + } + else + { + if (backwardHelperPoint.isOutfoldedInInspector == false) + { + return false; + } + } + + if (forwardHelperPoint.IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + //-> not foldable + } + else + { + if (forwardHelperPoint.isOutfoldedInInspector == false) + { + return false; + } + } + return true; + } + + public bool CheckIf_foldableHelperPoints_areCollapsed_inTheInspectorList() + { + if (backwardHelperPoint.IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + //-> not foldable + } + else + { + if (backwardHelperPoint.isOutfoldedInInspector) + { + return false; + } + } + + if (forwardHelperPoint.IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + //-> not foldable + } + else + { + if (forwardHelperPoint.isOutfoldedInInspector) + { + return false; + } + } + return true; + } + + public void UnfoldBothHelperPointInTheInspectorList() + { + backwardHelperPoint.isOutfoldedInInspector = true; + forwardHelperPoint.isOutfoldedInInspector = true; + } + + public void CollapseBothHelperPointInTheInspectorList() + { + backwardHelperPoint.isOutfoldedInInspector = false; + forwardHelperPoint.isOutfoldedInInspector = false; + } + + public Vector3 GetPosAtPlusButton_onUpcomingBezierSegment_inUnitsOfGlobalSpace() + { + return GetAPos_onUpcomingBezierSegment_inUnitsOfGlobalSpace(progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment); + } + + public Vector3 GetAPos_onUpcomingBezierSegment_inUnitsOfGlobalSpace(float progress0to1_inUpcomingBezierSegment) + { + InternalDXXL_BezierControlPointTriplet nextControlPointTriplet = GetNextControlPointTripletAlongSplineDir(true); + if (nextControlPointTriplet == null) + { + return anchorPoint.GetPos_inUnitsOfGlobalSpace(); + } + else + { + Vector3 segmentStartPos = anchorPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 segmentEndPos = nextControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace(); + if (forwardHelperPoint.isUsed == true) + { + Vector3 firstControlPosInBetween = forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + if (nextControlPointTriplet.backwardHelperPoint.isUsed == true) + { + Vector3 secondControlPosInBetween = nextControlPointTriplet.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + return GetPos_onCubicBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, firstControlPosInBetween, secondControlPosInBetween, segmentEndPos); + } + else + { + return GetPos_onQuadraticBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, firstControlPosInBetween, segmentEndPos); + } + } + else + { + if (nextControlPointTriplet.backwardHelperPoint.isUsed == true) + { + Vector3 theSingleControlPosInBetween = nextControlPointTriplet.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + return GetPos_onQuadraticBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, theSingleControlPosInBetween, segmentEndPos); + } + else + { + //straight line: + Vector3 fromStart_toEnd = segmentEndPos - segmentStartPos; + return (segmentStartPos + fromStart_toEnd * progress0to1_inUpcomingBezierSegment); + } + } + } + } + + Vector3 GetPos_onQuadraticBezierSegment(float progress_0to1, Vector3 segmentStartPos, Vector3 controlPosInBetween, Vector3 segmentEndPos) + { + float oneMinusProgress0to1 = 1.0f - progress_0to1; + float factor1 = oneMinusProgress0to1 * oneMinusProgress0to1; + float factor2 = 2.0f * oneMinusProgress0to1 * progress_0to1; + float factor3 = progress_0to1 * progress_0to1; + return (factor1 * segmentStartPos + factor2 * controlPosInBetween + factor3 * segmentEndPos); + } + + Vector3 GetPos_onCubicBezierSegment(float progress_0to1, Vector3 segmentStartPos, Vector3 firstControlPosInBetween, Vector3 secondControlPosInBetween, Vector3 segmentEndPos) + { + float progress_0to1_sqr = progress_0to1 * progress_0to1; + float oneMinusProgress0to1 = 1.0f - progress_0to1; + float oneMinusProgress0to1_sqr = oneMinusProgress0to1 * oneMinusProgress0to1; + float factor1 = oneMinusProgress0to1 * oneMinusProgress0to1_sqr; + float factor2 = 3.0f * oneMinusProgress0to1_sqr * progress_0to1; + float factor3 = 3.0f * oneMinusProgress0to1 * progress_0to1_sqr; + float factor4 = progress_0to1 * progress_0to1_sqr; + return (factor1 * segmentStartPos + factor2 * firstControlPosInBetween + factor3 * secondControlPosInBetween + factor4 * segmentEndPos); + } + + public Vector3 GetTangentAtPlusButton_onUpcomingBezierSegment_inUnitsOfGlobalSpace(bool normalized) + { + return GetATangent_onUpcomingBezierSegment_inUnitsOfGlobalSpace(progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment, normalized); + } + + public Vector3 GetATangent_onUpcomingBezierSegment_inUnitsOfGlobalSpace(float progress0to1_inUpcomingBezierSegment, bool normalized) + { + InternalDXXL_BezierControlPointTriplet nextControlPointTriplet = GetNextControlPointTripletAlongSplineDir(true); + if (nextControlPointTriplet == null) + { + return bezierSplineDrawer_thisPointIsPartOf.Get_forwardTangent_ofControlPointThatDoesntKnowOfANextOne_inUnitsOfGlobalSpace_normalized(this); + } + else + { + Vector3 tangent_notNormalized; + + Vector3 segmentStartPos = anchorPoint.GetPos_inUnitsOfGlobalSpace(); + Vector3 segmentEndPos = nextControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace(); + if (forwardHelperPoint.isUsed == true) + { + Vector3 firstControlPosInBetween = forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + if (nextControlPointTriplet.backwardHelperPoint.isUsed == true) + { + Vector3 secondControlPosInBetween = nextControlPointTriplet.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + tangent_notNormalized = GetTangent_onCubicBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, firstControlPosInBetween, secondControlPosInBetween, segmentEndPos); + } + else + { + tangent_notNormalized = GetTangent_onQuadraticBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, firstControlPosInBetween, segmentEndPos); + } + } + else + { + if (nextControlPointTriplet.backwardHelperPoint.isUsed == true) + { + Vector3 theSingleControlPosInBetween = nextControlPointTriplet.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + tangent_notNormalized = GetTangent_onQuadraticBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, theSingleControlPosInBetween, segmentEndPos); + } + else + { + //straight line: + Vector3 fromStart_toEnd = segmentEndPos - segmentStartPos; + if (UtilitiesDXXL_Math.ApproximatelyZero(fromStart_toEnd)) + { + return bezierSplineDrawer_thisPointIsPartOf.Get_forwardTangent_ofControlPointThatDoesntKnowOfANextOne_inUnitsOfGlobalSpace_normalized(this); + } + else + { + tangent_notNormalized = fromStart_toEnd; + } + } + } + + if (normalized) + { + Vector3 tangent_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(tangent_notNormalized); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(tangent_normalized)) + { + return bezierSplineDrawer_thisPointIsPartOf.Get_forward_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + else + { + return tangent_normalized; + } + } + else + { + return tangent_notNormalized; + } + } + } + + Vector3 GetTangent_onQuadraticBezierSegment(float progress_0to1, Vector3 segmentStartPos, Vector3 controlPosInBetween, Vector3 segmentEndPos) + { + return (2.0f * (1.0f - progress_0to1) * (controlPosInBetween - segmentStartPos) + 2.0f * progress_0to1 * (segmentEndPos - controlPosInBetween)); + } + + Vector3 GetTangent_onCubicBezierSegment(float progress_0to1, Vector3 segmentStartPos, Vector3 firstControlPosInBetween, Vector3 secondControlPosInBetween, Vector3 segmentEndPos) + { + float progress_0to1_sqr = progress_0to1 * progress_0to1; + float oneMinusProgress0to1 = 1.0f - progress_0to1; + return (3.0f * oneMinusProgress0to1 * oneMinusProgress0to1 * (firstControlPosInBetween - segmentStartPos) + (6.0f * oneMinusProgress0to1 * progress_0to1) * (secondControlPosInBetween - firstControlPosInBetween) + 3.0f * progress_0to1_sqr * (segmentEndPos - secondControlPosInBetween)); + } + + public void Invert_alignedHelperPoints_areOnTheSameSideOfTheAnchor() + { + alignedHelperPoints_areOnTheSameSideOfTheAnchor = !alignedHelperPoints_areOnTheSameSideOfTheAnchor; + } + + public void DrawValuesToInspector() + { + TryHighlightThisControlPoint_dueToMouseClickOnItInInspector(); + DrawBackgroundArea_forInspector(); + DrawSubPoints_forInspector(); + } + + void TryHighlightThisControlPoint_dueToMouseClickOnItInInspector() + { + Event currentEvent = Event.current; + if (currentEvent.type == EventType.MouseDown) + { + if (inspectorRect_reservedForThisTriplet.Contains(currentEvent.mousePosition)) + { + bezierSplineDrawer_thisPointIsPartOf.SetSelectedListSlot(i_ofThisPoint_insideControlPointsList); + bezierSplineDrawer_thisPointIsPartOf.SheduleSceneViewRepaint(); + } + } + } + + void DrawBackgroundArea_forInspector() + { + Rect space_ofBigBackgroundColorRect = new Rect(Get_xPos_ofBackgroundRect(inspectorRect_reservedForThisTriplet), Get_yPos_ofBackgroundRect(inspectorRect_reservedForThisTriplet), Get_width_ofBackgroundRect(inspectorRect_reservedForThisTriplet), inspectorRect_reservedForThisTriplet.height - 2.0f * Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() - Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint()); + float alphaFactor_ofBackgroundColor = isHighlighted ? alpha_ofInspectorBackgroundColor_highlighted : alpha_ofInspectorBackgroundColor_nonHighlighted; + Color backgroundColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_thisPointIsPartOf.color_ofAnchorPoints, alphaFactor_ofBackgroundColor); + + DrawBackgroundColor_forInspector(space_ofBigBackgroundColorRect, backgroundColor); + + //See also "Get_xPos_ofPlusAndMinusButtonRect()": + //float y_of_minusButton = position.y + position.height - inspectorVertSpace_from_mainRect_to_backgroundColorBox - inspectorVertSpace_ofMinusButtonOnEachControlPoint; //-> float calculation imprecision errors seems to introduce overlap offsets of 1 pixel when calculated like this + //float y_of_minusButton = space_ofBigBackgroundColorRect.y + space_ofBigBackgroundColorRect.height; //-> this also is not solving the 1 pixel overlap offset + //float y_of_minusButton = space_ofBigBackgroundColorRect.yMax; //-> this also is not solving the 1 pixel overlap offset + float y_of_minusButton = space_ofBigBackgroundColorRect.yMax + 1.0f; //-> fixing it manually (with the risk of adding an empty pixel line if there are situations where the problem doesn't occur) + + DrawMinusButton_forInspector(backgroundColor, y_of_minusButton); + DrawIndexNumber_forInspector(backgroundColor, y_of_minusButton); + } + + void DrawBackgroundColor_forInspector(Rect space_ofBigBackgroundColorRect, Color backgroundColor) + { +#if UNITY_EDITOR + UnityEditor.EditorGUI.DrawRect(space_ofBigBackgroundColorRect, backgroundColor); +#endif + } + + void DrawMinusButton_forInspector(Color backgroundColor, float y_of_minusButton) + { +#if UNITY_EDITOR + Rect space_ofMinusButtonBackground = new Rect(Get_xPos_ofPlusAndMinusButtonRect(inspectorRect_reservedForThisTriplet), y_of_minusButton, Get_width_ofPlusAndMinusButtons(), Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint()); + UnityEditor.EditorGUI.DrawRect(space_ofMinusButtonBackground, backgroundColor); + + GUIContent minusSymbolIcon = UnityEditor.EditorGUIUtility.TrIconContent("Toolbar Minus", "Delete control point"); + GUIStyle style_ofMinusButton = "RL FooterButton"; + minusButtonAtThisListItem_hasBeenClickedInInspector = GUI.Button(space_ofMinusButtonBackground, minusSymbolIcon, style_ofMinusButton); +#endif + } + + void DrawIndexNumber_forInspector(Color backgroundColor, float y_of_minusButton) + { +#if UNITY_EDITOR + float horizSpace_betweenSlotIndexNumber_and_minusButton = 0.5f * UnityEditor.EditorGUIUtility.singleLineHeight; + float horizPadding_besideIndexNumberInsideNumberRect_perSide = 0.5f * UnityEditor.EditorGUIUtility.singleLineHeight; + float horizPadding_besideIndexNumberInsideNumberRect_forBothSides = 2.0f * horizPadding_besideIndexNumberInsideNumberRect_perSide; + float width_perNumberDigit = 0.6f * UnityEditor.EditorGUIUtility.singleLineHeight; + float width_ofSlotIndexNumberRect = horizPadding_besideIndexNumberInsideNumberRect_forBothSides + width_perNumberDigit * GetNumberOfDigitsInIndexNumber(); + Rect space_ofSlotIndexNumberBackground = new Rect(inspectorRect_reservedForThisTriplet.x + inspectorRect_reservedForThisTriplet.width - Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() - Get_width_ofPlusAndMinusButtons() - horizSpace_betweenSlotIndexNumber_and_minusButton - width_ofSlotIndexNumberRect, y_of_minusButton, width_ofSlotIndexNumberRect, Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint()); + UnityEditor.EditorGUI.DrawRect(space_ofSlotIndexNumberBackground, backgroundColor); + + GUIStyle style_ofNumber = new GUIStyle(); + Color color_ofNumber; + if (isHighlighted) + { + color_ofNumber = UtilitiesDXXL_Colors.GetSimilarColorWithOtherBrightnessValue(bezierSplineDrawer_thisPointIsPartOf.color_ofAnchorPoints, 0.375f); + } + else + { + color_ofNumber = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_thisPointIsPartOf.color_ofAnchorPoints, 0.725f); + } + + string textString_ofNumber = "" + i_ofThisPoint_insideControlPointsList + ""; + float y_offset_ofSlotIndexNumber = -0.1f * UnityEditor.EditorGUIUtility.singleLineHeight; + Rect space_ofSlotIndexNumber = new Rect(space_ofSlotIndexNumberBackground.x + horizPadding_besideIndexNumberInsideNumberRect_perSide, space_ofSlotIndexNumberBackground.y + y_offset_ofSlotIndexNumber, space_ofSlotIndexNumberBackground.width - horizPadding_besideIndexNumberInsideNumberRect_forBothSides, space_ofSlotIndexNumberBackground.height); + UnityEditor.EditorGUI.LabelField(space_ofSlotIndexNumber, textString_ofNumber, style_ofNumber); +#endif + } + + int GetNumberOfDigitsInIndexNumber() + { + if (i_ofThisPoint_insideControlPointsList >= 10000) + { + return 5; + } + else + { + if (i_ofThisPoint_insideControlPointsList >= 1000) + { + return 4; + } + else + { + if (i_ofThisPoint_insideControlPointsList >= 100) + { + return 3; + } + else + { + if (i_ofThisPoint_insideControlPointsList >= 10) + { + return 2; + } + else + { + return 1; + } + } + } + } + } + + void DrawSubPoints_forInspector() + { + float height_ofBackwardHelper = backwardHelperPoint.GetPropertyHeightForInspectorList(); + float height_ofAnchor = anchorPoint.GetPropertyHeightForInspectorList(); + float height_ofForwardHelper = forwardHelperPoint.GetPropertyHeightForInspectorList(); + + float x_ofHelperPointsColorBox = inspectorRect_reservedForThisTriplet.x + Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge(); + float width_ofHelperPointsColorBox = inspectorRect_reservedForThisTriplet.width - 2.0f * Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() - 2.0f * Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge(); + + float currentHeightOffset = 0.0f; + currentHeightOffset += Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox(); + currentHeightOffset += Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge(); + + Rect rect_of_backwardHelperPoint = new Rect(x_ofHelperPointsColorBox, inspectorRect_reservedForThisTriplet.y + currentHeightOffset, width_ofHelperPointsColorBox, height_ofBackwardHelper); + + currentHeightOffset += height_ofBackwardHelper; + currentHeightOffset += Get_inspectorVertSpace_betweenSubPoints(); + + float x_ofAnchorPointsSubProperty = inspectorRect_reservedForThisTriplet.x + Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge() + InternalDXXL_BezierControlHelperSubPoint.Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields(); + float width_ofAnchorPointsSubProperty = inspectorRect_reservedForThisTriplet.width - 2.0f * Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() - 2.0f * Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge() - 2.0f * InternalDXXL_BezierControlHelperSubPoint.Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields(); + Rect rect_of_anchorPoint = new Rect(x_ofAnchorPointsSubProperty, inspectorRect_reservedForThisTriplet.y + currentHeightOffset, width_ofAnchorPointsSubProperty, height_ofAnchor); + + currentHeightOffset += height_ofAnchor; + currentHeightOffset += Get_inspectorVertSpace_betweenSubPoints(); + + Rect rect_of_forwardHelperPoint = new Rect(x_ofHelperPointsColorBox, inspectorRect_reservedForThisTriplet.y + currentHeightOffset, width_ofHelperPointsColorBox, height_ofForwardHelper); + + backwardHelperPoint.DrawValuesToInspector(rect_of_backwardHelperPoint); + anchorPoint.DrawValuesToInspector(rect_of_anchorPoint); + forwardHelperPoint.DrawValuesToInspector(rect_of_forwardHelperPoint); + } + + public bool TryApplyChangesAfterInspectorInput() + { + bool didChangeSomething; + + didChangeSomething = backwardHelperPoint.TryApplyChangesAfterInspectorInput(); + if (didChangeSomething) { return true; } + + didChangeSomething = anchorPoint.TryApplyChangesAfterInspectorInput(); + if (didChangeSomething) { return true; } + + didChangeSomething = forwardHelperPoint.TryApplyChangesAfterInspectorInput(); + if (didChangeSomething) { return true; } + + return false; + } + + public float GetPropertyHeightForInspectorList() + { + float height_ofBackwardHelper = backwardHelperPoint.GetPropertyHeightForInspectorList(); + float height_ofAnchor = anchorPoint.GetPropertyHeightForInspectorList(); + float height_ofForwardHelper = forwardHelperPoint.GetPropertyHeightForInspectorList(); + float additionalHeight = Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge() + Get_inspectorVertSpace_betweenSubPoints() + Get_inspectorVertSpace_betweenSubPoints() + Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge() + Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint() + Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox(); + + return (height_ofBackwardHelper + height_ofAnchor + height_ofForwardHelper + additionalHeight); + } + + public static void DrawEmptyControlPointHoldingOnlyAPlusButton_forInspector(out bool plusButtonBelowListOfControlPoints_hasBeenClicked, out bool unfoldAllWeightsBelowListOfControlPoints_hasBeenClicked, out bool collapseAllWeightsBelowListOfControlPoints_hasBeenClicked, Rect position, Color color_ofAnchorPoints, GUIContent plusSymbolIcon, bool greyOutUnfoldAllButton, bool greyOutCollapseAllButton) + { +#if UNITY_EDITOR + Color backgroundColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofAnchorPoints, alpha_ofInspectorBackgroundColor_nonHighlighted); + + Rect rect_ofEmptyLine = new Rect(Get_xPos_ofBackgroundRect(position), Get_yPos_ofBackgroundRect(position), Get_width_ofBackgroundRect(position), Get_inspectorVertSpace_ofEmptyLineOfEmptyControlPointHoldingOnlyAPlusButton()); + UnityEditor.EditorGUI.DrawRect(rect_ofEmptyLine, backgroundColor); + + Rect rect_ofPlusButtonBelowEmptyLine = new Rect(Get_xPos_ofPlusAndMinusButtonRect(position), position.y + Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorVertSpace_ofEmptyLineOfEmptyControlPointHoldingOnlyAPlusButton(), Get_width_ofPlusAndMinusButtons(), Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint()); + UnityEditor.EditorGUI.DrawRect(rect_ofPlusButtonBelowEmptyLine, backgroundColor); + + GUIStyle style_ofMinusButton = "RL FooterButton"; + plusButtonBelowListOfControlPoints_hasBeenClicked = GUI.Button(rect_ofPlusButtonBelowEmptyLine, plusSymbolIcon, style_ofMinusButton); + + Rect rect_ofBothFoldAllButtons = new Rect(Get_xPos_ofBackgroundRect(position), position.y + Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorVertSpace_ofEmptyLineOfEmptyControlPointHoldingOnlyAPlusButton() + Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint() + Get_additionalInspectorVertSpace_belowEmptyPlusLine_tillFoldAllButtons(), Get_width_ofBackgroundRect(position), Get_inspectorVertSpace_forFoldAllButtons()); + + float halfHorizSpaceBetweenButtons = 0.5f * Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox(); + Rect rect_ofUnfoldAllButton = new Rect(rect_ofBothFoldAllButtons.x, rect_ofBothFoldAllButtons.y, rect_ofBothFoldAllButtons.width * 0.5f - halfHorizSpaceBetweenButtons, rect_ofBothFoldAllButtons.height); + Rect rect_ofCollapseAllButton = new Rect(rect_ofBothFoldAllButtons.x + rect_ofBothFoldAllButtons.width * 0.5f + halfHorizSpaceBetweenButtons, rect_ofBothFoldAllButtons.y, rect_ofBothFoldAllButtons.width * 0.5f - halfHorizSpaceBetweenButtons, rect_ofBothFoldAllButtons.height); + + GUIStyle style_ofUnfoldAllButtons = new GUIStyle(style_ofMinusButton); + style_ofUnfoldAllButtons.fontStyle = FontStyle.Normal; + Color color_ofAGreyedOut_foldAllButton = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(backgroundColor, 0.5f); + + Color color_ofUnfoldAllButton = greyOutUnfoldAllButton ? color_ofAGreyedOut_foldAllButton : backgroundColor; + UnityEditor.EditorGUI.DrawRect(rect_ofUnfoldAllButton, color_ofUnfoldAllButton); + UnityEditor.EditorGUI.BeginDisabledGroup(greyOutUnfoldAllButton); + unfoldAllWeightsBelowListOfControlPoints_hasBeenClicked = GUI.Button(rect_ofUnfoldAllButton, "Unfold all weights", style_ofUnfoldAllButtons); + UnityEditor.EditorGUI.EndDisabledGroup(); + + Color color_ofCollapseAllButton = greyOutCollapseAllButton ? color_ofAGreyedOut_foldAllButton : backgroundColor; + UnityEditor.EditorGUI.DrawRect(rect_ofCollapseAllButton, color_ofCollapseAllButton); + UnityEditor.EditorGUI.BeginDisabledGroup(greyOutCollapseAllButton); + collapseAllWeightsBelowListOfControlPoints_hasBeenClicked = GUI.Button(rect_ofCollapseAllButton, "Collapse all weights", style_ofUnfoldAllButtons); + UnityEditor.EditorGUI.EndDisabledGroup(); +#else + plusButtonBelowListOfControlPoints_hasBeenClicked = false; + unfoldAllWeightsBelowListOfControlPoints_hasBeenClicked = false; + collapseAllWeightsBelowListOfControlPoints_hasBeenClicked = false; +#endif + } + + public static float GetPropertyHeightForEmptyControlPointHoldingOnlyAPlusButtonAndFoldAllButtons() + { + return (Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorVertSpace_ofEmptyLineOfEmptyControlPointHoldingOnlyAPlusButton() + Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint() + Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + Get_additionalInspectorVertSpace_belowEmptyPlusLine_tillFoldAllButtons() + Get_inspectorVertSpace_forFoldAllButtons() + Get_emptyInspectorVertSpace_belowFoldAllButtons()); + } + + static float Get_xPos_ofBackgroundRect(Rect inspectorRect_reservedForThisTriplet) + { + return (inspectorRect_reservedForThisTriplet.x + Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox()); + } + + static float Get_yPos_ofBackgroundRect(Rect inspectorRect_reservedForThisTriplet) + { + return (inspectorRect_reservedForThisTriplet.y + Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox()); + } + + static float Get_width_ofBackgroundRect(Rect inspectorRect_reservedForThisTriplet) + { + return (inspectorRect_reservedForThisTriplet.width - 2.0f * Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox()); + } + + static float Get_xPos_ofPlusAndMinusButtonRect(Rect inspectorRect_reservedForThisTriplet) + { + //-> similar problem as described in "DrawBackgroundArea()", where the yPos is shifted by 1 pixel. + //-> in this case the x-position is shifted by 1 pixel to the left. + float offsetForFixingTheOnePixelOffset = 1.0f; //-> fixing it manually (with the risk of introducing a horizontal one pixel offset if there are situations where the problem doesn't occur) + return (inspectorRect_reservedForThisTriplet.x + inspectorRect_reservedForThisTriplet.width - Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() - Get_width_ofPlusAndMinusButtons() + offsetForFixingTheOnePixelOffset); + } + + static float Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge() + { +#if UNITY_EDITOR + return (0.2f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + { +#if UNITY_EDITOR + return (0.2f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorVertSpace_betweenSubPoints() + { +#if UNITY_EDITOR + return (2.0f * Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge()); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint() + { +#if UNITY_EDITOR + return (UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorVertSpace_ofEmptyLineOfEmptyControlPointHoldingOnlyAPlusButton() + { +#if UNITY_EDITOR + return (UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_additionalInspectorVertSpace_belowEmptyPlusLine_tillFoldAllButtons() + { +#if UNITY_EDITOR + return (0.5f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorVertSpace_forFoldAllButtons() + { +#if UNITY_EDITOR + return (UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_emptyInspectorVertSpace_belowFoldAllButtons() + { +#if UNITY_EDITOR + return (0.0f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_width_ofPlusAndMinusButtons() + { +#if UNITY_EDITOR + return (1.5f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() + { +#if UNITY_EDITOR + return (0.2f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet.cs.meta new file mode 100644 index 0000000..b99c612 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d578c9820a2e3104c889df00fc8d3bdf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet2D.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet2D.cs new file mode 100644 index 0000000..466b77d --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet2D.cs @@ -0,0 +1,793 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + + [Serializable] + public class InternalDXXL_BezierControlPointTriplet2D + { + public bool isHighlighted; + public int i_ofThisPoint_insideControlPointsList; + public BezierSplineDrawer2D bezierSplineDrawer_thisPointIsPartOf; + + [SerializeField] public bool alignedHelperPoints_areOnTheSameSideOfTheAnchor; + [SerializeField] public float progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment; + + public InternalDXXL_BezierControlAnchorSubPoint2D anchorPoint; + public InternalDXXL_BezierControlHelperSubPoint2D forwardHelperPoint; + public InternalDXXL_BezierControlHelperSubPoint2D backwardHelperPoint; + + InternalDXXL_BezierPointShapeConfig2D pointShape_afterSpaceChange_inUnitsOfGlobalSpace; + InternalDXXL_BezierPointShapeConfig2D pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace; + + public Rect inspectorRect_reservedForThisTriplet; + public bool minusButtonAtThisListItem_hasBeenClickedInInspector = false; + + public void Initialize(BezierSplineDrawer2D containingSplineDrawer, Vector2 initialPos_inUnitsOfGlobalSpace, Vector2 initialForwardDir_inUnitsOfGlobalSpace_normalized, InternalDXXL_BezierControlAnchorSubPoint.JunctureType junctureType) + { + bezierSplineDrawer_thisPointIsPartOf = containingSplineDrawer; + + isHighlighted = false; //-> the caller has to decide whether and take care of highlighting newly created control points after this initialization + + alignedHelperPoints_areOnTheSameSideOfTheAnchor = false; + progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment = 0.5f; + + anchorPoint = new InternalDXXL_BezierControlAnchorSubPoint2D(); + anchorPoint.InitializeValuesThatAreIndependentFromOtherSubPoints(this); + anchorPoint.subPointType = InternalDXXL_BezierControlSubPoint.SubPointType.anchor; + anchorPoint.isUsed = true; + anchorPoint.junctureType = junctureType; + anchorPoint.SetPos_inUnitsOfGlobalSpace(initialPos_inUnitsOfGlobalSpace, false, null); + + forwardHelperPoint = new InternalDXXL_BezierControlHelperSubPoint2D(); + forwardHelperPoint.InitializeValuesThatAreIndependentFromOtherSubPoints(this); + forwardHelperPoint.subPointType = InternalDXXL_BezierControlSubPoint.SubPointType.forwardHelper; + forwardHelperPoint.isForward_notBackward = true; + forwardHelperPoint.isUsed = true; + forwardHelperPoint.Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(initialForwardDir_inUnitsOfGlobalSpace_normalized, false, null); + float initial_forwardWeightDistance_inUnitsOfGlobalSpace = bezierSplineDrawer_thisPointIsPartOf.TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(bezierSplineDrawer_thisPointIsPartOf.forwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace); + Vector2 initialPos_ofForwardHelperPoint_inUnitsOfGlobalSpace = initialPos_inUnitsOfGlobalSpace + initialForwardDir_inUnitsOfGlobalSpace_normalized * initial_forwardWeightDistance_inUnitsOfGlobalSpace; + forwardHelperPoint.SetPos_inUnitsOfGlobalSpace(initialPos_ofForwardHelperPoint_inUnitsOfGlobalSpace, false, null); + forwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(initial_forwardWeightDistance_inUnitsOfGlobalSpace, false, null); + + backwardHelperPoint = new InternalDXXL_BezierControlHelperSubPoint2D(); + backwardHelperPoint.InitializeValuesThatAreIndependentFromOtherSubPoints(this); + backwardHelperPoint.subPointType = InternalDXXL_BezierControlSubPoint.SubPointType.backwardHelper; + backwardHelperPoint.isForward_notBackward = false; + backwardHelperPoint.isUsed = true; + backwardHelperPoint.Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized(-initialForwardDir_inUnitsOfGlobalSpace_normalized, false, null); + float initial_backwardWeightDistance_inUnitsOfGlobalSpace = bezierSplineDrawer_thisPointIsPartOf.TransformLength_fromUnitsOfActiveDrawSpace_toGlobalSpace(bezierSplineDrawer_thisPointIsPartOf.backwardWeightDistance_ofNewlyCreatedPoints_inUnitsOfActiveDrawSpace); + Vector2 initialPos_ofBackwardHelperPoint_inUnitsOfGlobalSpace = initialPos_inUnitsOfGlobalSpace - initialForwardDir_inUnitsOfGlobalSpace_normalized * initial_backwardWeightDistance_inUnitsOfGlobalSpace; + backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(initialPos_ofBackwardHelperPoint_inUnitsOfGlobalSpace, false, null); + backwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(initial_backwardWeightDistance_inUnitsOfGlobalSpace, false, null); + } + + public void ReassignIndexInsideControlPointsList(int new_i) + { + i_ofThisPoint_insideControlPointsList = new_i; + + if (anchorPoint != null) //-> skipping newly created points (whose sub points don't exist yet). They get the value in the "controlPointTriplet.Initialize()" function + { + anchorPoint.ReassignIndexInsideControlPointsList(new_i); + } + + if (forwardHelperPoint != null) //-> skipping newly created points (whose sub points don't exist yet). They get the value in the "controlPointTriplet.Initialize()" function + { + forwardHelperPoint.ReassignIndexInsideControlPointsList(new_i); + } + + if (backwardHelperPoint != null) //-> skipping newly created points (whose sub points don't exist yet). They get the value in the "controlPointTriplet.Initialize()" function + { + backwardHelperPoint.ReassignIndexInsideControlPointsList(new_i); + } + } + + public InternalDXXL_BezierControlHelperSubPoint2D GetAHelperPoint(bool requestedHelperPoint_isForward_notBackward) + { + if (requestedHelperPoint_isForward_notBackward) + { + return forwardHelperPoint; + } + else + { + return backwardHelperPoint; + } + } + + public InternalDXXL_BezierControlSubPoint2D GetASubPoint(InternalDXXL_BezierControlSubPoint.SubPointType typeOfRequestedSubPoint) + { + switch (typeOfRequestedSubPoint) + { + case InternalDXXL_BezierControlSubPoint.SubPointType.backwardHelper: + return backwardHelperPoint; + case InternalDXXL_BezierControlSubPoint.SubPointType.anchor: + return anchorPoint; + case InternalDXXL_BezierControlSubPoint.SubPointType.forwardHelper: + return forwardHelperPoint; + default: + return anchorPoint; + } + } + + public bool IsFirstControlPoint() + { + return bezierSplineDrawer_thisPointIsPartOf.IsFirstControlPoint(this); + } + + public bool IsLastControlPoint() + { + return bezierSplineDrawer_thisPointIsPartOf.IsLastControlPoint(this); + } + + public InternalDXXL_BezierControlPointTriplet2D GetNextControlPointTripletAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return bezierSplineDrawer_thisPointIsPartOf.GetNextControlPointTriplet(this, allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + + public InternalDXXL_BezierControlPointTriplet2D GetPreviousControlPointTripletAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + return bezierSplineDrawer_thisPointIsPartOf.GetPreviousControlPointTriplet(this, allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + + public void Save_currentPosConfigInUnitsOfGlobalSpace_as_posConfigAfterSpaceChangeInUnitsOfGlobalSpace() + { + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.anchorPos = anchorPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toForward_normalized = anchorPoint.Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toBackward_normalized = anchorPoint.Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.forwardHelperPos = forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToForwardAnchorPoint = forwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.backwardHelperPos = backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToBackwardAnchorPoint = backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + } + + public void Save_currentPosConfigInUnitsOfActiveDrawSpace_as_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace() + { + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.anchorPos = anchorPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toForward_normalized = anchorPoint.Get_direction_toForward_inUnitsOfActiveDrawSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toBackward_normalized = anchorPoint.Get_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.forwardHelperPos = forwardHelperPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToForwardAnchorPoint = forwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.backwardHelperPos = backwardHelperPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToBackwardAnchorPoint = backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + } + + public void Save_currentPosConfigInUnitsOfActiveDrawSpace_as_posConfigAfterSpaceChangeInUnitsOfGlobalSpace() + { + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.anchorPos = anchorPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toForward_normalized = anchorPoint.Get_direction_toForward_inUnitsOfActiveDrawSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toBackward_normalized = anchorPoint.Get_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.forwardHelperPos = forwardHelperPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToForwardAnchorPoint = forwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.backwardHelperPos = backwardHelperPoint.GetPos_inUnitsOfActiveDrawSpace(); + pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToBackwardAnchorPoint = backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(); + } + + public void Save_currentPosConfigInUnitsOfGlobalSpace_as_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace() + { + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.anchorPos = anchorPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toForward_normalized = anchorPoint.Get_direction_toForward_inUnitsOfGlobalSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toBackward_normalized = anchorPoint.Get_direction_toBackward_inUnitsOfGlobalSpace_normalized(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.forwardHelperPos = forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToForwardAnchorPoint = forwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.backwardHelperPos = backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToBackwardAnchorPoint = backwardHelperPoint.Get_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(); + } + + public void ApplySaved_posConfigAfterSpaceChangeInUnitsOfGlobalSpace() + { + anchorPoint.SetPos_inUnitsOfGlobalSpace(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.anchorPos, false, null); + anchorPoint.Set_direction_toForward_inUnitsOfGlobalSpace_normalized(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toForward_normalized, false, null); + anchorPoint.Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.direction_toBackward_normalized, false, null); + forwardHelperPoint.SetPos_inUnitsOfGlobalSpace(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.forwardHelperPos, false, null); + forwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToForwardAnchorPoint, false, null); + backwardHelperPoint.SetPos_inUnitsOfGlobalSpace(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.backwardHelperPos, false, null); + backwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfGlobalSpace(pointShape_afterSpaceChange_inUnitsOfGlobalSpace.absDistanceToBackwardAnchorPoint, false, null); + } + + public void ApplySaved_posConfigAfterSpaceChangeInUnitsOfActiveDrawSpace() + { + anchorPoint.SetPos_inUnitsOfActiveDrawSpace(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.anchorPos, false, null); + anchorPoint.Set_direction_toForward_inUnitsOfActiveDrawSpace_normalized(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toForward_normalized, false, null); + anchorPoint.Set_direction_toBackward_inUnitsOfActiveDrawSpace_normalized(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.direction_toBackward_normalized, false, null); + forwardHelperPoint.SetPos_inUnitsOfActiveDrawSpace(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.forwardHelperPos, false, null); + forwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToForwardAnchorPoint, false, null); + backwardHelperPoint.SetPos_inUnitsOfActiveDrawSpace(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.backwardHelperPos, false, null); + backwardHelperPoint.Set_absDistanceToAnchorPoint_inUnitsOfActiveDrawSpace(pointShape_afterSpaceChange_inUnitsOfActiveDrawSpace.absDistanceToBackwardAnchorPoint, false, null); + } + + public bool IsEndPointToVoid_atStartOrEndOfAnUnclosedSpline() + { + if (bezierSplineDrawer_thisPointIsPartOf.gapFromEndToStart_isClosed == false) + { + if (IsFirstControlPoint() || IsLastControlPoint()) + { + return true; + } + } + return false; + } + + public bool IsPartOfThisTriplet(InternalDXXL_BezierControlSubPoint2D subPointToCheckIfItIsPartOfThisTriplet) + { + if (subPointToCheckIfItIsPartOfThisTriplet == backwardHelperPoint) + { + return true; + } + + if (subPointToCheckIfItIsPartOfThisTriplet == anchorPoint) + { + return true; + } + + if (subPointToCheckIfItIsPartOfThisTriplet == forwardHelperPoint) + { + return true; + } + + return false; + } + + public bool CheckIf_foldableHelperPoints_areUnfolded_inTheInspectorList() + { + if (backwardHelperPoint.IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + //-> not foldable + } + else + { + if (backwardHelperPoint.isOutfoldedInInspector == false) + { + return false; + } + } + + if (forwardHelperPoint.IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + //-> not foldable + } + else + { + if (forwardHelperPoint.isOutfoldedInInspector == false) + { + return false; + } + } + return true; + } + + public bool CheckIf_foldableHelperPoints_areCollapsed_inTheInspectorList() + { + if (backwardHelperPoint.IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + //-> not foldable + } + else + { + if (backwardHelperPoint.isOutfoldedInInspector) + { + return false; + } + } + + if (forwardHelperPoint.IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid()) + { + //-> not foldable + } + else + { + if (forwardHelperPoint.isOutfoldedInInspector) + { + return false; + } + } + return true; + } + + public void UnfoldBothHelperPointInTheInspectorList() + { + backwardHelperPoint.isOutfoldedInInspector = true; + forwardHelperPoint.isOutfoldedInInspector = true; + } + + public void CollapseBothHelperPointInTheInspectorList() + { + backwardHelperPoint.isOutfoldedInInspector = false; + forwardHelperPoint.isOutfoldedInInspector = false; + } + + public Vector2 GetPosAtPlusButton_onUpcomingBezierSegment_inUnitsOfGlobalSpace() + { + return GetAPos_onUpcomingBezierSegment_inUnitsOfGlobalSpace(progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment); + } + + public Vector2 GetAPos_onUpcomingBezierSegment_inUnitsOfGlobalSpace(float progress0to1_inUpcomingBezierSegment) + { + InternalDXXL_BezierControlPointTriplet2D nextControlPointTriplet = GetNextControlPointTripletAlongSplineDir(true); + if (nextControlPointTriplet == null) + { + return anchorPoint.GetPos_inUnitsOfGlobalSpace(); + } + else + { + Vector2 segmentStartPos = anchorPoint.GetPos_inUnitsOfGlobalSpace(); + Vector2 segmentEndPos = nextControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace(); + if (forwardHelperPoint.isUsed == true) + { + Vector2 firstControlPosInBetween = forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + if (nextControlPointTriplet.backwardHelperPoint.isUsed == true) + { + Vector2 secondControlPosInBetween = nextControlPointTriplet.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + return GetPos_onCubicBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, firstControlPosInBetween, secondControlPosInBetween, segmentEndPos); + } + else + { + return GetPos_onQuadraticBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, firstControlPosInBetween, segmentEndPos); + } + } + else + { + if (nextControlPointTriplet.backwardHelperPoint.isUsed == true) + { + Vector2 theSingleControlPosInBetween = nextControlPointTriplet.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + return GetPos_onQuadraticBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, theSingleControlPosInBetween, segmentEndPos); + } + else + { + //straight line: + Vector2 fromStart_toEnd = segmentEndPos - segmentStartPos; + return (segmentStartPos + fromStart_toEnd * progress0to1_inUpcomingBezierSegment); + } + } + } + } + + Vector2 GetPos_onQuadraticBezierSegment(float progress_0to1, Vector2 segmentStartPos, Vector2 controlPosInBetween, Vector2 segmentEndPos) + { + float oneMinusProgress0to1 = 1.0f - progress_0to1; + float factor1 = oneMinusProgress0to1 * oneMinusProgress0to1; + float factor2 = 2.0f * oneMinusProgress0to1 * progress_0to1; + float factor3 = progress_0to1 * progress_0to1; + return (factor1 * segmentStartPos + factor2 * controlPosInBetween + factor3 * segmentEndPos); + } + + Vector2 GetPos_onCubicBezierSegment(float progress_0to1, Vector2 segmentStartPos, Vector2 firstControlPosInBetween, Vector2 secondControlPosInBetween, Vector2 segmentEndPos) + { + float progress_0to1_sqr = progress_0to1 * progress_0to1; + float oneMinusProgress0to1 = 1.0f - progress_0to1; + float oneMinusProgress0to1_sqr = oneMinusProgress0to1 * oneMinusProgress0to1; + float factor1 = oneMinusProgress0to1 * oneMinusProgress0to1_sqr; + float factor2 = 3.0f * oneMinusProgress0to1_sqr * progress_0to1; + float factor3 = 3.0f * oneMinusProgress0to1 * progress_0to1_sqr; + float factor4 = progress_0to1 * progress_0to1_sqr; + return (factor1 * segmentStartPos + factor2 * firstControlPosInBetween + factor3 * secondControlPosInBetween + factor4 * segmentEndPos); + } + + public Vector2 GetTangentAtPlusButton_onUpcomingBezierSegment_inUnitsOfGlobalSpace(bool normalized) + { + return GetATangent_onUpcomingBezierSegment_inUnitsOfGlobalSpace(progress0to1_ofPlusButtonPosition_inUpcomingBezierSegment, normalized); + } + + public Vector2 GetATangent_onUpcomingBezierSegment_inUnitsOfGlobalSpace(float progress0to1_inUpcomingBezierSegment, bool normalized) + { + InternalDXXL_BezierControlPointTriplet2D nextControlPointTriplet = GetNextControlPointTripletAlongSplineDir(true); + if (nextControlPointTriplet == null) + { + return bezierSplineDrawer_thisPointIsPartOf.Get_forwardTangent_ofControlPointThatDoesntKnowOfANextOne_inUnitsOfGlobalSpace_normalized(this); + } + else + { + Vector2 tangent_notNormalized; + + Vector2 segmentStartPos = anchorPoint.GetPos_inUnitsOfGlobalSpace(); + Vector2 segmentEndPos = nextControlPointTriplet.anchorPoint.GetPos_inUnitsOfGlobalSpace(); + if (forwardHelperPoint.isUsed == true) + { + Vector2 firstControlPosInBetween = forwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + if (nextControlPointTriplet.backwardHelperPoint.isUsed == true) + { + Vector2 secondControlPosInBetween = nextControlPointTriplet.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + tangent_notNormalized = GetTangent_onCubicBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, firstControlPosInBetween, secondControlPosInBetween, segmentEndPos); + } + else + { + tangent_notNormalized = GetTangent_onQuadraticBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, firstControlPosInBetween, segmentEndPos); + } + } + else + { + if (nextControlPointTriplet.backwardHelperPoint.isUsed == true) + { + Vector2 theSingleControlPosInBetween = nextControlPointTriplet.backwardHelperPoint.GetPos_inUnitsOfGlobalSpace(); + tangent_notNormalized = GetTangent_onQuadraticBezierSegment(progress0to1_inUpcomingBezierSegment, segmentStartPos, theSingleControlPosInBetween, segmentEndPos); + } + else + { + //straight line: + Vector2 fromStart_toEnd = segmentEndPos - segmentStartPos; + if (UtilitiesDXXL_Math.ApproximatelyZero(fromStart_toEnd)) + { + return bezierSplineDrawer_thisPointIsPartOf.Get_forwardTangent_ofControlPointThatDoesntKnowOfANextOne_inUnitsOfGlobalSpace_normalized(this); + } + else + { + tangent_notNormalized = fromStart_toEnd; + } + } + } + + if (normalized) + { + Vector2 tangent_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(tangent_notNormalized); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(tangent_normalized)) + { + return bezierSplineDrawer_thisPointIsPartOf.Get_right_ofActiveDrawSpace_inUnitsOfGlobalSpace_normalized(); + } + else + { + return tangent_normalized; + } + } + else + { + return tangent_notNormalized; + } + } + } + + Vector2 GetTangent_onQuadraticBezierSegment(float progress_0to1, Vector2 segmentStartPos, Vector2 controlPosInBetween, Vector2 segmentEndPos) + { + return (2.0f * (1.0f - progress_0to1) * (controlPosInBetween - segmentStartPos) + 2.0f * progress_0to1 * (segmentEndPos - controlPosInBetween)); + } + + Vector2 GetTangent_onCubicBezierSegment(float progress_0to1, Vector2 segmentStartPos, Vector2 firstControlPosInBetween, Vector2 secondControlPosInBetween, Vector2 segmentEndPos) + { + float progress_0to1_sqr = progress_0to1 * progress_0to1; + float oneMinusProgress0to1 = 1.0f - progress_0to1; + return (3.0f * oneMinusProgress0to1 * oneMinusProgress0to1 * (firstControlPosInBetween - segmentStartPos) + (6.0f * oneMinusProgress0to1 * progress_0to1) * (secondControlPosInBetween - firstControlPosInBetween) + 3.0f * progress_0to1_sqr * (segmentEndPos - secondControlPosInBetween)); + } + + public void Invert_alignedHelperPoints_areOnTheSameSideOfTheAnchor() + { + alignedHelperPoints_areOnTheSameSideOfTheAnchor = !alignedHelperPoints_areOnTheSameSideOfTheAnchor; + } + + public void DrawValuesToInspector() + { + TryHighlightThisControlPoint_dueToMouseClickOnItInInspector(); + DrawBackgroundArea_forInspector(); + DrawSubPoints_forInspector(); + } + + void TryHighlightThisControlPoint_dueToMouseClickOnItInInspector() + { + Event currentEvent = Event.current; + if (currentEvent.type == EventType.MouseDown) + { + if (inspectorRect_reservedForThisTriplet.Contains(currentEvent.mousePosition)) + { + bezierSplineDrawer_thisPointIsPartOf.SetSelectedListSlot(i_ofThisPoint_insideControlPointsList); + bezierSplineDrawer_thisPointIsPartOf.SheduleSceneViewRepaint(); + } + } + } + + void DrawBackgroundArea_forInspector() + { + Rect space_ofBigBackgroundColorRect = new Rect(Get_xPos_ofBackgroundRect(inspectorRect_reservedForThisTriplet), Get_yPos_ofBackgroundRect(inspectorRect_reservedForThisTriplet), Get_width_ofBackgroundRect(inspectorRect_reservedForThisTriplet), inspectorRect_reservedForThisTriplet.height - 2.0f * Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() - Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint()); + float alphaFactor_ofBackgroundColor = isHighlighted ? InternalDXXL_BezierControlPointTriplet.alpha_ofInspectorBackgroundColor_highlighted : InternalDXXL_BezierControlPointTriplet.alpha_ofInspectorBackgroundColor_nonHighlighted; + Color backgroundColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_thisPointIsPartOf.color_ofAnchorPoints, alphaFactor_ofBackgroundColor); + + DrawBackgroundColor_forInspector(space_ofBigBackgroundColorRect, backgroundColor); + + //See also "Get_xPos_ofPlusAndMinusButtonRect()": + //float y_of_minusButton = position.y + position.height - inspectorVertSpace_from_mainRect_to_backgroundColorBox - inspectorVertSpace_ofMinusButtonOnEachControlPoint; //-> float calculation imprecision errors seems to introduce overlap offsets of 1 pixel when calculated like this + //float y_of_minusButton = space_ofBigBackgroundColorRect.y + space_ofBigBackgroundColorRect.height; //-> this also is not solving the 1 pixel overlap offset + //float y_of_minusButton = space_ofBigBackgroundColorRect.yMax; //-> this also is not solving the 1 pixel overlap offset + float y_of_minusButton = space_ofBigBackgroundColorRect.yMax + 1.0f; //-> fixing it manually (with the risk of adding an empty pixel line if there are situations where the problem doesn't occur) + + DrawMinusButton_forInspector(backgroundColor, y_of_minusButton); + DrawIndexNumber_forInspector(backgroundColor, y_of_minusButton); + } + + void DrawBackgroundColor_forInspector(Rect space_ofBigBackgroundColorRect, Color backgroundColor) + { +#if UNITY_EDITOR + UnityEditor.EditorGUI.DrawRect(space_ofBigBackgroundColorRect, backgroundColor); +#endif + } + + void DrawMinusButton_forInspector(Color backgroundColor, float y_of_minusButton) + { +#if UNITY_EDITOR + Rect space_ofMinusButtonBackground = new Rect(Get_xPos_ofPlusAndMinusButtonRect(inspectorRect_reservedForThisTriplet), y_of_minusButton, Get_width_ofPlusAndMinusButtons(), Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint()); + UnityEditor.EditorGUI.DrawRect(space_ofMinusButtonBackground, backgroundColor); + + GUIContent minusSymbolIcon = UnityEditor.EditorGUIUtility.TrIconContent("Toolbar Minus", "Delete control point"); + GUIStyle style_ofMinusButton = "RL FooterButton"; + minusButtonAtThisListItem_hasBeenClickedInInspector = GUI.Button(space_ofMinusButtonBackground, minusSymbolIcon, style_ofMinusButton); +#endif + } + + void DrawIndexNumber_forInspector(Color backgroundColor, float y_of_minusButton) + { +#if UNITY_EDITOR + float horizSpace_betweenSlotIndexNumber_and_minusButton = 0.5f * UnityEditor.EditorGUIUtility.singleLineHeight; + float horizPadding_besideIndexNumberInsideNumberRect_perSide = 0.5f * UnityEditor.EditorGUIUtility.singleLineHeight; + float horizPadding_besideIndexNumberInsideNumberRect_forBothSides = 2.0f * horizPadding_besideIndexNumberInsideNumberRect_perSide; + float width_perNumberDigit = 0.6f * UnityEditor.EditorGUIUtility.singleLineHeight; + float width_ofSlotIndexNumberRect = horizPadding_besideIndexNumberInsideNumberRect_forBothSides + width_perNumberDigit * GetNumberOfDigitsInIndexNumber(); + Rect space_ofSlotIndexNumberBackground = new Rect(inspectorRect_reservedForThisTriplet.x + inspectorRect_reservedForThisTriplet.width - Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() - Get_width_ofPlusAndMinusButtons() - horizSpace_betweenSlotIndexNumber_and_minusButton - width_ofSlotIndexNumberRect, y_of_minusButton, width_ofSlotIndexNumberRect, Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint()); + UnityEditor.EditorGUI.DrawRect(space_ofSlotIndexNumberBackground, backgroundColor); + + GUIStyle style_ofNumber = new GUIStyle(); + Color color_ofNumber; + if (isHighlighted) + { + color_ofNumber = UtilitiesDXXL_Colors.GetSimilarColorWithOtherBrightnessValue(bezierSplineDrawer_thisPointIsPartOf.color_ofAnchorPoints, 0.375f); + } + else + { + color_ofNumber = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(bezierSplineDrawer_thisPointIsPartOf.color_ofAnchorPoints, 0.725f); + } + + string textString_ofNumber = "" + i_ofThisPoint_insideControlPointsList + ""; + float y_offset_ofSlotIndexNumber = -0.1f * UnityEditor.EditorGUIUtility.singleLineHeight; + Rect space_ofSlotIndexNumber = new Rect(space_ofSlotIndexNumberBackground.x + horizPadding_besideIndexNumberInsideNumberRect_perSide, space_ofSlotIndexNumberBackground.y + y_offset_ofSlotIndexNumber, space_ofSlotIndexNumberBackground.width - horizPadding_besideIndexNumberInsideNumberRect_forBothSides, space_ofSlotIndexNumberBackground.height); + UnityEditor.EditorGUI.LabelField(space_ofSlotIndexNumber, textString_ofNumber, style_ofNumber); +#endif + } + + int GetNumberOfDigitsInIndexNumber() + { + if (i_ofThisPoint_insideControlPointsList >= 10000) + { + return 5; + } + else + { + if (i_ofThisPoint_insideControlPointsList >= 1000) + { + return 4; + } + else + { + if (i_ofThisPoint_insideControlPointsList >= 100) + { + return 3; + } + else + { + if (i_ofThisPoint_insideControlPointsList >= 10) + { + return 2; + } + else + { + return 1; + } + } + } + } + } + + void DrawSubPoints_forInspector() + { + float height_ofBackwardHelper = backwardHelperPoint.GetPropertyHeightForInspectorList(); + float height_ofAnchor = anchorPoint.GetPropertyHeightForInspectorList(); + float height_ofForwardHelper = forwardHelperPoint.GetPropertyHeightForInspectorList(); + + float x_ofHelperPointsColorBox = inspectorRect_reservedForThisTriplet.x + Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge(); + float width_ofHelperPointsColorBox = inspectorRect_reservedForThisTriplet.width - 2.0f * Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() - 2.0f * Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge(); + + float currentHeightOffset = 0.0f; + currentHeightOffset += Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox(); + currentHeightOffset += Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge(); + + Rect rect_of_backwardHelperPoint = new Rect(x_ofHelperPointsColorBox, inspectorRect_reservedForThisTriplet.y + currentHeightOffset, width_ofHelperPointsColorBox, height_ofBackwardHelper); + + currentHeightOffset += height_ofBackwardHelper; + currentHeightOffset += Get_inspectorVertSpace_betweenSubPoints(); + + float x_ofAnchorPointsSubProperty = inspectorRect_reservedForThisTriplet.x + Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge() + InternalDXXL_BezierControlHelperSubPoint.Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields(); + float width_ofAnchorPointsSubProperty = inspectorRect_reservedForThisTriplet.width - 2.0f * Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() - 2.0f * Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge() - 2.0f * InternalDXXL_BezierControlHelperSubPoint.Get_inspectorHorizSpace_between_subPointColorBoxEdge_and_actualContenFields(); + Rect rect_of_anchorPoint = new Rect(x_ofAnchorPointsSubProperty, inspectorRect_reservedForThisTriplet.y + currentHeightOffset, width_ofAnchorPointsSubProperty, height_ofAnchor); + + currentHeightOffset += height_ofAnchor; + currentHeightOffset += Get_inspectorVertSpace_betweenSubPoints(); + + Rect rect_of_forwardHelperPoint = new Rect(x_ofHelperPointsColorBox, inspectorRect_reservedForThisTriplet.y + currentHeightOffset, width_ofHelperPointsColorBox, height_ofForwardHelper); + + backwardHelperPoint.DrawValuesToInspector(rect_of_backwardHelperPoint); + anchorPoint.DrawValuesToInspector(rect_of_anchorPoint); + forwardHelperPoint.DrawValuesToInspector(rect_of_forwardHelperPoint); + } + + public bool TryApplyChangesAfterInspectorInput() + { + bool didChangeSomething; + + didChangeSomething = backwardHelperPoint.TryApplyChangesAfterInspectorInput(); + if (didChangeSomething) { return true; } + + didChangeSomething = anchorPoint.TryApplyChangesAfterInspectorInput(); + if (didChangeSomething) { return true; } + + didChangeSomething = forwardHelperPoint.TryApplyChangesAfterInspectorInput(); + if (didChangeSomething) { return true; } + + return false; + } + + public float GetPropertyHeightForInspectorList() + { + float height_ofBackwardHelper = backwardHelperPoint.GetPropertyHeightForInspectorList(); + float height_ofAnchor = anchorPoint.GetPropertyHeightForInspectorList(); + float height_ofForwardHelper = forwardHelperPoint.GetPropertyHeightForInspectorList(); + float additionalHeight = Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge() + Get_inspectorVertSpace_betweenSubPoints() + Get_inspectorVertSpace_betweenSubPoints() + Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge() + Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint() + Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox(); + + return (height_ofBackwardHelper + height_ofAnchor + height_ofForwardHelper + additionalHeight); + } + + public static void DrawEmptyControlPointHoldingOnlyAPlusButton_forInspector(out bool plusButtonBelowListOfControlPoints_hasBeenClicked, out bool unfoldAllWeightsBelowListOfControlPoints_hasBeenClicked, out bool collapseAllWeightsBelowListOfControlPoints_hasBeenClicked, Rect position, Color color_ofAnchorPoints, GUIContent plusSymbolIcon, bool greyOutUnfoldAllButton, bool greyOutCollapseAllButton) + { +#if UNITY_EDITOR + Color backgroundColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofAnchorPoints, InternalDXXL_BezierControlPointTriplet.alpha_ofInspectorBackgroundColor_nonHighlighted); + + Rect rect_ofEmptyLine = new Rect(Get_xPos_ofBackgroundRect(position), Get_yPos_ofBackgroundRect(position), Get_width_ofBackgroundRect(position), Get_inspectorVertSpace_ofEmptyLineOfEmptyControlPointHoldingOnlyAPlusButton()); + UnityEditor.EditorGUI.DrawRect(rect_ofEmptyLine, backgroundColor); + + Rect rect_ofPlusButtonBelowEmptyLine = new Rect(Get_xPos_ofPlusAndMinusButtonRect(position), position.y + Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorVertSpace_ofEmptyLineOfEmptyControlPointHoldingOnlyAPlusButton(), Get_width_ofPlusAndMinusButtons(), Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint()); + UnityEditor.EditorGUI.DrawRect(rect_ofPlusButtonBelowEmptyLine, backgroundColor); + + GUIStyle style_ofMinusButton = "RL FooterButton"; + plusButtonBelowListOfControlPoints_hasBeenClicked = GUI.Button(rect_ofPlusButtonBelowEmptyLine, plusSymbolIcon, style_ofMinusButton); + + Rect rect_ofBothFoldAllButtons = new Rect(Get_xPos_ofBackgroundRect(position), position.y + Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorVertSpace_ofEmptyLineOfEmptyControlPointHoldingOnlyAPlusButton() + Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint() + Get_additionalInspectorVertSpace_belowEmptyPlusLine_tillFoldAllButtons(), Get_width_ofBackgroundRect(position), Get_inspectorVertSpace_forFoldAllButtons()); + + float halfHorizSpaceBetweenButtons = 0.5f * Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox(); + Rect rect_ofUnfoldAllButton = new Rect(rect_ofBothFoldAllButtons.x, rect_ofBothFoldAllButtons.y, rect_ofBothFoldAllButtons.width * 0.5f - halfHorizSpaceBetweenButtons, rect_ofBothFoldAllButtons.height); + Rect rect_ofCollapseAllButton = new Rect(rect_ofBothFoldAllButtons.x + rect_ofBothFoldAllButtons.width * 0.5f + halfHorizSpaceBetweenButtons, rect_ofBothFoldAllButtons.y, rect_ofBothFoldAllButtons.width * 0.5f - halfHorizSpaceBetweenButtons, rect_ofBothFoldAllButtons.height); + + GUIStyle style_ofUnfoldAllButtons = new GUIStyle(style_ofMinusButton); + style_ofUnfoldAllButtons.fontStyle = FontStyle.Normal; + Color color_ofAGreyedOut_foldAllButton = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(backgroundColor, 0.5f); + + Color color_ofUnfoldAllButton = greyOutUnfoldAllButton ? color_ofAGreyedOut_foldAllButton : backgroundColor; + UnityEditor.EditorGUI.DrawRect(rect_ofUnfoldAllButton, color_ofUnfoldAllButton); + UnityEditor.EditorGUI.BeginDisabledGroup(greyOutUnfoldAllButton); + unfoldAllWeightsBelowListOfControlPoints_hasBeenClicked = GUI.Button(rect_ofUnfoldAllButton, "Unfold all weights", style_ofUnfoldAllButtons); + UnityEditor.EditorGUI.EndDisabledGroup(); + + Color color_ofCollapseAllButton = greyOutCollapseAllButton ? color_ofAGreyedOut_foldAllButton : backgroundColor; + UnityEditor.EditorGUI.DrawRect(rect_ofCollapseAllButton, color_ofCollapseAllButton); + UnityEditor.EditorGUI.BeginDisabledGroup(greyOutCollapseAllButton); + collapseAllWeightsBelowListOfControlPoints_hasBeenClicked = GUI.Button(rect_ofCollapseAllButton, "Collapse all weights", style_ofUnfoldAllButtons); + UnityEditor.EditorGUI.EndDisabledGroup(); +#else + plusButtonBelowListOfControlPoints_hasBeenClicked = false; + unfoldAllWeightsBelowListOfControlPoints_hasBeenClicked = false; + collapseAllWeightsBelowListOfControlPoints_hasBeenClicked = false; +#endif + } + + public static float GetPropertyHeightForEmptyControlPointHoldingOnlyAPlusButtonAndFoldAllButtons() + { + return (Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + Get_inspectorVertSpace_ofEmptyLineOfEmptyControlPointHoldingOnlyAPlusButton() + Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint() + Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + Get_additionalInspectorVertSpace_belowEmptyPlusLine_tillFoldAllButtons() + Get_inspectorVertSpace_forFoldAllButtons() + Get_emptyInspectorVertSpace_belowFoldAllButtons()); + } + + static float Get_xPos_ofBackgroundRect(Rect inspectorRect_reservedForThisTriplet) + { + return (inspectorRect_reservedForThisTriplet.x + Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox()); + } + + static float Get_yPos_ofBackgroundRect(Rect inspectorRect_reservedForThisTriplet) + { + return (inspectorRect_reservedForThisTriplet.y + Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox()); + } + + static float Get_width_ofBackgroundRect(Rect inspectorRect_reservedForThisTriplet) + { + return (inspectorRect_reservedForThisTriplet.width - 2.0f * Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox()); + } + + static float Get_xPos_ofPlusAndMinusButtonRect(Rect inspectorRect_reservedForThisTriplet) + { + //-> similar problem as described in "DrawBackgroundArea()", where the yPos is shifted by 1 pixel. + //-> in this case the x-position is shifted by 1 pixel to the left. + float offsetForFixingTheOnePixelOffset = 1.0f; //-> fixing it manually (with the risk of introducing a horizontal one pixel offset if there are situations where the problem doesn't occur) + return (inspectorRect_reservedForThisTriplet.x + inspectorRect_reservedForThisTriplet.width - Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() - Get_width_ofPlusAndMinusButtons() + offsetForFixingTheOnePixelOffset); + } + + static float Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge() + { +#if UNITY_EDITOR + return (0.2f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorVertSpace_from_mainRect_to_backgroundColorBox() + { +#if UNITY_EDITOR + return (0.2f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorVertSpace_betweenSubPoints() + { +#if UNITY_EDITOR + return (2.0f * Get_inspectorSpace_fromOutsideColorBoxEdge_toInsideColorBoxEdge()); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorVertSpace_ofMinusButtonOnEachControlPoint() + { +#if UNITY_EDITOR + return (UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorVertSpace_ofEmptyLineOfEmptyControlPointHoldingOnlyAPlusButton() + { +#if UNITY_EDITOR + return (UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_additionalInspectorVertSpace_belowEmptyPlusLine_tillFoldAllButtons() + { +#if UNITY_EDITOR + return (0.5f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorVertSpace_forFoldAllButtons() + { +#if UNITY_EDITOR + return (UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_emptyInspectorVertSpace_belowFoldAllButtons() + { +#if UNITY_EDITOR + return (0.0f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_width_ofPlusAndMinusButtons() + { +#if UNITY_EDITOR + return (1.5f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + static float Get_inspectorHorizSpace_from_mainRect_to_backgroundColorBox() + { +#if UNITY_EDITOR + return (0.2f * UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return 16.0f; //-> not used +#endif + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet2D.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet2D.cs.meta new file mode 100644 index 0000000..05a1654 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlPointTriplet2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d9634370ba98d947b85834f62524d7f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint.cs new file mode 100644 index 0000000..44788bc --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint.cs @@ -0,0 +1,519 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + + [Serializable] + public class InternalDXXL_BezierControlSubPoint + { + public enum SubPointType { backwardHelper, anchor, forwardHelper }; + + [SerializeField] public bool isUsed; //can be disabled by the user in the control points list inspector (only for kinked junctures), or is automatically disabled for endPoints of non-closed splines + [SerializeField] public Vector3 position_inUnitsOfActiveDrawSpace; + [SerializeField] Vector3 position_inUnitsOfGlobalSpace; + + public BezierSplineDrawer bezierSplineDrawer_thisSubPointIsPartOf; + [SerializeField] public int i_ofContainingControlPoint_insideControlPointsList; + public SubPointType subPointType; + + public GameObject boundGameobject; + public DrawXXLSplineConnection connectionComponent_onBoundGameobject; + public bool boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled; + public bool boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled; + + public Quaternion globalRotation_ofPositionHandle = Quaternion.identity; + public bool recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = true; + + public virtual void InitializeValuesThatAreIndependentFromOtherSubPoints(InternalDXXL_BezierControlPointTriplet controlPoint_thisSubPointIsPartOf) + { + boundGameobject = null; + connectionComponent_onBoundGameobject = null; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = false; + i_ofContainingControlPoint_insideControlPointsList = controlPoint_thisSubPointIsPartOf.i_ofThisPoint_insideControlPointsList; + bezierSplineDrawer_thisSubPointIsPartOf = controlPoint_thisSubPointIsPartOf.bezierSplineDrawer_thisPointIsPartOf; + } + + public void ReassignIndexInsideControlPointsList(int new_i) + { + SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); //-> function is dependent on the "old" i. + if (boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled) + { + connectionComponent_onBoundGameobject.i_ofControlPointTriplet_thisGameobjectIsBoundTo = new_i; + } + i_ofContainingControlPoint_insideControlPointsList = new_i; + } + + public InternalDXXL_BezierControlPointTriplet Get_controlPointTriplet_thisSubPointIsPartOf() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + return bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets[i_ofContainingControlPoint_insideControlPointsList]; + } + + public void SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled() + { + ///De-assigning connectionComponents is not trivial as soon as it has to comply with the build-in Undo-System. + //Problems: + //The spline-component and the connection-component should only exist together, but they are on independent gameobjects, which the user can delete or copy independently. + //When the spline-component is deleted then also all corresponding connection-componenets should be deleted. + //-> It could be done in "spline.OnDestroy()", but this is not fired always when a component gets destroyed. The Unity docu says the it is not fired when the carrying gameobject is inactive. Though testing it in the Unity Editor showed: It is often called, even when the gameobject is inactive, but it is sometimes omited, even when the gameobject is active. So overall: Not fully reliable. Orphaned connection-components may still remain in the scene, which is not desired. + //-> More reliable than "spline.OnDestroy()" is "spline.OnDisable()", but we don't want to destroy the connection reference just because some disabled a participating component (maybe with the intention to enabled it sometime later) + //-> So the connection components should handle their deletion self contained, as soon as the referncing spline is not there anymore. + //-> This is working fine as long as "Undo" doesn't come into play. + //-> If a boundGameobject gets deleted and then the deletion is reverted via "Editor/Undo", then the two partners (spline-component and connection-component) don't recognize each other anymore as "referenced partners". The reference is lost. This seems to be a Unity bug, see here: https://forum.unity.com/threads/monobehaviour-references-are-lost-on-undo.587011/ and here: https://issuetracker.unity3d.com/issues/gameobject-isnt-set-as-public-variable-after-undo-operation It's an unconvenience but since Unity itself accepts this bug it's hopefully indeed "acceptable". + //-> It can be fixed in the case of spline-deletion (because in "spline.OnDestroy()" the connectionComponents can be deleted by the spline itself (so not following the mentioned "self contained deletion" way)), and along with that the spline can register "Undo.DestroyImmediate()" for the connection-components: In this case the references are correctly reverted after Undo. A similar construction inside "connectionComponent.OnDestroy()" doesn't have the same fixing effect though (see note there). + //-> Another approach would be to not immediately destroy the connection components after spline-deletion, but delay the self contained destruction with a timer, so that the undo-process doesn't have to "recreate them as new instance from serialized data" in the hope that they are then still the "correct reference". But tests showed: It is not the case. It makes no difference and the reference is still lost. + //-> Another approach would be to somehow search the formerly reference component and recreate the reference "OnUndoExecuted". The problem with that is that it is quiete non-intended from Unities paradigm of doing things. Such "hacky interventions" sometimes lead to Editor crashes when shuffling around "Undo/Redo" to and fro. It seems unwieldly and to risky. + //-> Another case where the reference gets lost: "Assign boundGameobject in the inspector" -> "Undo assign" -> "Redo assign" -> reference is lost. + + if (boundGameobject == null) + { + //cases that arrive here: + //-> "boundGameobject" hasnn't been assigned yet + //-> "boundGameobject" was regularly deassgined + //-> "boundGameobject" has been independently deleted (but may come back via "Undo") + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = false; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = false; + } + else + { + if (connectionComponent_onBoundGameobject == null) + { + //cases that arrive here: + //-> the "connectionComponent_onBoundGameobject"-component has been independently deleted from the (still existing) "boundGameobject" (but it may come back via "Undo") + //-> also after "Undo" it sometimes doesn't come back due to the reference lost error described above in this function + //-> assign boundGameobject to a controlSubPoint -> Undo assign -> Redo assign -> connection is not retrieved + boundGameobject = null; + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = false; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = false; + } + else + { + if (connectionComponent_onBoundGameobject.bezierSplineDrawer_thatHasReferencedThisGameobject != bezierSplineDrawer_thisSubPointIsPartOf) + { + //-> The spline component (e.g. along with it's carrying gameobject) has been copied. Both the old spline component and the new spline component here reference the single connection-component on the boundGameobject + //-> The new spline here creates his own additonal connection component on the boundGameobject now: + + CreateConnectionComponentOnBoundGameobject("Auto-create connection after spline copy"); + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = true; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = connectionComponent_onBoundGameobject.isActiveAndEnabled; + } + else + { + // if (connectionComponent_onBoundGameobject.bezierSubPoint_thatHasReferencedThisGameobject != this) //this is not suitable as reference, because in the serialized context "InternalDXXL_BezierControlSubPoint" acts as value type, not as reference type. + if (connectionComponent_onBoundGameobject.i_ofControlPointTriplet_thisGameobjectIsBoundTo != i_ofContainingControlPoint_insideControlPointsList) + { + bezierSplineDrawer_thisSubPointIsPartOf.DeleteConnectionComponentOfBoundGameobject_onControlSubPoint(i_ofContainingControlPoint_insideControlPointsList, subPointType); + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = false; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = false; + UtilitiesDXXL_Log.PrintErrorCode("50-" + connectionComponent_onBoundGameobject.i_ofControlPointTriplet_thisGameobjectIsBoundTo + "-" + i_ofContainingControlPoint_insideControlPointsList + "-" + bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets.Count); + } + else + { + if (connectionComponent_onBoundGameobject.subPointType_whereThisGameobjectIsBoundTo != subPointType) + { + bezierSplineDrawer_thisSubPointIsPartOf.DeleteConnectionComponentOfBoundGameobject_onControlSubPoint(i_ofContainingControlPoint_insideControlPointsList, subPointType); + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = false; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = false; + UtilitiesDXXL_Log.PrintErrorCode("51-" + connectionComponent_onBoundGameobject.subPointType_whereThisGameobjectIsBoundTo + "-" + subPointType + "-" + bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets.Count); + } + else + { + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = true; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = connectionComponent_onBoundGameobject.isActiveAndEnabled; + } + } + } + } + } + } + + public void ProcessNewGameobjectAssignment(GameObject newlyAssignedGameobject) + { + if (newlyAssignedGameobject != boundGameobject) + { + if (bezierSplineDrawer_thisSubPointIsPartOf.CheckIf_gameobjectToAssign_isAlreadyAssignedAtAnotherSubPointOfTheSpline(newlyAssignedGameobject, out int i_ofTripletThatContainsTheSubPointThatAlreadyHasTheGameobjectAssigned, out SubPointType subPointThatAlreadyHasTheGameobjectAssigned)) + { + //This restriction is done to prevent tangled unwieldy cross-dependencies between subPoints. Otherwise numerous cases would need special consideration, e.g.: A gameobject could be bound not only to the backward helper, but also to the forward helper of the same controlPoint triplet. + //Already without this restriction there are overdefined situations: E.g. when different gameobjects are bound to all three subPoints of a triplet, junctureType=kinked, and both helperPoint bind their direction to the same transform direction of the boundGameobject at the center point. + Debug.LogError("Assignment of gameobject (" + newlyAssignedGameobject.name + ") denied, because a gameobject can only be assinged once per spline. It is already assinged at the " + GetSubPointTypeAsString(subPointThatAlreadyHasTheGameobjectAssigned) + " of control point " + i_ofTripletThatContainsTheSubPointThatAlreadyHasTheGameobjectAssigned + "."); + } + else + { + string nameOfUndoEntry = "Change Spline Gameobject Ref"; + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo(nameOfUndoEntry, true, true); + + if (boundGameobject != null) + { + //Deassign old gameobject: + if (connectionComponent_onBoundGameobject != null) + { +#if UNITY_EDITOR + UnityEditor.Undo.DestroyObjectImmediate(connectionComponent_onBoundGameobject); +#endif + } + boundGameobject = null; + connectionComponent_onBoundGameobject = null; + } + + boundGameobject = newlyAssignedGameobject; + + if (newlyAssignedGameobject != null) + { + //Assign new gameobject: + CreateConnectionComponentOnBoundGameobject(nameOfUndoEntry); + } + else + { + ResetDirectionSourceToIndependent(); + } + } + } + } + + void CreateConnectionComponentOnBoundGameobject(string nameOfUndoEntry_forNewlyCreatedComponent) + { +#if UNITY_EDITOR + connectionComponent_onBoundGameobject = UnityEditor.Undo.AddComponent(boundGameobject); + UnityEditor.Undo.RegisterCompleteObjectUndo(connectionComponent_onBoundGameobject, nameOfUndoEntry_forNewlyCreatedComponent); +#else + connectionComponent_onBoundGameobject = boundGameobject.AddComponent(); +#endif + + connectionComponent_onBoundGameobject.componentHasBeenManuallyCreated = false; + connectionComponent_onBoundGameobject.bezierSplineDrawer_thatHasReferencedThisGameobject = bezierSplineDrawer_thisSubPointIsPartOf; + connectionComponent_onBoundGameobject.i_ofControlPointTriplet_thisGameobjectIsBoundTo = i_ofContainingControlPoint_insideControlPointsList; + connectionComponent_onBoundGameobject.subPointType_whereThisGameobjectIsBoundTo = subPointType; + + SetPos_inUnitsOfGlobalSpace(boundGameobject.transform.position, true, boundGameobject); + TryTransferBoundGameobjectsRotationToAnchorPointsDirection(); + } + + public virtual void ResetDirectionSourceToIndependent() + { + } + + public virtual void TryTransferBoundGameobjectsRotationToAnchorPointsDirection() + { + } + + public Vector3 GetPos_inUnitsOfGlobalSpace() + { + return position_inUnitsOfGlobalSpace; + } + + public Vector3 GetPos_inUnitsOfActiveDrawSpace() + { + return position_inUnitsOfActiveDrawSpace; + } + + public virtual void SetPos_inUnitsOfGlobalSpace(Vector3 newPos_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + //all children override this + } + + public Vector3 SetPos_inUnitsOfGlobalSpace_butIgnoreDependentValues_nonRecursively(Vector3 newPos_inUnitsOfGlobalSpace, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + //"_nonRecursively" indicates: This function is reserved to be called inside the overrides of "SetPos_inUnitsOfGlobalSpace". In all other cases use "SetPos_inUnitsOfGlobalSpace(..., false)" + + Vector3 offset_fromPrevious_toNewPosition_inUnitsOfGlobalSpace = newPos_inUnitsOfGlobalSpace - position_inUnitsOfGlobalSpace; + position_inUnitsOfGlobalSpace = newPos_inUnitsOfGlobalSpace; + position_inUnitsOfActiveDrawSpace = bezierSplineDrawer_thisSubPointIsPartOf.TransformPos_fromGlobalSpace_toUnitsOfActiveDrawSpace(newPos_inUnitsOfGlobalSpace); + + SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + if (boundGameobject != boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + boundGameobject.transform.position = newPos_inUnitsOfGlobalSpace; + } + } + + return offset_fromPrevious_toNewPosition_inUnitsOfGlobalSpace; + } + + public void SetPos_inUnitsOfActiveDrawSpace(Vector3 newPos_inUnitsOfActiveDrawSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector3 newPos_inUnitsOfGlobalSpace = bezierSplineDrawer_thisSubPointIsPartOf.TransformPos_fromUnitsOfActiveDrawSpace_toGlobalSpace(newPos_inUnitsOfActiveDrawSpace); + SetPos_inUnitsOfGlobalSpace(newPos_inUnitsOfGlobalSpace, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void AddPosOffset_inUnitsOfGlobalSpace(Vector3 posOffset_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector3 newPos_inUnitsOfGlobalSpace = GetPos_inUnitsOfGlobalSpace() + posOffset_inUnitsOfGlobalSpace; + SetPos_inUnitsOfGlobalSpace(newPos_inUnitsOfGlobalSpace, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void AddPosOffset_inUnitsOfActiveDrawSpace(Vector3 posOffset_inUnitsOfActiveDrawSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector3 newPos_inUnitsOfActiveDrawSpace = GetPos_inUnitsOfActiveDrawSpace() + posOffset_inUnitsOfActiveDrawSpace; + SetPos_inUnitsOfActiveDrawSpace(newPos_inUnitsOfActiveDrawSpace, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public virtual void Set_direction_toForward_inUnitsOfGlobalSpace_normalized(Vector3 newDirection_toForward_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + //-> is not intended to be called for non-overriding helperPoints. Use "helperPoint.Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized()" instead + UtilitiesDXXL_Log.PrintErrorCode("37"); + } + + public virtual void Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(Vector3 newDirection_toBackward_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + //-> is not intended to be called for non-overriding helperPoints. Use "helperPoint.Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized()" instead + UtilitiesDXXL_Log.PrintErrorCode("38"); + } + + public virtual InternalDXXL_BezierControlAnchorSubPoint.JunctureType GetJunctureType() + { + //-> is not intended to be called for non-overriding helperPoints + UtilitiesDXXL_Log.PrintErrorCode("39"); + return InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned; + } + + public virtual InternalDXXL_BezierControlHelperSubPoint GetForwardHelper() + { + //-> is not intended to be called for non-overriding helperPoints + UtilitiesDXXL_Log.PrintErrorCode("40"); + return null; + } + + public virtual InternalDXXL_BezierControlHelperSubPoint GetBackwardHelper() + { + //-> is not intended to be called for non-overriding helperPoints + UtilitiesDXXL_Log.PrintErrorCode("41"); + return null; + } + + public virtual InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper Get_sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked() + { + //-> is not intended to be called for non-overriding helperPoints + UtilitiesDXXL_Log.PrintErrorCode("42"); + return InternalDXXL_BezierControlAnchorSubPoint.SourceOf_directionToHelper.independentFromGameobject; + } + + public virtual InternalDXXL_BezierControlSubPoint GetNextSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + //-> all children override this + return null; + } + + public virtual InternalDXXL_BezierControlSubPoint GetPreviousSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + //-> all children override this + return null; + } + + public virtual InternalDXXL_BezierControlSubPoint GetNextUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + //-> all children override this + return null; + } + + public virtual InternalDXXL_BezierControlSubPoint GetPreviousUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + //-> all children override this + return null; + } + + public InternalDXXL_BezierControlSubPoint GetNextUsedNonSuperimposedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + InternalDXXL_BezierControlSubPoint currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir = GetNextSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); //-> cannot use "GetNext-USED-SubPointAlongSplineDir()" here in this function, because then an endless-loop-prevention-check is not possible for cases, where this function is called on subPoints which are iself "isUsed=false". + int maxAttempts = 100; + for (int i = 0; i < maxAttempts; i++) + { + if (currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir != null) + { + if (currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir != this) //-> prevent endless loops around closed splines + { + if (currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir.isUsed == true) + { + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(GetPos_inUnitsOfGlobalSpace(), currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace())) + { + currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir = currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir.GetNextSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + else + { + return currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir; + } + } + else + { + currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir = currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir.GetNextSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + } + else + { + return null; + } + } + else + { + return null; + } + } + return null; + } + + public InternalDXXL_BezierControlSubPoint GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + InternalDXXL_BezierControlSubPoint currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir = GetPreviousSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); //-> cannot use "GetPrevious-USED-SubPointAlongSplineDir()" here in this function, because then an endless-loop-prevention-check is not possible for cases, where this function is called on subPoints which are iself "isUsed=false". + int maxAttempts = 100; + for (int i = 0; i < maxAttempts; i++) + { + if (currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir != null) + { + if (currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir != this) //-> prevent endless loops around closed splines + { + if (currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir.isUsed == true) + { + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(GetPos_inUnitsOfGlobalSpace(), currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace())) + { + currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir = currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir.GetPreviousSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + else + { + return currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir; + } + } + else + { + currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir = currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir.GetPreviousSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + } + else + { + return null; + } + } + else + { + return null; + } + } + return null; + } + + public virtual Vector3 GetDirectionAlongSplineForwardBasedOnNeighborPoints_inUnitsOfGlobalSpace() + { + //-> all children override this + //-> not guaranteed normalized + //-> not to be consued with "anchor.Get_direction_to*Helper*()" + return Vector3.forward; + } + + public virtual bool IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid() + { + //-> all children override this + return false; + } + + public static string GetSubPointTypeAsString(SubPointType subPointType_toGetAsString) + { + switch (subPointType_toGetAsString) + { + case SubPointType.backwardHelper: + return "backward weight point"; + case SubPointType.anchor: + return "center point"; + case SubPointType.forwardHelper: + return "forward weight point"; + default: + return "unknown sub point"; + } + } + + public Rect RecalcCurrentRect_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset) + { +#if UNITY_EDITOR + return new Rect(reducedRectForOnlyContentLines.x, reducedRectForOnlyContentLines.y + currentHeightOffset, reducedRectForOnlyContentLines.width, UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return default; +#endif + } + + public Vector3 Draw_Vector3Field_withoutLineBreak_forInspector(Rect position, GUIContent label, Vector3 value, bool allowRichText = false) + { + return Draw_Vector3Field_withoutLineBreak_forInspector(position, out Rect rectForOnlyThePrefixLabel, label, value, allowRichText); + } + + public Vector3 Draw_Vector3Field_withoutLineBreak_forInspector(Rect position, out Rect rectForOnlyThePrefixLabel, GUIContent label, Vector3 value, bool allowRichText = false) + { +#if UNITY_EDITOR + //"EditorGUI.Vector3Field" makes a line break and expands to two lines if the inspector window gets narrow. Therefore this modified version without the line break. + Rect position_forOnlyTheContentValues; + if (allowRichText) + { + GUIStyle styleWithRichText = new GUIStyle(UnityEditor.EditorStyles.label); + styleWithRichText.richText = true; + position_forOnlyTheContentValues = UnityEditor.EditorGUI.PrefixLabel(position, label, styleWithRichText); + } + else + { + position_forOnlyTheContentValues = UnityEditor.EditorGUI.PrefixLabel(position, label); + } + rectForOnlyThePrefixLabel = new Rect(position.x, position.y, position.width - position_forOnlyTheContentValues.width, position.height); + + Vector3 value_after = UnityEditor.EditorGUI.Vector3Field(position_forOnlyTheContentValues, GUIContent.none, value); + return value_after; +#else + rectForOnlyThePrefixLabel = default; + return default; +#endif + } + + public Vector3 position_inUnitsOfActiveDrawSpace_afterInspectorInput; + public void DrawPositionLine_forInspector(Rect rect, GUIContent guiContent) + { + position_inUnitsOfActiveDrawSpace_afterInspectorInput = Draw_Vector3Field_withoutLineBreak_forInspector(rect, guiContent, position_inUnitsOfActiveDrawSpace); + } + + public GameObject boundGameobject_afterInspectorInput; + public void DrawBoundGameobjectLine_forInspector(Rect rect, GUIContent guiContent) + { +#if UNITY_EDITOR + SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + bool boundGameobjectConnetionExists_butIsNotActiveRespEnabled = ((boundGameobject != null) && (connectionComponent_onBoundGameobject != null) && ((boundGameobject.activeInHierarchy == false) || (connectionComponent_onBoundGameobject.enabled == false))); + if (boundGameobjectConnetionExists_butIsNotActiveRespEnabled) + { + Rect rect_forGameobjectPickerAndInactiveNotifier = UnityEditor.EditorGUI.PrefixLabel(rect, guiContent); + float posOfSeparation_0to1 = 0.5f; + Rect rect_gameobjectPickerWithoutLabel = new Rect(rect_forGameobjectPickerAndInactiveNotifier.x, rect_forGameobjectPickerAndInactiveNotifier.y, posOfSeparation_0to1 * rect_forGameobjectPickerAndInactiveNotifier.width, rect_forGameobjectPickerAndInactiveNotifier.height); + Rect rect_forInactiveRespDisabledNotifier = new Rect(rect_forGameobjectPickerAndInactiveNotifier.x + posOfSeparation_0to1 * rect_forGameobjectPickerAndInactiveNotifier.width, rect_forGameobjectPickerAndInactiveNotifier.y, (1.0f - posOfSeparation_0to1) * rect_forGameobjectPickerAndInactiveNotifier.width, rect_forGameobjectPickerAndInactiveNotifier.height); + + boundGameobject_afterInspectorInput = (UnityEngine.GameObject)UnityEditor.EditorGUI.ObjectField(rect_gameobjectPickerWithoutLabel, GUIContent.none, boundGameobject, typeof(UnityEngine.GameObject), true); + if (boundGameobject.activeInHierarchy == false) + { + UnityEditor.EditorGUI.LabelField(rect_forInactiveRespDisabledNotifier, new GUIContent(" is inactive", "The bound gameobject or any of it's parents is set to inactive. As long as this is the case the tieing will not be updated.")); + } + else + { + UnityEditor.EditorGUI.LabelField(rect_forInactiveRespDisabledNotifier, new GUIContent(" is disabled", "The connection component on the bound gameobject is disabled. As long as this is the case the tieing will not be updated.")); + } + } + else + { + boundGameobject_afterInspectorInput = (UnityEngine.GameObject)UnityEditor.EditorGUI.ObjectField(rect, guiContent, boundGameobject, typeof(UnityEngine.GameObject), true); + } +#endif + } + + public string Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector() + { + switch (bezierSplineDrawer_thisSubPointIsPartOf.drawSpace) + { + case BezierSplineDrawer.DrawSpace.global: + return "This value display is in units of the active draw space, which is currently the global space."; + case BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject: + return "This value display is in units of the active draw space, which is currently the local space defined by the gameobject that holds this spline component."; + default: + return ""; + } + } + + public virtual float GetPropertyHeightForInspectorList() + { + //-> all children override this + return 16.0f; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint.cs.meta new file mode 100644 index 0000000..a236f88 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 18f2b3ad5533c3b40bcc75e5750a8d0b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint2D.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint2D.cs new file mode 100644 index 0000000..207bad6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint2D.cs @@ -0,0 +1,510 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + + [Serializable] + public class InternalDXXL_BezierControlSubPoint2D + { + [SerializeField] public bool isUsed; //can be disabled by the user in the control points list inspector (only for kinked junctures), or is automatically disabled for endPoints of non-closed splines + [SerializeField] public Vector2 position_inUnitsOfActiveDrawSpace; + [SerializeField] Vector2 position_inUnitsOfGlobalSpace; + + public BezierSplineDrawer2D bezierSplineDrawer_thisSubPointIsPartOf; + [SerializeField] public int i_ofContainingControlPoint_insideControlPointsList; + public InternalDXXL_BezierControlSubPoint.SubPointType subPointType; + + public GameObject boundGameobject; + public DrawXXLSpline2DConnection connectionComponent_onBoundGameobject; + public bool boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled; + public bool boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled; + + public Quaternion globalRotation_ofPositionHandle = Quaternion.identity; + public bool recalc_globalRotation_ofPositionHandle_duringNextOnSceneGUI = true; + + public int controlID_ofUnityStylePositionHandleUp; + public int controlID_ofUnityStylePositionHandleRight; + + public virtual void InitializeValuesThatAreIndependentFromOtherSubPoints(InternalDXXL_BezierControlPointTriplet2D controlPoint_thisSubPointIsPartOf) + { + boundGameobject = null; + connectionComponent_onBoundGameobject = null; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = false; + i_ofContainingControlPoint_insideControlPointsList = controlPoint_thisSubPointIsPartOf.i_ofThisPoint_insideControlPointsList; + bezierSplineDrawer_thisSubPointIsPartOf = controlPoint_thisSubPointIsPartOf.bezierSplineDrawer_thisPointIsPartOf; + } + + public void ReassignIndexInsideControlPointsList(int new_i) + { + SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); //-> function is dependent on the "old" i. + if (boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled) + { + connectionComponent_onBoundGameobject.i_ofControlPointTriplet_thisGameobjectIsBoundTo = new_i; + } + i_ofContainingControlPoint_insideControlPointsList = new_i; + } + + public InternalDXXL_BezierControlPointTriplet2D Get_controlPointTriplet_thisSubPointIsPartOf() + { + //Serialized lists containing other lists and containing custom classes with cross references don't work well in Unity, even when using the [SerializeReference] attribute. Functions like this try to keep the convenience of a real reference tree. The only "real" reference is the monobehavior-inherited spline component. Everything has to start from there. + return bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets[i_ofContainingControlPoint_insideControlPointsList]; + } + + public void SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled() + { + ///De-assigning connectionComponents is not trivial as soon as it has to comply with the build-in Undo-System. + //Problems: + //The spline-component and the connection-component should only exist together, but they are on independent gameobjects, which the user can delete or copy independently. + //When the spline-component is deleted then also all corresponding connection-componenets should be deleted. + //-> It could be done in "spline.OnDestroy()", but this is not fired always when a component gets destroyed. The Unity docu says the it is not fired when the carrying gameobject is inactive. Though testing it in the Unity Editor showed: It is often called, even when the gameobject is inactive, but it is sometimes omited, even when the gameobject is active. So overall: Not fully reliable. Orphaned connection-components may still remain in the scene, which is not desired. + //-> More reliable than "spline.OnDestroy()" is "spline.OnDisable()", but we don't want to destroy the connection reference just because some disabled a participating component (maybe with the intention to enabled it sometime later) + //-> So the connection components should handle their deletion self contained, as soon as the referncing spline is not there anymore. + //-> This is working fine as long as "Undo" doesn't come into play. + //-> If a boundGameobject gets deleted and then the deletion is reverted via "Editor/Undo", then the two partners (spline-component and connection-component) don't recognize each other anymore as "referenced partners". The reference is lost. This seems to be a Unity bug, see here: https://forum.unity.com/threads/monobehaviour-references-are-lost-on-undo.587011/ and here: https://issuetracker.unity3d.com/issues/gameobject-isnt-set-as-public-variable-after-undo-operation It's an unconvenience but since Unity itself accepts this bug it's hopefully indeed "acceptable". + //-> It can be fixed in the case of spline-deletion (because in "spline.OnDestroy()" the connectionComponents can be deleted by the spline itself (so not following the mentioned "self contained deletion" way)), and along with that the spline can register "Undo.DestroyImmediate()" for the connection-components: In this case the references are correctly reverted after Undo. A similar construction inside "connectionComponent.OnDestroy()" doesn't have the same fixing effect though (see note there). + //-> Another approach would be to not immediately destroy the connection components after spline-deletion, but delay the self contained destruction with a timer, so that the undo-process doesn't have to "recreate them as new instance from serialized data" in the hope that they are then still the "correct reference". But tests showed: It is not the case. It makes no difference and the reference is still lost. + //-> Another approach would be to somehow search the formerly reference component and recreate the reference "OnUndoExecuted". The problem with that is that it is quiete non-intended from Unities paradigm of doing things. Such "hacky interventions" sometimes lead to Editor crashes when shuffling around "Undo/Redo" to and fro. It seems unwieldly and to risky. + //-> Another case where the reference gets lost: "Assign boundGameobject in the inspector" -> "Undo assign" -> "Redo assign" -> reference is lost. + + if (boundGameobject == null) + { + //cases that arrive here: + //-> "boundGameobject" hasnn't been assigned yet + //-> "boundGameobject" was regularly deassgined + //-> "boundGameobject" has been independently deleted (but may come back via "Undo") + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = false; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = false; + } + else + { + if (connectionComponent_onBoundGameobject == null) + { + //cases that arrive here: + //-> the "connectionComponent_onBoundGameobject"-component has been independently deleted from the (still existing) "boundGameobject" (but it may come back via "Undo") + //-> also after "Undo" it sometimes doesn't come back due to the reference lost error described above in this function + //-> assign boundGameobject to a controlSubPoint -> Undo assign -> Redo assign -> connection is not retrieved + boundGameobject = null; + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = false; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = false; + } + else + { + if (connectionComponent_onBoundGameobject.bezierSplineDrawer_thatHasReferencedThisGameobject != bezierSplineDrawer_thisSubPointIsPartOf) + { + //-> The spline component (e.g. along with it's carrying gameobject) has been copied. Both the old spline component and the new spline component here reference the single connection-component on the boundGameobject + //-> The new spline here creates his own additonal connection component on the boundGameobject now: + + CreateConnectionComponentOnBoundGameobject("Auto-create connection after spline copy"); + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = true; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = connectionComponent_onBoundGameobject.isActiveAndEnabled; + } + else + { + // if (connectionComponent_onBoundGameobject.bezierSubPoint_thatHasReferencedThisGameobject != this) //this is not suitable as reference, because in the serialized context "InternalDXXL_BezierControlSubPoint" acts as value type, not as reference type. + if (connectionComponent_onBoundGameobject.i_ofControlPointTriplet_thisGameobjectIsBoundTo != i_ofContainingControlPoint_insideControlPointsList) + { + bezierSplineDrawer_thisSubPointIsPartOf.DeleteConnectionComponentOfBoundGameobject_onControlSubPoint(i_ofContainingControlPoint_insideControlPointsList, subPointType); + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = false; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = false; + UtilitiesDXXL_Log.PrintErrorCode("74-" + connectionComponent_onBoundGameobject.i_ofControlPointTriplet_thisGameobjectIsBoundTo + "-" + i_ofContainingControlPoint_insideControlPointsList + "-" + bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets.Count); + } + else + { + if (connectionComponent_onBoundGameobject.subPointType_whereThisGameobjectIsBoundTo != subPointType) + { + bezierSplineDrawer_thisSubPointIsPartOf.DeleteConnectionComponentOfBoundGameobject_onControlSubPoint(i_ofContainingControlPoint_insideControlPointsList, subPointType); + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = false; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = false; + UtilitiesDXXL_Log.PrintErrorCode("75-" + connectionComponent_onBoundGameobject.subPointType_whereThisGameobjectIsBoundTo + "-" + subPointType + "-" + bezierSplineDrawer_thisSubPointIsPartOf.listOfControlPointTriplets.Count); + } + else + { + boundGameobjectInclConnectionComponent_isAssignedButMayBeInactiveOrDisabled = true; + boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled = connectionComponent_onBoundGameobject.isActiveAndEnabled; + } + } + } + } + } + } + + public void ProcessNewGameobjectAssignment(GameObject newlyAssignedGameobject) + { + if (newlyAssignedGameobject != boundGameobject) + { + if (bezierSplineDrawer_thisSubPointIsPartOf.CheckIf_gameobjectToAssign_isAlreadyAssignedAtAnotherSubPointOfTheSpline(newlyAssignedGameobject, out int i_ofTripletThatContainsTheSubPointThatAlreadyHasTheGameobjectAssigned, out InternalDXXL_BezierControlSubPoint.SubPointType subPointThatAlreadyHasTheGameobjectAssigned)) + { + //This restriction is done to prevent tangled unwieldy cross-dependencies between subPoints. Otherwise numerous cases would need special consideration, e.g.: A gameobject could be bound not only to the backward helper, but also to the forward helper of the same controlPoint triplet. + //Already without this restriction there are overdefined situations: E.g. when different gameobjects are bound to all three subPoints of a triplet, junctureType=kinked, and both helperPoint bind their direction to the same transform direction of the boundGameobject at the center point. + Debug.LogError("Assignment of gameobject (" + newlyAssignedGameobject.name + ") denied, because a gameobject can only be assinged once per spline. It is already assinged at the " + InternalDXXL_BezierControlSubPoint.GetSubPointTypeAsString(subPointThatAlreadyHasTheGameobjectAssigned) + " of control point " + i_ofTripletThatContainsTheSubPointThatAlreadyHasTheGameobjectAssigned + "."); + } + else + { + string nameOfUndoEntry = "Change Spline Gameobject Ref"; + bezierSplineDrawer_thisSubPointIsPartOf.RegisterStateForUndo(nameOfUndoEntry, true, true); + + if (boundGameobject != null) + { + //Deassign old gameobject: + if (connectionComponent_onBoundGameobject != null) + { +#if UNITY_EDITOR + UnityEditor.Undo.DestroyObjectImmediate(connectionComponent_onBoundGameobject); +#endif + } + boundGameobject = null; + connectionComponent_onBoundGameobject = null; + } + + boundGameobject = newlyAssignedGameobject; + + if (newlyAssignedGameobject != null) + { + //Assign new gameobject: + CreateConnectionComponentOnBoundGameobject(nameOfUndoEntry); + } + else + { + ResetDirectionSourceToIndependent(); + } + } + } + } + + void CreateConnectionComponentOnBoundGameobject(string nameOfUndoEntry_forNewlyCreatedComponent) + { +#if UNITY_EDITOR + connectionComponent_onBoundGameobject = UnityEditor.Undo.AddComponent(boundGameobject); + UnityEditor.Undo.RegisterCompleteObjectUndo(connectionComponent_onBoundGameobject, nameOfUndoEntry_forNewlyCreatedComponent); +#else + connectionComponent_onBoundGameobject = boundGameobject.AddComponent(); +#endif + + connectionComponent_onBoundGameobject.componentHasBeenManuallyCreated = false; + connectionComponent_onBoundGameobject.bezierSplineDrawer_thatHasReferencedThisGameobject = bezierSplineDrawer_thisSubPointIsPartOf; + connectionComponent_onBoundGameobject.i_ofControlPointTriplet_thisGameobjectIsBoundTo = i_ofContainingControlPoint_insideControlPointsList; + connectionComponent_onBoundGameobject.subPointType_whereThisGameobjectIsBoundTo = subPointType; + + SetPos_inUnitsOfGlobalSpace(boundGameobject.transform.position, true, boundGameobject); + TryTransferBoundGameobjectsRotationToAnchorPointsDirection(); + } + + public virtual void ResetDirectionSourceToIndependent() + { + } + + public virtual void TryTransferBoundGameobjectsRotationToAnchorPointsDirection() + { + } + + public Vector2 GetPos_inUnitsOfGlobalSpace() + { + return position_inUnitsOfGlobalSpace; + } + + public Vector3 GetPos_inUnitsOfGlobalSpace_asV3DrawPos() + { + return UtilitiesDXXL_DrawBasics2D.Position_V2toV3(position_inUnitsOfGlobalSpace, bezierSplineDrawer_thisSubPointIsPartOf.GetZPos_global_for2D()); + } + + public Vector2 GetPos_inUnitsOfActiveDrawSpace() + { + return position_inUnitsOfActiveDrawSpace; + } + + public virtual void SetPos_inUnitsOfGlobalSpace(Vector2 newPos_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + //all children override this + } + + public Vector2 SetPos_inUnitsOfGlobalSpace_butIgnoreDependentValues_nonRecursively(Vector2 newPos_inUnitsOfGlobalSpace, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + //"_nonRecursively" indicates: This function is reserved to be called inside the overrides of "SetPos_inUnitsOfGlobalSpace". In all other cases use "SetPos_inUnitsOfGlobalSpace(..., false)" + + Vector2 offset_fromPrevious_toNewPosition_inUnitsOfGlobalSpace = newPos_inUnitsOfGlobalSpace - position_inUnitsOfGlobalSpace; + position_inUnitsOfGlobalSpace = newPos_inUnitsOfGlobalSpace; + position_inUnitsOfActiveDrawSpace = bezierSplineDrawer_thisSubPointIsPartOf.TransformPos_fromGlobalSpace_toUnitsOfActiveDrawSpace(newPos_inUnitsOfGlobalSpace); + + SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + if (boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled) + { + if (boundGameobject != boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + boundGameobject.transform.position = new Vector3(newPos_inUnitsOfGlobalSpace.x, newPos_inUnitsOfGlobalSpace.y, boundGameobject.transform.position.z); + } + } + + return offset_fromPrevious_toNewPosition_inUnitsOfGlobalSpace; + } + + public void SetPos_inUnitsOfActiveDrawSpace(Vector2 newPos_inUnitsOfActiveDrawSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector2 newPos_inUnitsOfGlobalSpace = bezierSplineDrawer_thisSubPointIsPartOf.TransformPos_fromUnitsOfActiveDrawSpace_toGlobalSpace(newPos_inUnitsOfActiveDrawSpace); + SetPos_inUnitsOfGlobalSpace(newPos_inUnitsOfGlobalSpace, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void AddPosOffset_inUnitsOfGlobalSpace(Vector2 posOffset_inUnitsOfGlobalSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector2 newPos_inUnitsOfGlobalSpace = GetPos_inUnitsOfGlobalSpace() + posOffset_inUnitsOfGlobalSpace; + SetPos_inUnitsOfGlobalSpace(newPos_inUnitsOfGlobalSpace, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public void AddPosOffset_inUnitsOfActiveDrawSpace(Vector2 posOffset_inUnitsOfActiveDrawSpace, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + Vector2 newPos_inUnitsOfActiveDrawSpace = GetPos_inUnitsOfActiveDrawSpace() + posOffset_inUnitsOfActiveDrawSpace; + SetPos_inUnitsOfActiveDrawSpace(newPos_inUnitsOfActiveDrawSpace, updateDependentValuesOnControlPointTriplet, boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls); + } + + public virtual void Set_direction_toForward_inUnitsOfGlobalSpace_normalized(Vector2 newDirection_toForward_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + //-> is not intended to be called for non-overriding helperPoints. Use "helperPoint.Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized()" instead + UtilitiesDXXL_Log.PrintErrorCode("61"); + } + + public virtual void Set_direction_toBackward_inUnitsOfGlobalSpace_normalized(Vector2 newDirection_toBackward_inUnitsOfGlobalSpace_normalized, bool updateDependentValuesOnControlPointTriplet, GameObject boundGameobjectThatTriggeredThisPosOrDirChange_independentlyFromSplineControls) + { + //-> is not intended to be called for non-overriding helperPoints. Use "helperPoint.Set_direction_fromMountingAnchorToThisHelperPoint_inUnitsOfGlobalSpace_normalized()" instead + UtilitiesDXXL_Log.PrintErrorCode("62"); + } + + public virtual InternalDXXL_BezierControlAnchorSubPoint.JunctureType GetJunctureType() + { + //-> is not intended to be called for non-overriding helperPoints + UtilitiesDXXL_Log.PrintErrorCode("63"); + return InternalDXXL_BezierControlAnchorSubPoint.JunctureType.aligned; + } + + public virtual InternalDXXL_BezierControlHelperSubPoint2D GetForwardHelper() + { + //-> is not intended to be called for non-overriding helperPoints + UtilitiesDXXL_Log.PrintErrorCode("64"); + return null; + } + + public virtual InternalDXXL_BezierControlHelperSubPoint2D GetBackwardHelper() + { + //-> is not intended to be called for non-overriding helperPoints + UtilitiesDXXL_Log.PrintErrorCode("65"); + return null; + } + + public virtual InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D Get_sourceOf_directionToHelper_unifiedTowardsForwardForCaseNonKinked() + { + //-> is not intended to be called for non-overriding helperPoints + UtilitiesDXXL_Log.PrintErrorCode("66"); + return InternalDXXL_BezierControlAnchorSubPoint2D.SourceOf_directionToHelper2D.independentFromGameobject; + } + + public virtual InternalDXXL_BezierControlSubPoint2D GetNextSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + //-> all children override this + return null; + } + + public virtual InternalDXXL_BezierControlSubPoint2D GetPreviousSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + //-> all children override this + return null; + } + + public virtual InternalDXXL_BezierControlSubPoint2D GetNextUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + //-> all children override this + return null; + } + + public virtual InternalDXXL_BezierControlSubPoint2D GetPreviousUsedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + //-> all children override this + return null; + } + + public InternalDXXL_BezierControlSubPoint2D GetNextUsedNonSuperimposedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + InternalDXXL_BezierControlSubPoint2D currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir = GetNextSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); //-> cannot use "GetNext-USED-SubPointAlongSplineDir()" here in this function, because then an endless-loop-prevention-check is not possible for cases, where this function is called on subPoints which are iself "isUsed=false". + int maxAttempts = 100; + for (int i = 0; i < maxAttempts; i++) + { + if (currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir != null) + { + if (currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir != this) //-> prevent endless loops around closed splines + { + if (currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir.isUsed == true) + { + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(GetPos_inUnitsOfGlobalSpace(), currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace())) + { + currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir = currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir.GetNextSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + else + { + return currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir; + } + } + else + { + currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir = currentCandidateFor_nextUsedNonSuperimposedSubPointAlongSplineDir.GetNextSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + } + else + { + return null; + } + } + else + { + return null; + } + } + return null; + } + + public InternalDXXL_BezierControlSubPoint2D GetPreviousUsedNonSuperimposedSubPointAlongSplineDir(bool allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet) + { + InternalDXXL_BezierControlSubPoint2D currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir = GetPreviousSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); //-> cannot use "GetPrevious-USED-SubPointAlongSplineDir()" here in this function, because then an endless-loop-prevention-check is not possible for cases, where this function is called on subPoints which are iself "isUsed=false". + int maxAttempts = 100; + for (int i = 0; i < maxAttempts; i++) + { + if (currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir != null) + { + if (currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir != this) //-> prevent endless loops around closed splines + { + if (currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir.isUsed == true) + { + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(GetPos_inUnitsOfGlobalSpace(), currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir.GetPos_inUnitsOfGlobalSpace())) + { + currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir = currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir.GetPreviousSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + else + { + return currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir; + } + } + else + { + currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir = currentCandidateFor_previousUsedNonSuperimposedSubPointAlongSplineDir.GetPreviousSubPointAlongSplineDir(allowRequestingControlPointAsResult_inCaseOfRingSplineOfOnlyOneControlPointTriplet); + } + } + else + { + return null; + } + } + else + { + return null; + } + } + return null; + } + + public virtual Vector2 GetDirectionAlongSplineForwardBasedOnNeighborPoints_inUnitsOfGlobalSpace() + { + //-> all children override this + //-> not guaranteed normalized + //-> not to be consued with "anchor.Get_direction_to*Helper*()" + return Vector2.right; + } + + public virtual bool IsUnusedHelperPointAtStartOrEndOfUnclosedSplines_onTheControlPointSideTowardsVoid() + { + //-> all children override this + return false; + } + + public Rect RecalcCurrentRect_forInspector(Rect reducedRectForOnlyContentLines, float currentHeightOffset) + { +#if UNITY_EDITOR + return new Rect(reducedRectForOnlyContentLines.x, reducedRectForOnlyContentLines.y + currentHeightOffset, reducedRectForOnlyContentLines.width, UnityEditor.EditorGUIUtility.singleLineHeight); +#else + return default; +#endif + } + + public Vector2 Draw_Vector2Field_withoutLineBreak_forInspector(Rect position, GUIContent label, Vector2 value, bool allowRichText = false) + { + return Draw_Vector2Field_withoutLineBreak_forInspector(position, out Rect rectForOnlyThePrefixLabel, label, value, allowRichText); + } + + public Vector2 Draw_Vector2Field_withoutLineBreak_forInspector(Rect position, out Rect rectForOnlyThePrefixLabel, GUIContent label, Vector2 value, bool allowRichText = false) + { +#if UNITY_EDITOR + //"EditorGUI.Vector2Field" makes a line break and expands to two lines if the inspector window gets narrow. Therefore this modified version without the line break. + Rect position_forOnlyTheContentValues; + if (allowRichText) + { + GUIStyle styleWithRichText = new GUIStyle(UnityEditor.EditorStyles.label); + styleWithRichText.richText = true; + position_forOnlyTheContentValues = UnityEditor.EditorGUI.PrefixLabel(position, label, styleWithRichText); + } + else + { + position_forOnlyTheContentValues = UnityEditor.EditorGUI.PrefixLabel(position, label); + } + rectForOnlyThePrefixLabel = new Rect(position.x, position.y, position.width - position_forOnlyTheContentValues.width, position.height); + + Vector2 value_after = UnityEditor.EditorGUI.Vector2Field(position_forOnlyTheContentValues, GUIContent.none, value); + return value_after; +#else + rectForOnlyThePrefixLabel = default; + return default; +#endif + } + + public Vector2 position_inUnitsOfActiveDrawSpace_afterInspectorInput; + public void DrawPositionLine_forInspector(Rect rect, GUIContent guiContent) + { + position_inUnitsOfActiveDrawSpace_afterInspectorInput = Draw_Vector2Field_withoutLineBreak_forInspector(rect, guiContent, position_inUnitsOfActiveDrawSpace); + } + + public GameObject boundGameobject_afterInspectorInput; + public void DrawBoundGameobjectLine_forInspector(Rect rect, GUIContent guiContent) + { +#if UNITY_EDITOR + SetBoolOf_boundGameobjectInclConnectionComponent_isAssignedActiveAndEnabled(); + bool boundGameobjectConnetionExists_butIsNotActiveRespEnabled = ((boundGameobject != null) && (connectionComponent_onBoundGameobject != null) && ((boundGameobject.activeInHierarchy == false) || (connectionComponent_onBoundGameobject.enabled == false))); + if (boundGameobjectConnetionExists_butIsNotActiveRespEnabled) + { + Rect rect_forGameobjectPickerAndInactiveNotifier = UnityEditor.EditorGUI.PrefixLabel(rect, guiContent); + float posOfSeparation_0to1 = 0.5f; + Rect rect_gameobjectPickerWithoutLabel = new Rect(rect_forGameobjectPickerAndInactiveNotifier.x, rect_forGameobjectPickerAndInactiveNotifier.y, posOfSeparation_0to1 * rect_forGameobjectPickerAndInactiveNotifier.width, rect_forGameobjectPickerAndInactiveNotifier.height); + Rect rect_forInactiveRespDisabledNotifier = new Rect(rect_forGameobjectPickerAndInactiveNotifier.x + posOfSeparation_0to1 * rect_forGameobjectPickerAndInactiveNotifier.width, rect_forGameobjectPickerAndInactiveNotifier.y, (1.0f - posOfSeparation_0to1) * rect_forGameobjectPickerAndInactiveNotifier.width, rect_forGameobjectPickerAndInactiveNotifier.height); + + boundGameobject_afterInspectorInput = (UnityEngine.GameObject)UnityEditor.EditorGUI.ObjectField(rect_gameobjectPickerWithoutLabel, GUIContent.none, boundGameobject, typeof(UnityEngine.GameObject), true); + if (boundGameobject.activeInHierarchy == false) + { + UnityEditor.EditorGUI.LabelField(rect_forInactiveRespDisabledNotifier, new GUIContent(" is inactive", "The bound gameobject or any of it's parents is set to inactive. As long as this is the case the tieing will not be updated.")); + } + else + { + UnityEditor.EditorGUI.LabelField(rect_forInactiveRespDisabledNotifier, new GUIContent(" is disabled", "The connection component on the bound gameobject is disabled. As long as this is the case the tieing will not be updated.")); + } + } + else + { + boundGameobject_afterInspectorInput = (UnityEngine.GameObject)UnityEditor.EditorGUI.ObjectField(rect, guiContent, boundGameobject, typeof(UnityEngine.GameObject), true); + } +#endif + } + + public string Get_tooltip_explainingWheatherUnitsAreInGlobalOrInLocalSpace_forInspector() + { + switch (bezierSplineDrawer_thisSubPointIsPartOf.drawSpace) + { + case BezierSplineDrawer.DrawSpace.global: + return "This value display is in units of the active draw space, which is currently the global space."; + case BezierSplineDrawer.DrawSpace.localDefinedByThisGameobject: + return "This value display is in units of the active draw space, which is currently the local space defined by the gameobject that holds this spline component."; + default: + return ""; + } + } + + public virtual float GetPropertyHeightForInspectorList() + { + //-> all children override this + return 16.0f; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint2D.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint2D.cs.meta new file mode 100644 index 0000000..39bbdd9 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierControlSubPoint2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d39fe386fc63a5040986d0ecd2cf7c87 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierHandles.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierHandles.cs new file mode 100644 index 0000000..e656b39 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierHandles.cs @@ -0,0 +1,104 @@ +namespace DrawXXL +{ + using UnityEngine; + +#if UNITY_EDITOR + using UnityEditor; + + public class InternalDXXL_BezierHandles + { + static float valueToSlide_duringMouseDown; + static Vector3 direction_duringMouseDown; + static Vector2 currentMousePosition; + static Vector2 mousePosition_duringMouseDown; + + public static float ValueSliderAlongCurve(float valueToSlide, Vector3 position, Quaternion rotation, Vector3 direction_duringMouseDown, float size, Handles.CapFunction capFunction, float snap) + { + int control_ID = GUIUtility.GetControlID(FocusType.Passive); + Event currentEvent = Event.current; + switch (currentEvent.GetTypeForControl(control_ID)) + { + case EventType.MouseDown: + if ((HandleUtility.nearestControl == control_ID) && (currentEvent.button == 0) && (currentEvent.alt == false)) + { + GUIUtility.hotControl = control_ID; + valueToSlide_duringMouseDown = valueToSlide; + mousePosition_duringMouseDown = currentEvent.mousePosition; + currentMousePosition = currentEvent.mousePosition; + InternalDXXL_BezierHandles.direction_duringMouseDown = direction_duringMouseDown; + currentEvent.Use(); + EditorGUIUtility.SetWantsMouseJumping(1); + } + break; + case EventType.MouseUp: + if (GUIUtility.hotControl == control_ID) + { + GUIUtility.hotControl = 0; + currentEvent.Use(); + EditorGUIUtility.SetWantsMouseJumping(0); + } + break; + case EventType.MouseDrag: + if (GUIUtility.hotControl == control_ID) + { + currentMousePosition = currentMousePosition + currentEvent.delta; + float travelledDistance_alongDirection = HandleUtility.CalcLineTranslation(mousePosition_duringMouseDown, currentMousePosition, position, InternalDXXL_BezierHandles.direction_duringMouseDown) / size; + float slideSpeed = 0.1f; + valueToSlide = (Handles.SnapValue(travelledDistance_alongDirection * slideSpeed, snap) + 1.0f) * valueToSlide_duringMouseDown; + GUI.changed = true; + currentEvent.Use(); + } + break; + case EventType.Repaint: + Color color_before = Handles.color; + if (control_ID == GUIUtility.hotControl) + { + Handles.color = Handles.selectedColor; + } + else + { + if (IsHovering(control_ID, currentEvent)) + { + Handles.color = Handles.preselectionColor; + } + } + capFunction(control_ID, position, rotation, size, EventType.Repaint); + Handles.color = color_before; + break; + case EventType.Layout: + capFunction(control_ID, position, rotation, size, EventType.Layout); + break; + default: + break; + } + return valueToSlide; + } + + static bool IsHovering(int control_ID, Event currentEvent) + { + return ((GUIUtility.hotControl == 0) && (control_ID == HandleUtility.nearestControl) && (currentEvent.alt == false)); + } + + public static bool PlusButton(Vector3 position_inUnitsOfGlobalSpace, float sizeScaleFactor, Color color, Vector3 buttonPlaneNormalAwayFromObserver_normalized, Vector3 buttonPlaneUp_normalized, Vector3 buttonPlaneRight_normalized, GUIContent plusSymbolIcon) + { + Quaternion rotation_ofButton = Quaternion.LookRotation(buttonPlaneNormalAwayFromObserver_normalized, Vector3.zero); + float unmodified_handleSize = HandleUtility.GetHandleSize(position_inUnitsOfGlobalSpace); + float radius_ofButton = 0.5f * sizeScaleFactor * unmodified_handleSize; //"0.5f" factor because "Handles.CircleHandleCap" as a 2D cap seems to interpret the specified size as "radius" differently form the 3D caps that interpret it as "diameter". + + Handles.color = color; + Handles.DrawSolidDisc(position_inUnitsOfGlobalSpace, buttonPlaneNormalAwayFromObserver_normalized, radius_ofButton); + + float shiftOffset_ofPlusSign = 0.09375f * unmodified_handleSize; + Vector3 posOfPlusSign_inUnitsOfGlobalSpace = position_inUnitsOfGlobalSpace + shiftOffset_ofPlusSign * buttonPlaneUp_normalized - shiftOffset_ofPlusSign * buttonPlaneRight_normalized; + Handles.Label(posOfPlusSign_inUnitsOfGlobalSpace, plusSymbolIcon); + + Handles.color = UtilitiesDXXL_Colors.GetSimilarColorWithOtherBrightnessValue(color); + bool buttonHasBeenClicked = Handles.Button(position_inUnitsOfGlobalSpace, rotation_ofButton, radius_ofButton, radius_ofButton, Handles.CircleHandleCap); + + return buttonHasBeenClicked; + } + + } + +#endif +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierHandles.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierHandles.cs.meta new file mode 100644 index 0000000..e0c5c7a --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierHandles.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 726506d8e0118b84b87cf0c292ef0dd5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig.cs new file mode 100644 index 0000000..ccf3f5a --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig.cs @@ -0,0 +1,14 @@ +namespace DrawXXL +{ + using UnityEngine; + public struct InternalDXXL_BezierPointShapeConfig + { + public Vector3 anchorPos; + public Vector3 direction_toForward_normalized; + public Vector3 direction_toBackward_normalized; + public Vector3 forwardHelperPos; + public float absDistanceToForwardAnchorPoint; + public Vector3 backwardHelperPos; + public float absDistanceToBackwardAnchorPoint; + } +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig.cs.meta new file mode 100644 index 0000000..65d27ac --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 79065652a54ba324ba727f6328bf5481 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig2D.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig2D.cs new file mode 100644 index 0000000..f3cb27f --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig2D.cs @@ -0,0 +1,14 @@ +namespace DrawXXL +{ + using UnityEngine; + public struct InternalDXXL_BezierPointShapeConfig2D + { + public Vector2 anchorPos; + public Vector2 direction_toForward_normalized; + public Vector2 direction_toBackward_normalized; + public Vector2 forwardHelperPos; + public float absDistanceToForwardAnchorPoint; + public Vector2 backwardHelperPos; + public float absDistanceToBackwardAnchorPoint; + } +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig2D.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig2D.cs.meta new file mode 100644 index 0000000..bebf67c --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_BezierPointShapeConfig2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd1c9a582882a384ab476c5943ed8da3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_TaggedScreenspaceObject.cs b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_TaggedScreenspaceObject.cs new file mode 100644 index 0000000..86924c5 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_TaggedScreenspaceObject.cs @@ -0,0 +1,34 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + + [Serializable] + public struct InternalDXXL_TaggedScreenspaceObject + { + [SerializeField] public GameObject previousGameobject; + [SerializeField] public GameObject gameobject; + [SerializeField] public Color color; + [SerializeField] public string text; + + public void TryUseSeededColorFromGameobjectID() + { + if (gameobject != null) + { + if (previousGameobject == null) + { + color = SeededColorGenerator.ColorOfGameobjectID(gameobject); + } + else + { + if (gameobject != previousGameobject) + { + color = SeededColorGenerator.ColorOfGameobjectID(gameobject); + } + } + } + previousGameobject = gameobject; + } + + } +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_TaggedScreenspaceObject.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_TaggedScreenspaceObject.cs.meta new file mode 100644 index 0000000..14deccf --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/InternalDXXL_TaggedScreenspaceObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8387cf011e2b3aa448179012ee17f256 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/PhysicsVisualizerEnums.cs b/Runtime/DrawDebugLibrary/components/internal utilities/PhysicsVisualizerEnums.cs new file mode 100644 index 0000000..b337fd5 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/PhysicsVisualizerEnums.cs @@ -0,0 +1,5 @@ +namespace DrawXXL +{ + public enum CollisionType { cast, overlap } + public enum WantedHits { onlyFirst, all } +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/PhysicsVisualizerEnums.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/PhysicsVisualizerEnums.cs.meta new file mode 100644 index 0000000..f3cf173 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/PhysicsVisualizerEnums.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab3fba1529d5b72409dd80db32977a1d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/UtilitiesDXXL_Components.cs b/Runtime/DrawDebugLibrary/components/internal utilities/UtilitiesDXXL_Components.cs new file mode 100644 index 0000000..f12b46b --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/UtilitiesDXXL_Components.cs @@ -0,0 +1,186 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_Components + { + public static int frameCount_forWhichAnEditorFrameStep_hasBeenSheduled_byAChart = -10; //this could also be a member of the chart components itself, but then multiple frame steps will be executed onPause if multiple charts exist in the scene. + public static int frameCount_forWhichAnEditorFrameStep_hasBeenSheduled_byADrawerComponent = -10; //this could also be a member of the drawer components itself, but then multiple frame steps will be executed onPause if multiple drawer components exist in the scene. + + public static void TryProceedOneSheduledFrameStep() + { +#if UNITY_EDITOR + //sidenote: + //-> it seems that "EditorApplication.Step()" cannot be called from inside "OnDrawGizmos". Unity prints several errors surrounding the problem "recursive OnGUI rendering". + //-> it works without errors when called from a "EditorApplication.update"-delegate + //-> multiple components that call this function still result in only one frame step, because after "UnityEditor.EditorApplication.Step()" the "Time.frameCount" is not the same any more. + + if (UnityEditor.EditorApplication.isPlaying && UnityEditor.EditorApplication.isPaused) + { + bool hasAlreadyStepped_dueToTheFlagConcerningCharts = false; + + if (DrawCharts.chartInspectorComponentsAutomaticallyProceedOneFrameStepOnPauseStarts_toPreventFrozenOverlayDraw) + { + if (frameCount_forWhichAnEditorFrameStep_hasBeenSheduled_byAChart == Time.frameCount) + { + hasAlreadyStepped_dueToTheFlagConcerningCharts = true; + UnityEditor.EditorApplication.Step(); + } + } + + if (DrawBasics.drawerComponentsAutomaticallyProceedOneFrameStepOnPauseStarts_toPreventFrozenOverlayDraw) + { + if (hasAlreadyStepped_dueToTheFlagConcerningCharts == false) + { + if (frameCount_forWhichAnEditorFrameStep_hasBeenSheduled_byADrawerComponent == Time.frameCount) + { + UnityEditor.EditorApplication.Step(); + } + } + } + } +#endif + } + + public static float Get_inspector_singleLineHeightInclSpacingBetweenLines() + { +#if UNITY_EDITOR + return (UnityEditor.EditorGUIUtility.singleLineHeight + UnityEditor.EditorGUIUtility.standardVerticalSpacing); +#else + return 18.0f; +#endif + } + + static List id_ofMonobehavioursThatDrawViaOnDrawGizmos = new List(); +#if UNITY_EDITOR + static int highestUsed_i_inMonoBList_sinceLastDrawnLinesCounterReset = -1; +#endif + public static bool currentVirtualOnDrawGizmoCycle_shouldRepaintAllViews = false; + public static int virtualGizmoCycleCount; + + public static void ReportOnDrawGizmosCycleOfAMonoBehaviour(int id_ofReportingMonoB) + { +#if UNITY_EDITOR + + ///Problem: + //The maxLinesPerFrame-limit to prevent editor freezing during playmode depends on "Time.frameCount" + //outside playmode or inside playmodePauses "Time.frameCount" is not reliable + + //These are the currently known options for an maxLinesPerFrame-limit outside (nonPaused)playmode: + + ///Using "Time.frameCount" + //-> it is not incremented in pause phases + //-> it is sometimes incremented in edit mode, and sometimes not. Is not reliable and not documented by Unity for edit mode. + + ///Using "Time.renderedFrameCount" + //-> according to forum posts this is incremented in pause phases. I couldn't reproduce this: It didn't increment during pauses in my case + //-> it is not documented by Unity and could change it's behaviour without notice, or even disappear completely + + ///Using "EditorApplication.timeSinceStartup" + //-> as "Time.realtimeSinceStartup" it is dependent from the platform and may sometimes not update regularly. + //-> doesn't help anyway, because it measures "time", but doesn't say anything about when a new OnDrawGizmos-cycle starts. E.g. allowing a limitedNumberOfLines(L) inside a timespan(x) doesn't prevent Editor freeze, because the drawnLines itself can raise the OnDrawGizmos-executionTime, and then after the timespan(x) has passed (but still inside the same OnDrawGizmo) a new set of limitedNumberOfLines(L) is allowed to be drawn, raising the execution time of the current OnDrawGizmo once again. This can endlessly repeat in the same OnDrawGizmos and freeze the Editor. + + ///Using a registered callback from "EditorApplication.update" + //-> EditorApplication.update has no guaranteed frequency and can (according to Unitys documentation) be called multiple times per frame update. + //-> It would still need a managing object that oversees all drawing MonoBehaviours (like this class here) + //-> Cannot be used for static-only drawing, but needs a MonoBehaviour in the scene. Or doesn't it? -> https://docs.unity3d.com/Manual/RunningEditorCodeOnLaunch.html + + ///Each drawing MonoBehaviour resets the counter after his own draw operation + //-> is at least SOME protection, because + //---> it will work if a single drawnObject exceeds the limit by itself + //---> it will not work if multiple drawnObject exceeds the limit with their cumulated lines + //---> though in most cases new drawingBehaviours will get added "gradually", so the editor slow down is also gradually and the user will notice that something is going wrong, so he can at least react. That may be acceptable, because the maxLines-limit is not for preventing slowdown, but for preventing freeze that forces the user to forceQuit the whole Unity application. + //It is similar in the special case of Charts: + //-> "OnDrawGizmos()" gets called for every existing "DrawXXLChartInspector"-gameObject in the scene, so the maxAllowedLinesPerFrame get summed up and become "maxLinesPerFrameLimit * chartsThatAreCurrentlyInspectedViaComponent" + //-> In many cases this should be no problem, because if a user calls "CreateChartInspectionGameobject(true)" for multiple charts at once then he has drawn them before the pause already all inside "Update()" (where the maxLinesPerFrame-limit works correctly), so the maxLinesPerFrame-limit would have spoken already. + //-> The loophole is this: + //---> The maxLinesLimit has not spoken before the pause because only a small section of the lines were displayed. Then during pause the user zooms out to display more. + //---> But there is still a security: + //-----> 1) If the user raises the linesPerChart very fast for 1 chart: Then the maxLinesLimit kicks in for this chart and prevents performance freezing. + //-----> 2) If he raises the linesPerChart for one chart after another to slighly below the maxLinesPerFrame limit, then it's a "gradual performance slowdown". He will realize it and stop the process before the whole system freezes. + + ///Central MonoBehaviour-OnDrawGizmosCalls-managingClass [= implemented solution below] + //-> the linesCounter gets reset as soon as any drawing MonoBehaviour comes back for a second draw (each MonoBehaviour reports only once inside its OnDrawGizmos. Custom MonoBehaviours from users don't participate in this, but are represented by the "DrawXXL_LinesManager"-singleton). In the meantime other drawing MonoBehaviour may have drawn. This is in most cases one OnDrawGizmo-cycle + //-> the execution order of different MonoBehaviour types stays the same according to https://docs.unity3d.com/Manual/class-MonoManager.html + //-> if there is still a mixup of the order of MonoBehaviours then the introduced error is not big, assumed to be not more than factor 2. This is still ok in respect of the purpose of the whole maxLines-mechanic, which is not preventing "editor-slowdown" (which is annoying but can be handled), but preventing "editor-freeze" (which may force the user to force-quit the whole Unity application). + //-> using only the DrawXXL_LinesManager may be not sufficient, since its "OnDrawGizmos()" event is not guaranteed to be fired always. (sidenote: It may be guaranteed due to "ExpandComponentInInspector") + + + for (int i = 0; i <= highestUsed_i_inMonoBList_sinceLastDrawnLinesCounterReset; i++) + { + if (id_ofMonobehavioursThatDrawViaOnDrawGizmos[i] == id_ofReportingMonoB) + { + highestUsed_i_inMonoBList_sinceLastDrawnLinesCounterReset = -1; + InitializeNewVirtualOnDrawGizmoCycle(); + break; + } + } + + highestUsed_i_inMonoBList_sinceLastDrawnLinesCounterReset++; + if (id_ofMonobehavioursThatDrawViaOnDrawGizmos.Count <= highestUsed_i_inMonoBList_sinceLastDrawnLinesCounterReset) + { + id_ofMonobehavioursThatDrawViaOnDrawGizmos.Add(id_ofReportingMonoB); + } + else + { + id_ofMonobehavioursThatDrawViaOnDrawGizmos[highestUsed_i_inMonoBList_sinceLastDrawnLinesCounterReset] = id_ofReportingMonoB; + } +#endif + } + + static void InitializeNewVirtualOnDrawGizmoCycle() + { + TryRepaintAllViews(); //this is called BEFORE "ResetLinesPerFrameCounter()", because it needs an uncleared "DrawnLinesSinceFrameStart" value + DXXLWrapperForUntiysBuildInDrawLines.ResetLinesPerFrameCounter(); + virtualGizmoCycleCount++; + if (Application.isPlaying == false) { virtualGizmoCycleCount = 0; } //-> not used outside playmode + } + + static void TryRepaintAllViews() + { +#if UNITY_EDITOR + //-> The scene view and game view windows are continuously repainted during playmode + //-> Though during edit mode or game pauses they are not + //-> The drawn shapes should continuously be updated on the screen, also outside playmode: Think of a "BoolDisplayer". It should always show the most current value. Also any simple line can change its position and should appear with its current shape. + //-> It is expensive, but doing it inside "InitializeNewVirtualOnDrawGizmoCycle()" at least ensures that it is called only once per OnDrawGizmo-cycle. + //-> And "currentVirtualOnDrawGizmoCycle_shouldRepaintAllViews" prevents some more repaints, mostly by detecting if the drawn lines came from user code calls and not by drawer components. Drawer components anyway automatically repaint the views, but only if their drawn shape as changed/one of their inspector values has changed. + + if (currentVirtualOnDrawGizmoCycle_shouldRepaintAllViews) + { + if ((UnityEditor.EditorApplication.isPlaying == false) || UnityEditor.EditorApplication.isPaused) + { + if (DXXLWrapperForUntiysBuildInDrawLines.DrawnLinesSinceFrameStart > 0) + { + UnityEditorInternal.InternalEditorUtility.RepaintAllViews(); + } + } + } + currentVirtualOnDrawGizmoCycle_shouldRepaintAllViews = false; +#endif + } + + public static void ExpandComponentInInspector(MonoBehaviour componentToExpand) + { + //Reference: https://answers.unity.com/questions/801692/query-whether-inspector-is-folded.html + //-> The problem is that "OnDrawGizmos()" (and along with it all Gizmo lines) is only fired when the component is expanded in the inspector. The gameobject doesn't have to be selected, but the component has to be expanded (that means you have to "leave" the selected gameobject (via selecting an other gameobject) also in a moment where the component is expanded). + //-> This disturbs drawing in edit mode. The components already have toggles for "enable/disable" and "draw only if selected", but on top of this the user has to be aware of this "component has to be expanded"-requirement, and may be irritated why his drawer component stops working sometimes. + //-> It gets more irritating for the user if the DrawXXL_LinesManager component is collapsed due to whatever reason, because then the user isn't event working with components but only with static code calls. + //-> The reference link above describes two approaches how to force a component to "expanded": One is via "UnityEditorInternal.InternalEditorUtility.SetIsInspectorExpanded()", the other is more complicated via reflection. + //-> Luckily it turns out that: The "UnityEditorInternal.InternalEditorUtility.SetIsInspectorExpanded()" function doesn't work for it's "actual task", that means it doesn't expand the components, BUT: It seems to do something in the background, which solves the actual problem here: Despite the components expanded state seeming to be not affected in the visual appearance of the inspector, the "OnDrawGizmos()"-function DOES think that it is expanded and does fire. + //-> This is even better than forcing the visual appearance in the inspector, because now the ability for the user to collapse or expand the component is preserved. + //-> There seem to be situations, where this "hidden" expanded state does transform to be "really expanding the components also visually". One such situation is when a new additional component (of any (other) type) is added to the gameobject. This may be a downside of the solution: It could annoy the user that he has to manually collapse the components over and over again, when he wants them to not take display space in the inspector. + //---> One such situation is when a new additional component (of any (other) type) is added to the gameobject + //---> Also when a component is removed + //---> Restarting the Unity Editor (which by the way means, that this "hidden expanded state" is preserved even when the Unity Editor is closed) + //-> This "hidden expanded" state seems also not to get overwritten when the component is collapsed via mouse click on the small triangle symbol in the top left corner of the component inspector window. Or else it could be that it does get overwritten in this case, but "OnDrawGizmos" may get called one last time and rescues the expanded state by once again calling "ExpandComponentInInspector()" + //-> Though some uncertainty remains if this solution will always work, also in future versions of Unity, because it's an undocumented feaure. + +#if UNITY_EDITOR + UnityEditorInternal.InternalEditorUtility.SetIsInspectorExpanded(componentToExpand, true); +#endif + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/UtilitiesDXXL_Components.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/UtilitiesDXXL_Components.cs.meta new file mode 100644 index 0000000..827b267 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/UtilitiesDXXL_Components.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43f29088c00ea5440949ad9ee2895f37 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerParent.cs b/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerParent.cs new file mode 100644 index 0000000..d36f09e --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerParent.cs @@ -0,0 +1,1586 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Internal Not For Manual Creation/Visualizer Parent")] + [ExecuteInEditMode] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class VisualizerParent : MonoBehaviour //has "parent" in it's name despite beeing already apparent through the code structure: For better orientation in the Unity Editor Component Picker list. + { + [SerializeField] bool drawOnlyIfSelected = DrawBasics.initial_drawOnlyIfSelected_forComponents; //has no effect in builds + [SerializeField] public bool hiddenByNearerObjects = true; + [SerializeField] public int drawnLinesPerPass; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool drawPosOffset3DSection_isOutfolded = false; + [SerializeField] Vector3 drawPosOffset3D_global = Vector3.zero; + [SerializeField] Vector3 drawPosOffset3D_local = Vector3.zero; + [SerializeField] public bool drawPosOffset3DSection_isOutfolded_independentAlternativeValue = false; + [SerializeField] Vector3 drawPosOffset3D_global_independentAlternativeValue = Vector3.zero; + [SerializeField] Vector3 drawPosOffset3D_local_independentAlternativeValue = Vector3.zero; + [SerializeField] public bool drawPosOffset2DSection_isOutfolded = false; + [SerializeField] Vector2 drawPosOffset2D_global = Vector2.zero; + [SerializeField] Vector2 drawPosOffset2D_local = Vector2.zero; + [SerializeField] public bool drawPosOffset2DSection_isOutfolded_independentAlternativeValue = false; + [SerializeField] Vector2 drawPosOffset2D_global_independentAlternativeValue = Vector2.zero; + [SerializeField] Vector2 drawPosOffset2D_local_independentAlternativeValue = Vector2.zero; + + //Foldouts: + [SerializeField] public bool textSection_isOutfolded = false; + [SerializeField] public bool textStyleSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool textMarkupHelperSection_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + //Text: + public string text_exclGlobalMarkupTags; + public string text_inclGlobalMarkupTags; + + [SerializeField] public bool globalText_isBold = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool globalText_isItalic = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool globalText_isUnderlined = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool globalText_isDeleted = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool globalText_isSizeModified = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool globalText_isColorModified = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool globalText_isStrokeWidthModified = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public float curr_sizeScaleFactor_forGlobalMarkup = 1.0f; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public Color curr_color_forGlobalMarkup = Color.red; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public float curr_strokeWidthSize0to1_forGlobalMarkup = 0.333333f; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + [SerializeField] public bool markupSnippetText_isBold = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool markupSnippetText_escapesBold = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool markupSnippetText_isItalic = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool markupSnippetText_escapesItalic = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool markupSnippetText_isUnderlined = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool markupSnippetText_escapesUnderlined = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool markupSnippetText_isDeleted = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool markupSnippetText_escapesDeleted = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool markupSnippetText_isSizeModified = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool markupSnippetText_isColorModified = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool markupSnippetText_isStrokeWidthModified = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public float curr_sizeScaleFactor_forMarkupSnippet = 1.0f; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public Color curr_color_forMarkupSnippet = Color.red; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public float curr_strokeWidthSize0to1_forMarkupSnippet = 0.333333f; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + public enum TextMarkupInputSnippetOptions { text, icon, logSymbol, customHeightEmptyLine, lineBreak }; + [SerializeField] public TextMarkupInputSnippetOptions curr_textMarkupInputSnippetOptions = TextMarkupInputSnippetOptions.text; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public string textSnippet_toPutInMarkupTags = "input text snippet"; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public string resultTextSnippet_insideMarkupTags_forTextInput = "input text snippet"; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public string resultTextSnippet_insideMarkupTags_forIconInput = DrawText.MarkupIcon(DrawBasics.IconType.heart); //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public string resultTextSnippet_insideMarkupTags_forCustomHeightEmptyLineInput = DrawText.MarkupCustomHeightEmptyLine(1.0f); //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public string resultTextSnippet_insideMarkupTags_forLogSymbolInput = DrawText.MarkupLogSymbol(LogType.Log); //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public DrawBasics.IconType curr_iconType_forMarkupCreator = DrawBasics.IconType.heart; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] [Range(0.1f, 10.0f)] public float curr_heightOfEmptyLine_forMarkupCreator = 1.0f; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public LogType curr_logType_forMarkupCreator = LogType.Log; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + [SerializeField] public float endPlates_size = 0.0f; + [SerializeField] public DrawBasics.LengthInterpretation endPlates_sizeInterpretation = DrawBasics.endPlates_sizeInterpretation; + [SerializeField] public bool endPlates_size_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public float coneLength_forStraightVectors = 0.17f; + [SerializeField] public DrawBasics.LengthInterpretation coneLength_interpretation_forStraightVectors = DrawBasics.coneLength_interpretation_forStraightVectors; + [SerializeField] public bool coneLength_forStraightVectors_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public float coneLength_forCircledVectors = 0.17f; + [SerializeField] public DrawBasics.LengthInterpretation coneLength_interpretation_forCircledVectors = DrawBasics.coneLength_interpretation_forCircledVectors; + [SerializeField] public bool coneLength_forCircledVectors_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + [Tooltip("Force wireMesh rendering mode in Game view during Play mode.\nToggle ON if you cannot see the visualization in the Game view.")] + [SerializeField] public bool useWireMeshInLateUpdate = false; + + [SerializeField] public bool customZPos_for2D_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + public enum ZPosSource { transformPositionPlusOffset, setAbsolute, defaultDrawZPosFromGlobalDrawXxlSettings }; + [SerializeField] ZPosSource zPosSource = ZPosSource.transformPositionPlusOffset; + [SerializeField] float customZPos_offsetValue = 0.0f; + [SerializeField] float customZPos_absValue = 0.0f; + + //custom vectors: + public enum CustomVector3Source { manualInput, toOtherGameobject, fromOtherGameobject, transformsForward, transformsUp, transformsRight, transformsBack, transformsDown, transformsLeft, globalForward, globalUp, globalRight, globalBack, globalDown, globalLeft, observerCameraForward, observerCameraUp, observerCameraRight, observerCameraBack, observerCameraDown, observerCameraLeft, observerCameraToThisGameobject }; + public enum CustomVector2Source { rotationAroundZStartingFromRight, manualInput, toOtherGameobject, fromOtherGameobject, transformsUp, transformsRight, transformsDown, transformsLeft, globalUp, globalRight, globalDown, globalLeft }; + public enum VectorInterpretation { globalSpace, localSpaceDefinedByParent }; + + //Custom Vector3's — 使用 CustomVector3Config[] 数组替代 4 组重复的独立字段 + [SerializeField] public CustomVector3Config[] customVector3Configs = new CustomVector3Config[] + { + CustomVector3Config.Default(), + CustomVector3Config.Default(), + CustomVector3Config.Default(), + CustomVector3Config.Default() + }; + + //Custom Vector2's — 使用 CustomVector2Config[] 数组替代 4 组重复的独立字段 + [SerializeField] public CustomVector2Config[] customVector2Configs = new CustomVector2Config[] + { + CustomVector2Config.Default(), + CustomVector2Config.Default(), + CustomVector2Config.Default(), + CustomVector2Config.Default() + }; + + public delegate Vector3 FlexibleGetCustomVector3(); + public delegate Vector2 FlexibleGetCustomVector2(); + + //partner Gameobject: + [SerializeField] public GameObject partnerGameobject; + [SerializeField] public GameObject partnerGameobject_independentAlternativeValue; + //parter gameobjects Vector3 offset: + [SerializeField] public bool drawPosOffset3DSection_ofPartnerGameobject_isOutfolded = false; + [SerializeField] Vector3 drawPosOffset3D_ofPartnerGameobject_global = Vector3.zero; + [SerializeField] Vector3 drawPosOffset3D_ofPartnerGameobject_local = Vector3.zero; + [SerializeField] public bool drawPosOffset3DSection_ofPartnerGameobject_isOutfolded_independentAlternativeValue = false; + [SerializeField] Vector3 drawPosOffset3D_ofPartnerGameobject_global_independentAlternativeValue = Vector3.zero; + [SerializeField] Vector3 drawPosOffset3D_ofPartnerGameobject_local_independentAlternativeValue = Vector3.zero; + //parter gameobjects Vector2 offset: + [SerializeField] public bool drawPosOffset2DSection_ofPartnerGameobject_isOutfolded = false; + [SerializeField] Vector2 drawPosOffset2D_ofPartnerGameobject_global = Vector2.zero; + [SerializeField] Vector2 drawPosOffset2D_ofPartnerGameobject_local = Vector2.zero; + [SerializeField] public bool drawPosOffset2DSection_ofPartnerGameobject_isOutfolded_independentAlternativeValue = false; + [SerializeField] Vector2 drawPosOffset2D_ofPartnerGameobject_global_independentAlternativeValue = Vector2.zero; + [SerializeField] Vector2 drawPosOffset2D_ofPartnerGameobject_local_independentAlternativeValue = Vector2.zero; + //parter gameobjects custom Vector3: + [SerializeField] public CustomVector3Source source_ofCustomVector3ofPartnerGameobject = (CustomVector3Source)(-1); + [SerializeField] public Vector3 customVector3ofPartnerGameobject_clipboardForManualInput; + [SerializeField] public GameObject customVector3ofPartnerGameobject_targetGameObject; + [SerializeField] bool customVector3ofPartnerGameobject_hasForcedAbsLength = false; + [SerializeField] public bool customVector3ofPartnerGameobject_picker_isOutfolded = false; + [SerializeField] float forcedAbsLength_ofCustomVector3ofPartnerGameobject = 1.0f; + [SerializeField] [Range(0.1f, 10.0f)] float lengthRelScaleFactor_ofCustomVector3ofPartnerGameobject = 1.0f; + [SerializeField] public VectorInterpretation vectorInterpretation_ofCustomVector3ofPartnerGameobject; + [SerializeField] public DrawBasics.CameraForAutomaticOrientation observerCamera_ofCustomVector3ofPartnerGameobject = DrawBasics.CameraForAutomaticOrientation.sceneViewCamera; + //parter gameobjects custom Vector2: + [SerializeField] public CustomVector2Source source_ofCustomVector2ofPartnerGameobject = (CustomVector2Source)(-1); + [SerializeField] public Vector2 customVector2ofPartnerGameobject_clipboardForManualInput; + [SerializeField] public GameObject customVector2ofPartnerGameobject_targetGameObject; + [SerializeField] bool customVector2ofPartnerGameobject_hasForcedAbsLength = false; + [SerializeField] public bool customVector2ofPartnerGameobject_picker_isOutfolded = false; + [SerializeField] [Range(-360.0f, 360.0f)] float rotationFromRight_ofCustomVector2ofPartnerGameobject = 0.0f; + [SerializeField] float forcedAbsLength_ofCustomVector2ofPartnerGameobject = 1.0f; + [SerializeField] [Range(0.1f, 10.0f)] float lengthRelScaleFactor_ofCustomVector2ofPartnerGameobject = 1.0f; + [SerializeField] public VectorInterpretation vectorInterpretation_ofCustomVector2ofPartnerGameobject; + +#if UNITY_EDITOR + bool isFirstUpdateCycleAfterGamePause = false; + int mostCurrentFrameCountDuringGamePause = -10; + [SerializeField] bool isAlreadyInitialized = false; + bool editorUpdateCallback_hasBeenRegistered = false; +#endif + + + void Start() + { +#if UNITY_EDITOR + RegisterEditorUpdateCallback(); + Reset_mostCurrentFrameCountDuringGamePause(); + + if (isAlreadyInitialized == false) + { + InitializeValues_onceInComponentLifetime(); + isAlreadyInitialized = true; + } + InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy(); +#endif + } + + public virtual void InitializeValues_onceInComponentLifetime() + { + //"BezierSplineDrawer.InitializeValues_onceInComponentLifetime()" contains the explanation of the difference between "InitializeValues_onceInComponentLifetime()" and "InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy()" + } + + public virtual void InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy() + { + //"BezierSplineDrawer.InitializeValues_onceInComponentLifetime()" contains the explanation of the difference between "InitializeValues_onceInComponentLifetime()" and "InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy()" + } + + public void TrySetTextToGameobjectName() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = "of " + this.gameObject.name; + text_inclGlobalMarkupTags = "of " + this.gameObject.name; + } + } + + public void TrySetTextToEmptyString() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = ""; + text_inclGlobalMarkupTags = ""; + } + } + + void OnDestroy() + { + UnregisterEditorUpdateCallback(); + } + +#if UNITY_EDITOR + void Reset_mostCurrentFrameCountDuringGamePause() + { + mostCurrentFrameCountDuringGamePause = -10; + } +#endif + + public void RegisterEditorUpdateCallback() + { +#if UNITY_EDITOR + UnityEditor.EditorApplication.update += EditorUpdateCallback; + editorUpdateCallback_hasBeenRegistered = true; +#endif + } + + public void UnregisterEditorUpdateCallback() + { +#if UNITY_EDITOR + if (editorUpdateCallback_hasBeenRegistered) + { + UnityEditor.EditorApplication.update -= EditorUpdateCallback; + editorUpdateCallback_hasBeenRegistered = false; + } +#endif + } + + void EditorUpdateCallback() + { + UtilitiesDXXL_Components.TryProceedOneSheduledFrameStep(); + } + + void OnEnable() + { +#if UNITY_EDITOR + UtilitiesDXXL_Components.ExpandComponentInInspector(this); +#endif + } + + void Update() + { +#if UNITY_EDITOR + UtilitiesDXXL_Components.ExpandComponentInInspector(this); +#endif + } + + void LateUpdate() + { + if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) + { + UtilitiesDXXL_Components.ExpandComponentInInspector(this); + if (this.enabled && PlaymodeIsActiveAndNotPaused() && CheckIf_drawObjectAccordingTo_selectedState()) + { + if (TrySkipDrawingBecauseItIsTheFirstFrameAfterAPausePhase()) { return; } + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + var drawingMethod = useWireMeshInLateUpdate + ? DrawBasics.UsedUnityLineDrawingMethod.wireMesh + : DrawBasics.UsedUnityLineDrawingMethod.debugLines; + UtilitiesDXXL_DrawBasics.Set_usedLineDrawingMethod_reversible(drawingMethod); + long lineCounter_beforeDrawing = DXXLWrapperForUntiysBuildInDrawLines.DrawnLinesSinceStart; //using "DXXLWrapperForUntiyDebugDraw.DrawnLinesSinceStart" instead of "DXXLWrapperForUntiyDebugDraw.DrawnLinesSinceFrameStart" because if this is the only drawn thing inside the frame, then the following "DrawVisualizedObject()" resets the "DrawnLinesSinceFrameStart"-counter (because it's the first drawn thing since "Time.frameCount" was incremented), so the herewith obtained "lineCounter_beforeDrawing" is not accurate anymore. + DrawVisualizedObject(); + drawnLinesPerPass = (int)(DXXLWrapperForUntiysBuildInDrawLines.DrawnLinesSinceStart - lineCounter_beforeDrawing); + UtilitiesDXXL_DrawBasics.Reverse_usedLineDrawingMethod(); + } + } + } + + void OnDrawGizmos() + { +#if UNITY_EDITOR + UtilitiesDXXL_Components.ExpandComponentInInspector(this); + if (this.enabled && IsEditModeOrPlaymodePause() && CheckIf_drawObjectAccordingTo_selectedState()) + { + UtilitiesDXXL_Components.ReportOnDrawGizmosCycleOfAMonoBehaviour(this.GetInstanceID()); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + UtilitiesDXXL_DrawBasics.Set_usedLineDrawingMethod_reversible(DrawBasics.UsedUnityLineDrawingMethod.gizmoLines); //-> "debugLinesInPlayMode_gizmoLinesInEditModeAndPlaymodePauses" is not an option here, because "DXXLWrapperForUntiysBuildInDrawLines.ChooseDebugOrGizmoLines_dependingOnPlayModeState()" forces to debug lines in some cases even if "pause == true" + UtilitiesDXXL_DrawBasics.Set_gizmoMatrix_reversible(Matrix4x4.identity); + long lineCounter_beforeDrawing = DXXLWrapperForUntiysBuildInDrawLines.DrawnLinesSinceStart; //using "DXXLWrapperForUntiyDebugDraw.DrawnLinesSinceStart" instead of "DXXLWrapperForUntiyDebugDraw.DrawnLinesSinceFrameStart": see comment in "LateUpdate()" + DrawVisualizedObject(); + drawnLinesPerPass = (int)(DXXLWrapperForUntiysBuildInDrawLines.DrawnLinesSinceStart - lineCounter_beforeDrawing); + UtilitiesDXXL_DrawBasics.Reverse_usedLineDrawingMethod(); + UtilitiesDXXL_DrawBasics.Reverse_gizmoMatrix(); + + TrySheduleAutomaticFrameStepAtTheStartOfPausePhases(); + } +#endif + } + + bool PlaymodeIsActiveAndNotPaused() + { +#if UNITY_EDITOR + return (UnityEditor.EditorApplication.isPlaying && (UnityEditor.EditorApplication.isPaused == false)); +#else + return (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled); +#endif + } + + bool IsEditModeOrPlaymodePause() + { +#if UNITY_EDITOR + if (UnityEditor.EditorApplication.isPlaying == false) + { + return true; + } + else + { + if (UnityEditor.EditorApplication.isPaused) + { + return true; + } + } + return false; +#else + return false; +#endif + } + + bool CheckIf_drawObjectAccordingTo_selectedState() + { +#if UNITY_EDITOR + if (drawOnlyIfSelected) + { + return UnityEditor.Selection.Contains(gameObject.GetInstanceID()); + } + else + { + return true; + } +#else + return true; +#endif + } + + public virtual void DrawVisualizedObject() + { + } + + bool TrySkipDrawingBecauseItIsTheFirstFrameAfterAPausePhase() + { + //returns "doSkipDrawing" + + //-> this prevents drawing in the first frame after pause phases, to prevent the additional frozen overdraw during pause phases, caused by using "Debug.DrawLine()", which doesn't get cleared during pause phases. + //-> see also "TrySheduleAutomaticFrameStepAtTheStartOfPausePhases()" + //-> for more details: See documentation of "DrawBasics.drawerComponentsAutomaticallyProceedOneFrameStepOnPauseStarts_toPreventFrozenOverlayDraw" + //-> it also preserves the ability of the user to use the "Step"-functionality via the right one of the three play/pause buttons on top of the Unity window. + +#if UNITY_EDITOR + if (isFirstUpdateCycleAfterGamePause) + { + isFirstUpdateCycleAfterGamePause = false; + return true; + } + else + { + isFirstUpdateCycleAfterGamePause = false; + return false; + } +#else + return false; +#endif + } + + void TrySheduleAutomaticFrameStepAtTheStartOfPausePhases() + { +#if UNITY_EDITOR + if (UnityEditor.EditorApplication.isPlaying && UnityEditor.EditorApplication.isPaused) + { + isFirstUpdateCycleAfterGamePause = true; //-> prepare for upcoming Update-cycles + + //-> the additional frame gives the component the chance to skip drawing with "Debug.DrawLine()" in the frame before pause phases, so there are no frozen uncleared debugLines present during the pause phase + //-> see also "TrySkipDrawingBecauseItIsTheFirstFrameAfterAPausePhase()" + //-> for more details: See documentation of "DrawBasics.drawerComponentsAutomaticallyProceedOneFrameStepOnPauseStarts_toPreventFrozenOverlayDraw" + if (mostCurrentFrameCountDuringGamePause <= (Time.frameCount - 2)) + { + //-> is first arrival after pausing the game + //-> at least two Update cycles happened since the previous game pause (or alternatively the playmode has been startet with "pause" already activated) + //-> cannot arrive here after proceeding only a single frame step between two pause phases + //("Time.frameCount" doesn't increase during pause phases) + UtilitiesDXXL_Components.frameCount_forWhichAnEditorFrameStep_hasBeenSheduled_byADrawerComponent = Time.frameCount; //-> sheduling, because calling "UnityEditor.EditorApplication.Step()" from here causes Unity to print "recursive GUI rendering" errors + } + mostCurrentFrameCountDuringGamePause = Time.frameCount; + } +#endif + } + + public Vector3 GetDrawPos3D_global() + { + //-> local space is defined by this gameObject itself, not by the parent. + return (transform.position + drawPosOffset3D_global + transform.rotation * Vector3.Scale(transform.lossyScale, drawPosOffset3D_local)); + } + + public Vector3 GetDrawPos3D_global_independentAlternativeValue() + { + //-> local space is defined by this gameObject itself, not by the parent. + return (transform.position + drawPosOffset3D_global_independentAlternativeValue + transform.rotation * Vector3.Scale(transform.lossyScale, drawPosOffset3D_local_independentAlternativeValue)); + } + + public Vector3 GetDrawPos3D_ofPartnerGameobject_global(bool theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject = true) + { + //-> local space is defined by the gameObject itself, not by the parent. + if (partnerGameobject != null) + { + if (theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject) + { + return (partnerGameobject.transform.position + drawPosOffset3D_ofPartnerGameobject_global + partnerGameobject.transform.rotation * Vector3.Scale(partnerGameobject.transform.lossyScale, drawPosOffset3D_ofPartnerGameobject_local)); + } + else + { + return (partnerGameobject.transform.position + drawPosOffset3D_ofPartnerGameobject_global + transform.rotation * Vector3.Scale(transform.lossyScale, drawPosOffset3D_ofPartnerGameobject_local)); + } + } + else + { + return (transform.position + drawPosOffset3D_ofPartnerGameobject_global + transform.rotation * Vector3.Scale(transform.lossyScale, drawPosOffset3D_ofPartnerGameobject_local)); + } + } + + public Vector3 GetDrawPos3D_ofPartnerGameobject_global_independentAlternativeValue(bool theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject = true) + { + //-> local space is defined by the gameObject itself, not by the parent. + if (partnerGameobject_independentAlternativeValue != null) + { + if (theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject) + { + return (partnerGameobject_independentAlternativeValue.transform.position + drawPosOffset3D_ofPartnerGameobject_global_independentAlternativeValue + partnerGameobject_independentAlternativeValue.transform.rotation * Vector3.Scale(partnerGameobject_independentAlternativeValue.transform.lossyScale, drawPosOffset3D_ofPartnerGameobject_local_independentAlternativeValue)); + } + else + { + return (partnerGameobject_independentAlternativeValue.transform.position + drawPosOffset3D_ofPartnerGameobject_global_independentAlternativeValue + transform.rotation * Vector3.Scale(transform.lossyScale, drawPosOffset3D_ofPartnerGameobject_local_independentAlternativeValue)); + } + } + else + { + return (transform.position + drawPosOffset3D_ofPartnerGameobject_global_independentAlternativeValue + transform.rotation * Vector3.Scale(transform.lossyScale, drawPosOffset3D_ofPartnerGameobject_local_independentAlternativeValue)); + } + } + + public Vector3 GetDrawPos3D_inLocalSpaceAsDefinedByParent() + { + //-> "drawPosOffset3D_local" is in units of the space defined by this gameObject itself, not by the parent. + //-> In constrast to "drawPosOffset3D_local" the return value is in units of the parent defined space + + if (transform.parent == null) + { + return GetDrawPos3D_global(); + } + else + { + Vector3 localDrawPosOffset_localInsideParentSpace = transform.localRotation * Vector3.Scale(transform.localScale, drawPosOffset3D_local); + Quaternion inverseRotationOfLocalSpaceDefinedByParent = Quaternion.Inverse(transform.parent.rotation); + Vector3 globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent = inverseRotationOfLocalSpaceDefinedByParent * drawPosOffset3D_global; + if (UtilitiesDXXL_Math.ContainsZeroComponents(transform.parent.lossyScale)) + { + //-> see note in "CustomVector_globalToLocalSpaceDefinedByParent()" + return (transform.localPosition + localDrawPosOffset_localInsideParentSpace + globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent); + } + else + { + Vector3 globalDrawPosOffset_rotatedAndScaledToLocalSpaceDefinedByParent = new Vector3(globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent.x / transform.parent.lossyScale.x, globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent.y / transform.parent.lossyScale.y, globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent.z / transform.parent.lossyScale.z); + return (transform.localPosition + localDrawPosOffset_localInsideParentSpace + globalDrawPosOffset_rotatedAndScaledToLocalSpaceDefinedByParent); + } + } + } + + public Vector3 GetDrawPos3D_inLocalSpaceAsDefinedByThisGameobject() + { + if (UtilitiesDXXL_Math.ApproximatelyZero(drawPosOffset3D_global) && UtilitiesDXXL_Math.ApproximatelyZero(drawPosOffset3D_local)) + { + return Vector3.zero; + } + else + { + Vector3 offsetPortion_fromGlobalOffset = transform.InverseTransformVector(drawPosOffset3D_global); + Vector3 offsetPortion_fromLocalOffset = drawPosOffset3D_local; + return (offsetPortion_fromGlobalOffset + offsetPortion_fromLocalOffset); + } + } + + public Vector2 GetDrawPos2D_global() + { + //-> local space is defined by this gameObject itself, not by the parent. + Vector2 transformPos_asV2_global = new Vector2(transform.position.x, transform.position.y); + + Vector2 transformsRight_asV2_normalized = new Vector2(transform.right.x, transform.right.y); + Vector2 localOffsetAlongTransformsRight_inGlobalSpaceUnits = transformsRight_asV2_normalized * transform.lossyScale.x * drawPosOffset2D_local.x; + + Vector2 transformsUp_asV2_normalized = new Vector2(transform.up.x, transform.up.y); + Vector2 localOffsetAlongTransformsUp_inGlobalSpaceUnits = transformsUp_asV2_normalized * transform.lossyScale.y * drawPosOffset2D_local.y; + + return (transformPos_asV2_global + drawPosOffset2D_global + localOffsetAlongTransformsRight_inGlobalSpaceUnits + localOffsetAlongTransformsUp_inGlobalSpaceUnits); + } + + public Vector2 GetDrawPos2D_global_independentAlternativeValue() + { + //-> local space is defined by this gameObject itself, not by the parent. + Vector2 transformPos_asV2_global = new Vector2(transform.position.x, transform.position.y); + + Vector2 transformsRight_asV2_normalized = new Vector2(transform.right.x, transform.right.y); + Vector2 localOffsetAlongTransformsRight_inGlobalSpaceUnits = transformsRight_asV2_normalized * transform.lossyScale.x * drawPosOffset2D_local_independentAlternativeValue.x; + + Vector2 transformsUp_asV2_normalized = new Vector2(transform.up.x, transform.up.y); + Vector2 localOffsetAlongTransformsUp_inGlobalSpaceUnits = transformsUp_asV2_normalized * transform.lossyScale.y * drawPosOffset2D_local_independentAlternativeValue.y; + + return (transformPos_asV2_global + drawPosOffset2D_global_independentAlternativeValue + localOffsetAlongTransformsRight_inGlobalSpaceUnits + localOffsetAlongTransformsUp_inGlobalSpaceUnits); + } + + public Vector2 GetDrawPos2D_ofPartnerGameobject_global(bool theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject = true) + { + //-> local space is defined by this gameObject itself, not by the parent. + Transform used_transform = (partnerGameobject != null) ? partnerGameobject.transform : transform; + Vector2 transformPos_asV2_global = new Vector2(used_transform.position.x, used_transform.position.y); + + if (theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject) + { + Vector2 transformsRight_asV2_normalized = new Vector2(used_transform.right.x, used_transform.right.y); + Vector2 localOffsetAlongTransformsRight_inGlobalSpaceUnits = transformsRight_asV2_normalized * used_transform.lossyScale.x * drawPosOffset2D_ofPartnerGameobject_local.x; + + Vector2 transformsUp_asV2_normalized = new Vector2(used_transform.up.x, used_transform.up.y); + Vector2 localOffsetAlongTransformsUp_inGlobalSpaceUnits = transformsUp_asV2_normalized * used_transform.lossyScale.y * drawPosOffset2D_ofPartnerGameobject_local.y; + + return (transformPos_asV2_global + drawPosOffset2D_ofPartnerGameobject_global + localOffsetAlongTransformsRight_inGlobalSpaceUnits + localOffsetAlongTransformsUp_inGlobalSpaceUnits); + } + else + { + Vector2 transformsRight_asV2_normalized = new Vector2(transform.right.x, transform.right.y); + Vector2 localOffsetAlongTransformsRight_inGlobalSpaceUnits = transformsRight_asV2_normalized * transform.lossyScale.x * drawPosOffset2D_ofPartnerGameobject_local.x; + + Vector2 transformsUp_asV2_normalized = new Vector2(transform.up.x, transform.up.y); + Vector2 localOffsetAlongTransformsUp_inGlobalSpaceUnits = transformsUp_asV2_normalized * transform.lossyScale.y * drawPosOffset2D_ofPartnerGameobject_local.y; + + return (transformPos_asV2_global + drawPosOffset2D_ofPartnerGameobject_global + localOffsetAlongTransformsRight_inGlobalSpaceUnits + localOffsetAlongTransformsUp_inGlobalSpaceUnits); + } + } + + public Vector2 GetDrawPos2D_ofPartnerGameobject_global_independentAlternativeValue(bool theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject = true) + { + //-> local space is defined by this gameObject itself, not by the parent. + Transform used_transform = (partnerGameobject_independentAlternativeValue != null) ? partnerGameobject_independentAlternativeValue.transform : transform; + Vector2 transformPos_asV2_global = new Vector2(used_transform.position.x, used_transform.position.y); + + if (theSpaceForTransformingThePartnerLocalOffsetValue_isTakenFromThePartnerGameobject_notFromThisGameobject) + { + Vector2 transformsRight_asV2_normalized = new Vector2(used_transform.right.x, used_transform.right.y); + Vector2 localOffsetAlongTransformsRight_inGlobalSpaceUnits = transformsRight_asV2_normalized * used_transform.lossyScale.x * drawPosOffset2D_ofPartnerGameobject_local_independentAlternativeValue.x; + + Vector2 transformsUp_asV2_normalized = new Vector2(used_transform.up.x, used_transform.up.y); + Vector2 localOffsetAlongTransformsUp_inGlobalSpaceUnits = transformsUp_asV2_normalized * used_transform.lossyScale.y * drawPosOffset2D_ofPartnerGameobject_local_independentAlternativeValue.y; + + return (transformPos_asV2_global + drawPosOffset2D_ofPartnerGameobject_global_independentAlternativeValue + localOffsetAlongTransformsRight_inGlobalSpaceUnits + localOffsetAlongTransformsUp_inGlobalSpaceUnits); + } + else + { + Vector2 transformsRight_asV2_normalized = new Vector2(transform.right.x, transform.right.y); + Vector2 localOffsetAlongTransformsRight_inGlobalSpaceUnits = transformsRight_asV2_normalized * transform.lossyScale.x * drawPosOffset2D_ofPartnerGameobject_local_independentAlternativeValue.x; + + Vector2 transformsUp_asV2_normalized = new Vector2(transform.up.x, transform.up.y); + Vector2 localOffsetAlongTransformsUp_inGlobalSpaceUnits = transformsUp_asV2_normalized * transform.lossyScale.y * drawPosOffset2D_ofPartnerGameobject_local_independentAlternativeValue.y; + + return (transformPos_asV2_global + drawPosOffset2D_ofPartnerGameobject_global_independentAlternativeValue + localOffsetAlongTransformsRight_inGlobalSpaceUnits + localOffsetAlongTransformsUp_inGlobalSpaceUnits); + } + } + + public Vector2 GetDrawPos2D_inLocalSpaceAsDefinedByParent() + { + //-> "drawPosOffset2D_local" is in units of the space defined by this gameObject itself, not by the parent. + //-> In constrast to "drawPosOffset2D_local" the return value is in units of the parent defined space + + if (transform.parent == null) + { + return GetDrawPos2D_global(); + } + else + { + Vector2 transformsLocalPosition_asV2 = new Vector2(transform.localPosition.x, transform.localPosition.y); + + Vector3 drawPosOffset2D_local_asV3 = new Vector3(drawPosOffset2D_local.x, drawPosOffset2D_local.y, 0.0f); + Vector3 localDrawPosOffset_localInsideParentSpace = transform.localRotation * Vector3.Scale(transform.localScale, drawPosOffset2D_local_asV3); + Vector2 localDrawPosOffset_localInsideParentSpace_asV2 = new Vector2(localDrawPosOffset_localInsideParentSpace.x, localDrawPosOffset_localInsideParentSpace.y); + + Quaternion inverseRotationOfLocalSpaceDefinedByParent = Quaternion.Inverse(transform.parent.rotation); + Vector3 drawPosOffset2D_global_asV3 = new Vector3(drawPosOffset2D_global.x, drawPosOffset2D_global.y, 0.0f); + Vector3 globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent = inverseRotationOfLocalSpaceDefinedByParent * drawPosOffset2D_global_asV3; + Vector2 globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent_asV2 = new Vector2(globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent.x, globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent.y); + + if (UtilitiesDXXL_Math.ContainsZeroComponentsInXorY(transform.parent.lossyScale)) + { + //-> see note in "CustomVector3_globalToLocalSpaceDefinedByParent()" + return (transformsLocalPosition_asV2 + localDrawPosOffset_localInsideParentSpace_asV2 + globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent_asV2); + } + else + { + Vector2 globalDrawPosOffset_rotatedAndScaledToLocalSpaceDefinedByParent_asV2 = new Vector2(globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent_asV2.x / transform.parent.lossyScale.x, globalDrawPosOffset_rotatedToLocalSpaceDefinedByParent_asV2.y / transform.parent.lossyScale.y); + return (transformsLocalPosition_asV2 + localDrawPosOffset_localInsideParentSpace_asV2 + globalDrawPosOffset_rotatedAndScaledToLocalSpaceDefinedByParent_asV2); + } + } + } + + public Vector3 GetDrawPos3D_ofA2DModeTransform_global() + { + Vector2 drawPos2D_global = GetDrawPos2D_global(); + Vector3 drawPos3D_ofA2DModeTransform_global = new Vector3(drawPos2D_global.x, drawPos2D_global.y, GetZPos_global_for2D()); + return drawPos3D_ofA2DModeTransform_global; + } + + public float GetZPos_global_for2D() + { + switch (zPosSource) + { + case ZPosSource.transformPositionPlusOffset: + if (UtilitiesDXXL_Math.FloatIsValid(customZPos_offsetValue)) + { + return transform.position.z + customZPos_offsetValue; + } + else + { + return transform.position.z; + } + case ZPosSource.setAbsolute: + if (UtilitiesDXXL_Math.FloatIsValid(customZPos_absValue)) + { + return customZPos_absValue; + } + else + { + return transform.position.z; + } + case ZPosSource.defaultDrawZPosFromGlobalDrawXxlSettings: + return DrawBasics2D.Default_zPos_forDrawing; + default: + return transform.position.z; + } + } + + public Vector3 Get_customVector3_1_inGlobalSpaceUnits() { return GetCustomVector3(0); } + public Vector3 Get_customVector3_1_inLocalSpaceDefinedByParentUnits() { return GetCustomVector3Local(0); } + public Vector3 Get_customVector3_2_inGlobalSpaceUnits() { return GetCustomVector3(1); } + public Vector3 Get_customVector3_2_inLocalSpaceDefinedByParentUnits() { return GetCustomVector3Local(1); } + public Vector3 Get_customVector3_3_inGlobalSpaceUnits() { return GetCustomVector3(2); } + public Vector3 Get_customVector3_3_inLocalSpaceDefinedByParentUnits() { return GetCustomVector3Local(2); } + public Vector3 Get_customVector3_4_inGlobalSpaceUnits() { return GetCustomVector3(3); } + public Vector3 Get_customVector3_4_inLocalSpaceDefinedByParentUnits() { return GetCustomVector3Local(3); } + + public Vector3 GetCustomVector3(int index) + { + var cfg = customVector3Configs[index]; + return Get_aCustomVector3_inGlobalSpaceUnits(cfg.vectorInterpretation, cfg.source, cfg.clipboardForManualInput, cfg.targetGameObject, cfg.hasForcedAbsLength, cfg.forcedAbsLength, cfg.lengthRelScaleFactor, cfg.observerCamera, transform); + } + + public Vector3 GetCustomVector3Local(int index) + { + var cfg = customVector3Configs[index]; + return Get_aCustomVector3_inLocalSpaceDefinedByParentUnits(cfg.vectorInterpretation, cfg.source, cfg.clipboardForManualInput, cfg.targetGameObject, cfg.hasForcedAbsLength, cfg.forcedAbsLength, cfg.lengthRelScaleFactor, cfg.observerCamera, transform); + } + + public Vector3 Get_customVector3ofPartnerGameobject_inGlobalSpaceUnits() + { + if (partnerGameobject == null) + { + return Vector3.zero; + } + else + { + return Get_aCustomVector3_inGlobalSpaceUnits(vectorInterpretation_ofCustomVector3ofPartnerGameobject, source_ofCustomVector3ofPartnerGameobject, customVector3ofPartnerGameobject_clipboardForManualInput, customVector3ofPartnerGameobject_targetGameObject, customVector3ofPartnerGameobject_hasForcedAbsLength, forcedAbsLength_ofCustomVector3ofPartnerGameobject, lengthRelScaleFactor_ofCustomVector3ofPartnerGameobject, observerCamera_ofCustomVector3ofPartnerGameobject, partnerGameobject.transform); + } + } + + public Vector3 Get_customVector3ofPartnerGameobject_inLocalSpaceDefinedByParentUnits() + { + if (partnerGameobject == null) + { + return Vector3.zero; + } + else + { + return Get_aCustomVector3_inLocalSpaceDefinedByParentUnits(vectorInterpretation_ofCustomVector3ofPartnerGameobject, source_ofCustomVector3ofPartnerGameobject, customVector3ofPartnerGameobject_clipboardForManualInput, customVector3ofPartnerGameobject_targetGameObject, customVector3ofPartnerGameobject_hasForcedAbsLength, forcedAbsLength_ofCustomVector3ofPartnerGameobject, lengthRelScaleFactor_ofCustomVector3ofPartnerGameobject, observerCamera_ofCustomVector3ofPartnerGameobject, partnerGameobject.transform); + } + } + + Vector3 Get_aCustomVector3_inGlobalSpaceUnits(VectorInterpretation vectorInterpretation_ofCustomVector, CustomVector3Source source_ofCustomVector, Vector3 customVector_clipboardForManualInput, GameObject customVector_targetGameObject, bool customVector_hasForcedAbsLength, float forcedAbsLength_ofCustomVector, float lengthRelScaleFactor_ofCustomVector, DrawBasics.CameraForAutomaticOrientation observerCamera_ofCustomVector, Transform transformThatMountsTheCustomVector) + { + //The custom vector depends in some cases on other gameobjects than this, namely when "source_ofCustomVector == toOtherGameobject" or when "vectorInterpretation_ofCustomVector == local" (then depending on transform of parents) + //-> Therefore the custom vector is calculated onDraw here in the MonoBehaviour instead of in the corresponding EditorClass.OnInspectorGUI(), since in this case it would only update there if this gameobject is selected. + + Vector3 vectorPreSpaceConversion_unscaled; + Vector3 vectorPreSpaceConversion_scaled; + + Vector3 observerCamForward_normalized; + Vector3 observerCamUp_normalized; + Vector3 observerCamRight_normalized; + Vector3 cam_to_observedPosition; + + if (vectorInterpretation_ofCustomVector == VectorInterpretation.globalSpace) + { + switch (source_ofCustomVector) + { + case CustomVector3Source.manualInput: + vectorPreSpaceConversion_unscaled = customVector_clipboardForManualInput; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.toOtherGameobject: + vectorPreSpaceConversion_unscaled = Get_vector3ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.fromOtherGameobject: + vectorPreSpaceConversion_unscaled = -Get_vector3ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.transformsForward: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.forward; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.transformsUp: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.transformsRight: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.transformsBack: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.forward); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.transformsDown: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.up); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.transformsLeft: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.right); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.globalForward: + vectorPreSpaceConversion_unscaled = Vector3.forward; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.globalUp: + vectorPreSpaceConversion_unscaled = Vector3.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.globalRight: + vectorPreSpaceConversion_unscaled = Vector3.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.globalBack: + vectorPreSpaceConversion_unscaled = Vector3.back; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.globalDown: + vectorPreSpaceConversion_unscaled = Vector3.down; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.globalLeft: + vectorPreSpaceConversion_unscaled = Vector3.left; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.observerCameraForward: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamForward_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.observerCameraUp: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamUp_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.observerCameraRight: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamRight_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.observerCameraBack: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamForward_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.observerCameraDown: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamUp_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.observerCameraLeft: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamRight_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.observerCameraToThisGameobject: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = cam_to_observedPosition; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + default: + return default(Vector3); + } + } + else + { + switch (source_ofCustomVector) + { + case CustomVector3Source.manualInput: + vectorPreSpaceConversion_unscaled = customVector_clipboardForManualInput; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_localToGlobal(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.toOtherGameobject: + vectorPreSpaceConversion_unscaled = Get_vector3ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == toOtherGameobject" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.fromOtherGameobject: + vectorPreSpaceConversion_unscaled = -Get_vector3ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == toOtherGameobject" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.transformsForward: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.forward; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_localToGlobal(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsUp: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_localToGlobal(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsRight: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_localToGlobal(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsBack: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.forward); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_localToGlobal(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsDown: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.up); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_localToGlobal(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsLeft: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.right); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_localToGlobal(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); + case CustomVector3Source.globalForward: + vectorPreSpaceConversion_unscaled = Vector3.forward; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == globalForward" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.globalUp: + vectorPreSpaceConversion_unscaled = Vector3.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == globalUp" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.globalRight: + vectorPreSpaceConversion_unscaled = Vector3.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == globalRight" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.globalBack: + vectorPreSpaceConversion_unscaled = Vector3.back; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == globalBack" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.globalDown: + vectorPreSpaceConversion_unscaled = Vector3.down; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == globalDown" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.globalLeft: + vectorPreSpaceConversion_unscaled = Vector3.left; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == globalLeft" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraForward: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamForward_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == observerCameraForward" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraUp: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamUp_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == observerCameraUp" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraRight: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamRight_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == observerCameraRight" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraBack: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamForward_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == observerCameraBack" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraDown: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamUp_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == observerCameraDown" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraLeft: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamRight_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == observerCameraLeft" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraToThisGameobject: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = cam_to_observedPosition; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == observerCameraToThisGameobject" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + default: + return default(Vector3); + } + } + } + + Vector3 Get_aCustomVector3_inLocalSpaceDefinedByParentUnits(VectorInterpretation vectorInterpretation_ofCustomVector, CustomVector3Source source_ofCustomVector, Vector3 customVector_clipboardForManualInput, GameObject customVector_targetGameObject, bool customVector_hasForcedAbsLength, float forcedAbsLength_ofCustomVector, float lengthRelScaleFactor_ofCustomVector, DrawBasics.CameraForAutomaticOrientation observerCamera_ofCustomVector, Transform transformThatMountsTheCustomVector) + { + //-> see notes inside "Get_aCustomVector3_inGlobalSpaceUnits" + + Vector3 vectorPreSpaceConversion_unscaled; + Vector3 vectorPreSpaceConversion_scaled; + + Vector3 observerCamForward_normalized; + Vector3 observerCamUp_normalized; + Vector3 observerCamRight_normalized; + Vector3 cam_to_observedPosition; + + if (vectorInterpretation_ofCustomVector == VectorInterpretation.localSpaceDefinedByParent) + { + switch (source_ofCustomVector) + { + case CustomVector3Source.manualInput: + vectorPreSpaceConversion_unscaled = customVector_clipboardForManualInput; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector3Source.toOtherGameobject: + vectorPreSpaceConversion_unscaled = Get_vector3ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == toOtherGameobject" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.fromOtherGameobject: + vectorPreSpaceConversion_unscaled = -Get_vector3ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == toOtherGameobject" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.transformsForward: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.forward; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); //-> could alse be derived via "Vector3.forward" (acting as "transform.forward" in localSpace of this.transform), which gets converted one hierarchy-layer towards "more global", so it is inside localSpace defined by parent. + case CustomVector3Source.transformsUp: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); //-> could alse be derived via "Vector3.up" (acting as "transform.up" in localSpace of this.transform), which gets converted one hierarchy-layer towards "more global", so it is inside localSpace defined by parent. + case CustomVector3Source.transformsRight: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); //-> could alse be derived via "Vector3.right" (acting as "transform.right" in localSpace of this.transform), which gets converted one hierarchy-layer towards "more global", so it is inside localSpace defined by parent. + case CustomVector3Source.transformsBack: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.forward); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); //-> could alse be derived via "Vector3.back" (acting as "transform.back" in localSpace of this.transform), which gets converted one hierarchy-layer towards "more global", so it is inside localSpace defined by parent. + case CustomVector3Source.transformsDown: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.up); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); //-> could alse be derived via "Vector3.down" (acting as "transform.down" in localSpace of this.transform), which gets converted one hierarchy-layer towards "more global", so it is inside localSpace defined by parent. + case CustomVector3Source.transformsLeft: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.right); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); //-> could alse be derived via "Vector3.left" (acting as "transform.left" in localSpace of this.transform), which gets converted one hierarchy-layer towards "more global", so it is inside localSpace defined by parent. + case CustomVector3Source.globalForward: + vectorPreSpaceConversion_unscaled = Vector3.forward; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == globalForward" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.globalUp: + vectorPreSpaceConversion_unscaled = Vector3.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == globalUp" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.globalRight: + vectorPreSpaceConversion_unscaled = Vector3.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == globalRight" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.globalBack: + vectorPreSpaceConversion_unscaled = Vector3.back; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == globalBack" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.globalDown: + vectorPreSpaceConversion_unscaled = Vector3.down; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == globalDown" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.globalLeft: + vectorPreSpaceConversion_unscaled = Vector3.left; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == globalLeft" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraForward: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamForward_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == observerCameraForward" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraUp: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamUp_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == observerCameraUp" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraRight: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamRight_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == observerCameraRight" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraBack: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamForward_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == observerCameraBack" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraDown: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamUp_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == observerCameraDown" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraLeft: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamRight_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == observerCameraLeft" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector3Source.observerCameraToThisGameobject: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = cam_to_observedPosition; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == observerCameraToThisGameobject" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + default: + return default(Vector3); + } + } + else + { + switch (source_ofCustomVector) + { + case CustomVector3Source.manualInput: + vectorPreSpaceConversion_unscaled = customVector_clipboardForManualInput; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.toOtherGameobject: + vectorPreSpaceConversion_unscaled = Get_vector3ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.fromOtherGameobject: + vectorPreSpaceConversion_unscaled = -Get_vector3ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsForward: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.forward; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsUp: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsRight: + vectorPreSpaceConversion_unscaled = transformThatMountsTheCustomVector.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsBack: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.forward); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsDown: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.up); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.transformsLeft: + vectorPreSpaceConversion_unscaled = (-transformThatMountsTheCustomVector.right); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.globalForward: + vectorPreSpaceConversion_unscaled = Vector3.forward; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.globalUp: + vectorPreSpaceConversion_unscaled = Vector3.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.globalRight: + vectorPreSpaceConversion_unscaled = Vector3.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.globalBack: + vectorPreSpaceConversion_unscaled = Vector3.back; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.globalDown: + vectorPreSpaceConversion_unscaled = Vector3.down; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.globalLeft: + vectorPreSpaceConversion_unscaled = Vector3.left; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.observerCameraForward: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamForward_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.observerCameraUp: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamUp_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.observerCameraRight: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = observerCamRight_normalized; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.observerCameraBack: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamForward_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.observerCameraDown: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamUp_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.observerCameraLeft: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = (-observerCamRight_normalized); + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector3Source.observerCameraToThisGameobject: + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, transformThatMountsTheCustomVector.position, observerCamera_ofCustomVector); + vectorPreSpaceConversion_unscaled = cam_to_observedPosition; + vectorPreSpaceConversion_scaled = ScaleCustomVector3(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector3_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + default: + return default(Vector3); + } + } + } + + Vector3 ScaleCustomVector3(Vector3 unscaledVector, bool customVector_hasForcedAbsLength, float forcedAbsLength_ofCustomVector, float lengthRelScaleFactor_ofCustomVector) + { + if (customVector_hasForcedAbsLength) + { + return (unscaledVector.normalized * forcedAbsLength_ofCustomVector); + } + else + { + return (unscaledVector * lengthRelScaleFactor_ofCustomVector); + } + } + + Vector3 CustomVector3_globalToLocalSpaceDefinedByParent(Vector3 customVector_global, bool convertOnlyRotation_butNotScale, Transform transformThatMountsTheCustomVector) + { + if (transformThatMountsTheCustomVector.parent == null) + { + return customVector_global; + } + else + { + Vector3 vector_inverseRotated = Quaternion.Inverse(transformThatMountsTheCustomVector.parent.rotation) * customVector_global; + if (convertOnlyRotation_butNotScale) + { + return vector_inverseRotated; + } + else + { + if (UtilitiesDXXL_Math.ContainsZeroComponents(transformThatMountsTheCustomVector.parent.lossyScale)) + { + //-> at least one dimension of the local space is shrinked to the size of 0. + //-> scaling from global space to local space skipped, because + //---> the smaller the local space shrinks, the bigger the components of a vector (with fixed size in global space) will become in this local space. + //---> each vector in global space would become a vector of infinity-length in a local space of scale=0 + //---> or formulated the other way round: a vector in units of a "local space of scale=0" would have to have a length of infinity to be represented as a (non-zero) vector in global space. + return vector_inverseRotated; + } + else + { + //scale inverse: + return new Vector3(vector_inverseRotated.x / transformThatMountsTheCustomVector.parent.lossyScale.x, vector_inverseRotated.y / transformThatMountsTheCustomVector.parent.lossyScale.y, vector_inverseRotated.z / transformThatMountsTheCustomVector.parent.lossyScale.z); + } + } + } + } + + Vector3 CustomVector3_localToGlobal(Vector3 customVector_local, bool convertOnlyScale_butNotRotation, Transform transformThatMountsTheCustomVector) + { + if (transformThatMountsTheCustomVector.parent == null) + { + return customVector_local; + } + else + { + Vector3 customVector_scaled = Vector3.Scale(transformThatMountsTheCustomVector.parent.lossyScale, customVector_local); + if (convertOnlyScale_butNotRotation) + { + return customVector_scaled; + } + else + { + return (transformThatMountsTheCustomVector.parent.rotation * customVector_scaled); + } + } + } + + Vector3 Get_vector3ToOtherGameobject_preSpaceConversion_unscaled(GameObject customVector_targetGameObject, Transform transformThatMountsTheCustomVector) + { + if (customVector_targetGameObject == null) + { + return Vector3.zero; + } + else + { + return (customVector_targetGameObject.transform.position - transformThatMountsTheCustomVector.position); + } + } + + public Vector2 Get_customVector2_1_inGlobalSpaceUnits() { return GetCustomVector2(0); } + public Vector2 Get_customVector2_1_inLocalSpaceDefinedByParentUnits() { return GetCustomVector2Local(0); } + public Vector2 Get_customVector2_2_inGlobalSpaceUnits() { return GetCustomVector2(1); } + public Vector2 Get_customVector2_2_inLocalSpaceDefinedByParentUnits() { return GetCustomVector2Local(1); } + public Vector2 Get_customVector2_3_inGlobalSpaceUnits() { return GetCustomVector2(2); } + public Vector2 Get_customVector2_3_inLocalSpaceDefinedByParentUnits() { return GetCustomVector2Local(2); } + public Vector2 Get_customVector2_4_inGlobalSpaceUnits() { return GetCustomVector2(3); } + public Vector2 Get_customVector2_4_inLocalSpaceDefinedByParentUnits() { return GetCustomVector2Local(3); } + + public Vector2 GetCustomVector2(int index) + { + var cfg = customVector2Configs[index]; + return Get_aCustomVector2_inGlobalSpaceUnits(cfg.vectorInterpretation, cfg.source, cfg.rotationFromRight, cfg.clipboardForManualInput, cfg.targetGameObject, cfg.hasForcedAbsLength, cfg.forcedAbsLength, cfg.lengthRelScaleFactor, transform); + } + + public Vector2 GetCustomVector2Local(int index) + { + var cfg = customVector2Configs[index]; + return Get_aCustomVector2_inLocalSpaceDefinedByParentUnits(cfg.vectorInterpretation, cfg.source, cfg.rotationFromRight, cfg.clipboardForManualInput, cfg.targetGameObject, cfg.hasForcedAbsLength, cfg.forcedAbsLength, cfg.lengthRelScaleFactor, transform); + } + + public Vector2 Get_customVector2ofPartnerGameobject_inGlobalSpaceUnits() + { + if (partnerGameobject == null) + { + return Vector2.zero; + } + else + { + return Get_aCustomVector2_inGlobalSpaceUnits(vectorInterpretation_ofCustomVector2ofPartnerGameobject, source_ofCustomVector2ofPartnerGameobject, rotationFromRight_ofCustomVector2ofPartnerGameobject, customVector2ofPartnerGameobject_clipboardForManualInput, customVector2ofPartnerGameobject_targetGameObject, customVector2ofPartnerGameobject_hasForcedAbsLength, forcedAbsLength_ofCustomVector2ofPartnerGameobject, lengthRelScaleFactor_ofCustomVector2ofPartnerGameobject, partnerGameobject.transform); + } + } + + public Vector2 Get_customVector2ofPartnerGameobject_inLocalSpaceDefinedByParentUnits() + { + if (partnerGameobject == null) + { + return Vector2.zero; + } + else + { + return Get_aCustomVector2_inLocalSpaceDefinedByParentUnits(vectorInterpretation_ofCustomVector2ofPartnerGameobject, source_ofCustomVector2ofPartnerGameobject, rotationFromRight_ofCustomVector2ofPartnerGameobject, customVector2ofPartnerGameobject_clipboardForManualInput, customVector2ofPartnerGameobject_targetGameObject, customVector2ofPartnerGameobject_hasForcedAbsLength, forcedAbsLength_ofCustomVector2ofPartnerGameobject, lengthRelScaleFactor_ofCustomVector2ofPartnerGameobject, partnerGameobject.transform); + } + } + + Vector2 Get_aCustomVector2_inGlobalSpaceUnits(VectorInterpretation vectorInterpretation_ofCustomVector, CustomVector2Source source_ofCustomVector, float rotationFromRight_ofCustomVector, Vector2 customVector_clipboardForManualInput, GameObject customVector_targetGameObject, bool customVector_hasForcedAbsLength, float forcedAbsLength_ofCustomVector, float lengthRelScaleFactor_ofCustomVector, Transform transformThatMountsTheCustomVector) + { + //-> see notes inside "Get_aCustomVector3_inGlobalSpaceUnits" + + Vector2 vectorPreSpaceConversion_unscaled; + Vector2 vectorPreSpaceConversion_scaled; + if (vectorInterpretation_ofCustomVector == VectorInterpretation.globalSpace) + { + switch (source_ofCustomVector) + { + case CustomVector2Source.rotationAroundZStartingFromRight: + vectorPreSpaceConversion_unscaled = GetToLeftVectorRotatedAroundZ_asV2(rotationFromRight_ofCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.manualInput: + vectorPreSpaceConversion_unscaled = customVector_clipboardForManualInput; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.toOtherGameobject: + vectorPreSpaceConversion_unscaled = Get_vector2ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.fromOtherGameobject: + vectorPreSpaceConversion_unscaled = -Get_vector2ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.transformsUp: + vectorPreSpaceConversion_unscaled = new Vector2(transformThatMountsTheCustomVector.up.x, transformThatMountsTheCustomVector.up.y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.transformsRight: + vectorPreSpaceConversion_unscaled = new Vector2(transformThatMountsTheCustomVector.right.x, transformThatMountsTheCustomVector.right.y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.transformsDown: + vectorPreSpaceConversion_unscaled = new Vector2((-transformThatMountsTheCustomVector.up).x, (-transformThatMountsTheCustomVector.up).y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.transformsLeft: + vectorPreSpaceConversion_unscaled = new Vector2((-transformThatMountsTheCustomVector.right).x, (-transformThatMountsTheCustomVector.right).y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.globalUp: + vectorPreSpaceConversion_unscaled = Vector2.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.globalRight: + vectorPreSpaceConversion_unscaled = Vector2.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.globalDown: + vectorPreSpaceConversion_unscaled = Vector2.down; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.globalLeft: + vectorPreSpaceConversion_unscaled = Vector2.left; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + default: + return default(Vector2); + } + } + else + { + switch (source_ofCustomVector) + { + case CustomVector2Source.rotationAroundZStartingFromRight: + vectorPreSpaceConversion_unscaled = GetToLeftVectorRotatedAroundZ_asV2(rotationFromRight_ofCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_localToGlobal(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.manualInput: + vectorPreSpaceConversion_unscaled = customVector_clipboardForManualInput; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_localToGlobal(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.toOtherGameobject: + vectorPreSpaceConversion_unscaled = Get_vector2ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == toOtherGameobject" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector2Source.fromOtherGameobject: + vectorPreSpaceConversion_unscaled = -Get_vector2ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == toOtherGameobject" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector2Source.transformsUp: + vectorPreSpaceConversion_unscaled = new Vector2(transformThatMountsTheCustomVector.up.x, transformThatMountsTheCustomVector.up.y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_localToGlobal(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); + case CustomVector2Source.transformsRight: + vectorPreSpaceConversion_unscaled = new Vector2(transformThatMountsTheCustomVector.right.x, transformThatMountsTheCustomVector.right.y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_localToGlobal(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); + case CustomVector2Source.transformsDown: + vectorPreSpaceConversion_unscaled = new Vector2((-transformThatMountsTheCustomVector.up).x, (-transformThatMountsTheCustomVector.up).y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_localToGlobal(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); + case CustomVector2Source.transformsLeft: + vectorPreSpaceConversion_unscaled = new Vector2((-transformThatMountsTheCustomVector.right).x, (-transformThatMountsTheCustomVector.right).y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_localToGlobal(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); + case CustomVector2Source.globalUp: + vectorPreSpaceConversion_unscaled = Vector2.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == globalUp" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector2Source.globalRight: + vectorPreSpaceConversion_unscaled = Vector2.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == globalRight" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector2Source.globalDown: + vectorPreSpaceConversion_unscaled = Vector2.down; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == globalDown" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector2Source.globalLeft: + vectorPreSpaceConversion_unscaled = Vector2.left; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; //"vector source == globalLeft" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + default: + return default(Vector2); + } + } + } + + Vector2 Get_aCustomVector2_inLocalSpaceDefinedByParentUnits(VectorInterpretation vectorInterpretation_ofCustomVector, CustomVector2Source source_ofCustomVector, float rotationFromRight_ofCustomVector, Vector2 customVector_clipboardForManualInput, GameObject customVector_targetGameObject, bool customVector_hasForcedAbsLength, float forcedAbsLength_ofCustomVector, float lengthRelScaleFactor_ofCustomVector, Transform transformThatMountsTheCustomVector) + { + //-> see notes inside "Get_aCustomVector3_inGlobalSpaceUnits" + + Vector2 vectorPreSpaceConversion_unscaled; + Vector2 vectorPreSpaceConversion_scaled; + if (vectorInterpretation_ofCustomVector == VectorInterpretation.localSpaceDefinedByParent) + { + switch (source_ofCustomVector) + { + case CustomVector2Source.rotationAroundZStartingFromRight: + vectorPreSpaceConversion_unscaled = GetToLeftVectorRotatedAroundZ_asV2(rotationFromRight_ofCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.manualInput: + vectorPreSpaceConversion_unscaled = customVector_clipboardForManualInput; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return vectorPreSpaceConversion_scaled; + case CustomVector2Source.toOtherGameobject: + vectorPreSpaceConversion_unscaled = Get_vector2ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == toOtherGameobject" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector2Source.fromOtherGameobject: + vectorPreSpaceConversion_unscaled = -Get_vector2ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == toOtherGameobject" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector2Source.transformsUp: + vectorPreSpaceConversion_unscaled = new Vector2(transformThatMountsTheCustomVector.up.x, transformThatMountsTheCustomVector.up.y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); //-> could alse be derived via "Vector3.up" (acting as "transform.up" in localSpace of this.transform), which gets converted one hierarchy-layer towards "more global", so it is inside localSpace defined by parent. + case CustomVector2Source.transformsRight: + vectorPreSpaceConversion_unscaled = new Vector2(transformThatMountsTheCustomVector.right.x, transformThatMountsTheCustomVector.right.y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); //-> could alse be derived via "Vector3.right" (acting as "transform.right" in localSpace of this.transform), which gets converted one hierarchy-layer towards "more global", so it is inside localSpace defined by parent. + case CustomVector2Source.transformsDown: + vectorPreSpaceConversion_unscaled = new Vector2((-transformThatMountsTheCustomVector.up).x, (-transformThatMountsTheCustomVector.up).y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); //-> could alse be derived via "Vector3.down" (acting as "transform.down" in localSpace of this.transform), which gets converted one hierarchy-layer towards "more global", so it is inside localSpace defined by parent. + case CustomVector2Source.transformsLeft: + vectorPreSpaceConversion_unscaled = new Vector2((-transformThatMountsTheCustomVector.right).x, (-transformThatMountsTheCustomVector.right).y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, true, transformThatMountsTheCustomVector); //-> could alse be derived via "Vector3.left" (acting as "transform.left" in localSpace of this.transform), which gets converted one hierarchy-layer towards "more global", so it is inside localSpace defined by parent. + case CustomVector2Source.globalUp: + vectorPreSpaceConversion_unscaled = Vector2.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == globalUp" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector2Source.globalRight: + vectorPreSpaceConversion_unscaled = Vector2.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == globalRight" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector2Source.globalDown: + vectorPreSpaceConversion_unscaled = Vector2.down; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == globalDown" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + case CustomVector2Source.globalLeft: + vectorPreSpaceConversion_unscaled = Vector2.left; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); //"vector source == globalLeft" can not be selected in the inspector as "interpretation == localSpaceDefinedByParent", so this case cannot happen. The fallback here behaves equal to the "interpretation == globalSpace"-thread + default: + return default(Vector2); + } + } + else + { + switch (source_ofCustomVector) + { + case CustomVector2Source.rotationAroundZStartingFromRight: + vectorPreSpaceConversion_unscaled = GetToLeftVectorRotatedAroundZ_asV2(rotationFromRight_ofCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.manualInput: + vectorPreSpaceConversion_unscaled = customVector_clipboardForManualInput; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.toOtherGameobject: + vectorPreSpaceConversion_unscaled = Get_vector2ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.fromOtherGameobject: + vectorPreSpaceConversion_unscaled = -Get_vector2ToOtherGameobject_preSpaceConversion_unscaled(customVector_targetGameObject, transformThatMountsTheCustomVector); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.transformsUp: + vectorPreSpaceConversion_unscaled = new Vector2(transformThatMountsTheCustomVector.up.x, transformThatMountsTheCustomVector.up.y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.transformsRight: + vectorPreSpaceConversion_unscaled = new Vector2(transformThatMountsTheCustomVector.right.x, transformThatMountsTheCustomVector.right.y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.transformsDown: + vectorPreSpaceConversion_unscaled = new Vector2((-transformThatMountsTheCustomVector.up).x, (-transformThatMountsTheCustomVector.up).y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.transformsLeft: + vectorPreSpaceConversion_unscaled = new Vector2((-transformThatMountsTheCustomVector.right).x, (-transformThatMountsTheCustomVector.right).y); + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.globalUp: + vectorPreSpaceConversion_unscaled = Vector2.up; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.globalRight: + vectorPreSpaceConversion_unscaled = Vector2.right; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.globalDown: + vectorPreSpaceConversion_unscaled = Vector2.down; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + case CustomVector2Source.globalLeft: + vectorPreSpaceConversion_unscaled = Vector2.left; + vectorPreSpaceConversion_scaled = ScaleCustomVector2(vectorPreSpaceConversion_unscaled, customVector_hasForcedAbsLength, forcedAbsLength_ofCustomVector, lengthRelScaleFactor_ofCustomVector); + return CustomVector2_globalToLocalSpaceDefinedByParent(vectorPreSpaceConversion_scaled, false, transformThatMountsTheCustomVector); + default: + return default(Vector2); + } + } + } + + Vector2 ScaleCustomVector2(Vector2 unscaledVector, bool customVector_hasForcedAbsLength, float forcedAbsLength_ofCustomVector, float lengthRelScaleFactor_ofCustomVector) + { + if (customVector_hasForcedAbsLength) + { + return (unscaledVector.normalized * forcedAbsLength_ofCustomVector); + } + else + { + return (unscaledVector * lengthRelScaleFactor_ofCustomVector); + } + } + + Vector2 Get_vector2ToOtherGameobject_preSpaceConversion_unscaled(GameObject customVector_targetGameObject, Transform transformThatMountsTheCustomVector) + { + if (customVector_targetGameObject == null) + { + return Vector2.zero; + } + else + { + Vector2 thisTransformsPosition_asV2 = new Vector2(transformThatMountsTheCustomVector.position.x, transformThatMountsTheCustomVector.position.y); + Vector2 otherGameobjectsPosition_asV2 = new Vector2(customVector_targetGameObject.transform.position.x, customVector_targetGameObject.transform.position.y); + return (otherGameobjectsPosition_asV2 - thisTransformsPosition_asV2); + } + } + + Vector2 CustomVector2_localToGlobal(Vector2 customVector_local, bool convertOnlyScale_butNotRotation, Transform transformThatMountsTheCustomVector) + { + if (transformThatMountsTheCustomVector.parent == null) + { + return customVector_local; + } + else + { + Vector2 customVector_local_asV2 = new Vector2(customVector_local.x, customVector_local.y); + Vector2 parentsLossyScale_asV2 = new Vector2(transformThatMountsTheCustomVector.parent.lossyScale.x, transformThatMountsTheCustomVector.parent.lossyScale.y); + Vector2 customVector_scaled = Vector2.Scale(parentsLossyScale_asV2, customVector_local_asV2); + if (convertOnlyScale_butNotRotation) + { + return customVector_scaled; + } + else + { + Vector3 customVector_scaled_asV3 = new Vector3(customVector_scaled.x, customVector_scaled.y, 0.0f); + Vector3 customVector_scaledAndRotated_asV3 = (transformThatMountsTheCustomVector.parent.rotation * customVector_scaled_asV3); + Vector2 customVector_scaledAndRotated_asV2 = new Vector2(customVector_scaledAndRotated_asV3.x, customVector_scaledAndRotated_asV3.y); + return customVector_scaledAndRotated_asV2; + } + } + } + + Vector2 CustomVector2_globalToLocalSpaceDefinedByParent(Vector2 customVector_global, bool convertOnlyRotation_butNotScale, Transform transformThatMountsTheCustomVector) + { + if (transformThatMountsTheCustomVector.parent == null) + { + return customVector_global; + } + else + { + Quaternion inverseRotation_ofParent = Quaternion.Inverse(transformThatMountsTheCustomVector.parent.rotation); + Vector3 customVector_global_asV3 = new Vector3(customVector_global.x, customVector_global.y, 0.0f); + Vector3 customVector_global_inverseRotated_asV3 = inverseRotation_ofParent * customVector_global_asV3; + Vector2 customVector_global_inverseRotated_asV2 = new Vector2(customVector_global_inverseRotated_asV3.x, customVector_global_inverseRotated_asV3.y); + + if (convertOnlyRotation_butNotScale) + { + return customVector_global_inverseRotated_asV2; + } + else + { + if (UtilitiesDXXL_Math.ContainsZeroComponentsInXorY(transformThatMountsTheCustomVector.parent.lossyScale)) + { + //-> see note in "CustomVector3_globalToLocalSpaceDefinedByParent()" + return customVector_global_inverseRotated_asV2; + } + else + { + //scale inverse: + return new Vector2(customVector_global_inverseRotated_asV2.x / transformThatMountsTheCustomVector.parent.lossyScale.x, customVector_global_inverseRotated_asV2.y / transformThatMountsTheCustomVector.parent.lossyScale.y); + } + } + } + } + + Vector2 GetToLeftVectorRotatedAroundZ_asV2(float rotationFromRight_ofCustomVector) + { + Quaternion rotation_fromRight = Quaternion.AngleAxis(rotationFromRight_ofCustomVector, Vector3.forward); + Vector3 vectorPreSpaceConversion_unscaled_asV3 = rotation_fromRight * Vector3.right; + return (new Vector2(vectorPreSpaceConversion_unscaled_asV3.x, vectorPreSpaceConversion_unscaled_asV3.y)); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerParent.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerParent.cs.meta new file mode 100644 index 0000000..a8acd23 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerParent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 747465b5900df494a8064194e81a3a4b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerScreenspaceParent.cs b/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerScreenspaceParent.cs new file mode 100644 index 0000000..bfe9330 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerScreenspaceParent.cs @@ -0,0 +1,115 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Internal Not For Manual Creation/Visualizer Screenspace Parent")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class VisualizerScreenspaceParent : VisualizerParent + { + public enum ScreenspaceDefiningCameras { cameraAtThisGameobject, manuallyAssignedCamera, automaticallySearchForMainGameViewCamera, sceneViewCamera }; + [SerializeField] public ScreenspaceDefiningCameras screenspaceDefiningCamera = ScreenspaceDefiningCameras.cameraAtThisGameobject; + ScreenspaceDefiningCameras screenspaceDefiningCamera_duringLastCall = ScreenspaceDefiningCameras.cameraAtThisGameobject; + + Camera cameraComponentOnThisGameobject; + Camera sceneViewCamera_thatStaysEvenIfTheFocusChangesToAnotherSceneViewWindow; + [SerializeField] public Camera manuallyAssignedCamera; + [SerializeField] public bool alwaysChangeToCurrentlyActiveSceneView_insteadOfStayingAtTheSelectedOne = false; + Camera usedCamera; + [SerializeField] public bool usedCameraIsAvailable; + public Vector2 positionInsideViewport0to1 = new Vector2(0.5f, 0.5f); + public Vector2 positionInsideViewport0to1_v2 = new Vector2(0.5f, 0.5f); + + public void TryFetchCamOnThisGO_andDecideScreenspaceDefiningCamera() + { + //-> is also called when components or gameobjects (containing this component) get copied und therefore the reference is updated to the new camera component on the new gameobject + if (screenspaceDefiningCamera == ScreenspaceDefiningCameras.cameraAtThisGameobject) + { + this.TryGetComponent(out cameraComponentOnThisGameobject); + if (cameraComponentOnThisGameobject == null) + { + screenspaceDefiningCamera = ScreenspaceDefiningCameras.automaticallySearchForMainGameViewCamera; + screenspaceDefiningCamera_duringLastCall = ScreenspaceDefiningCameras.automaticallySearchForMainGameViewCamera; + } + } + } + + public Camera Get_usedCamera(string nameOfComponentForErrorLog) + { + switch (screenspaceDefiningCamera) + { + case ScreenspaceDefiningCameras.cameraAtThisGameobject: + if (cameraComponentOnThisGameobject == null) + { + //this is for the case when a camera component is created at the gameobject AFTER the drawer component has been created + //it is accepted to call "TryGetComponent" here frequently (per Update-loop), because it is anyway only during an invalid case ("no camera found") on which the user gets notified to fix it via inspector help box. + this.TryGetComponent(out cameraComponentOnThisGameobject); + } + usedCamera = cameraComponentOnThisGameobject; + break; + case ScreenspaceDefiningCameras.manuallyAssignedCamera: + usedCamera = manuallyAssignedCamera; + break; + case ScreenspaceDefiningCameras.automaticallySearchForMainGameViewCamera: + UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out usedCamera, nameOfComponentForErrorLog, true); + break; + case ScreenspaceDefiningCameras.sceneViewCamera: +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + if (sceneViewCamera_thatStaysEvenIfTheFocusChangesToAnotherSceneViewWindow == null) { sceneViewCamera_thatStaysEvenIfTheFocusChangesToAnotherSceneViewWindow = UnityEditor.SceneView.lastActiveSceneView.camera; } + + if ((screenspaceDefiningCamera_duringLastCall != ScreenspaceDefiningCameras.sceneViewCamera) || (alwaysChangeToCurrentlyActiveSceneView_insteadOfStayingAtTheSelectedOne == true)) + { + sceneViewCamera_thatStaysEvenIfTheFocusChangesToAnotherSceneViewWindow = UnityEditor.SceneView.lastActiveSceneView.camera; + } + + if (alwaysChangeToCurrentlyActiveSceneView_insteadOfStayingAtTheSelectedOne == false) + { + usedCamera = sceneViewCamera_thatStaysEvenIfTheFocusChangesToAnotherSceneViewWindow; + } + else + { + usedCamera = UnityEditor.SceneView.lastActiveSceneView.camera; + } + } + else + { + usedCamera = null; + } +#else + UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out usedCamera, nameOfComponentForErrorLog, true); +#endif + break; + default: + usedCamera = null; + break; + } + + screenspaceDefiningCamera_duringLastCall = screenspaceDefiningCamera; + usedCameraIsAvailable = (usedCamera != null); + return usedCamera; + } + + public bool CheckIf_usedCameraIsActiveAndEnabled() + { + if (usedCamera != null) + { + bool isSceneViewCamera = false; +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + isSceneViewCamera = (usedCamera == UnityEditor.SceneView.lastActiveSceneView.camera); + } +#endif + return (isSceneViewCamera || usedCamera.isActiveAndEnabled); + } + else + { + return false; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerScreenspaceParent.cs.meta b/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerScreenspaceParent.cs.meta new file mode 100644 index 0000000..fadeeae --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/internal utilities/VisualizerScreenspaceParent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 652dc1e2204fe18489ba53c3044899bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/screenspace.meta b/Runtime/DrawDebugLibrary/components/screenspace.meta new file mode 100644 index 0000000..0cff245 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 054f03ff1d768954d84d5535e9df0296 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/screenspace/CameraGridVisualizer.cs b/Runtime/DrawDebugLibrary/components/screenspace/CameraGridVisualizer.cs new file mode 100644 index 0000000..d4dc3cf --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace/CameraGridVisualizer.cs @@ -0,0 +1,37 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Screenspace/Camera Grid Visualizer")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class CameraGridVisualizer : VisualizerScreenspaceParent + { + [SerializeField] Color color = DrawBasics.defaultColor; + [SerializeField] [Range(0.0f, 0.1f)] float linesWidth_relToViewportHeight = 0.0f; + [SerializeField] bool drawTenthLines = true; + [SerializeField] bool drawHundredthLines = true; + [SerializeField] DrawEngineBasics.GridScreenspaceMode gridScreenspaceMode = DrawEngineBasics.GridScreenspaceMode.warpWidthAndHeightIndividuallyToFitScreenInBothAxes; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + } + + public override void InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy() + { + TryFetchCamOnThisGO_andDecideScreenspaceDefiningCamera(); + } + + public override void DrawVisualizedObject() + { + Camera usedCamera = Get_usedCamera("Camera Grid Visualizer Component"); + if (usedCamera != null) + { + DrawEngineBasics.GridScreenspace(usedCamera, color, linesWidth_relToViewportHeight, drawTenthLines, drawHundredthLines, gridScreenspaceMode, 0.0f); + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/screenspace/CameraGridVisualizer.cs.meta b/Runtime/DrawDebugLibrary/components/screenspace/CameraGridVisualizer.cs.meta new file mode 100644 index 0000000..5746c5d --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace/CameraGridVisualizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bed2be6d23f8c0f4aa4be27ce39bf45e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/screenspace/LineDrawerScreenspace.cs b/Runtime/DrawDebugLibrary/components/screenspace/LineDrawerScreenspace.cs new file mode 100644 index 0000000..69593d5 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace/LineDrawerScreenspace.cs @@ -0,0 +1,309 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Screenspace/Line Drawer Screenspace")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class LineDrawerScreenspace : VisualizerScreenspaceParent + { + [SerializeField] LineDrawer.LineType lineType = LineDrawer.LineType.standardLine; + [SerializeField] LineDrawer.LineDefinitionMode lineDefinitionMode = LineDrawer.LineDefinitionMode.startPositionAndEndPosition; + [SerializeField] public bool lineDefinitionSection1_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] public bool lineDefinitionSection2_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + + //Shared: + [SerializeField] bool interpretDirectionAsUnwarped = false; + [SerializeField] Color startColor = DrawBasics.defaultColor; + [SerializeField] bool useDifferentEndColor = false; + [SerializeField] Color endColor = UtilitiesDXXL_Colors.red_boolFalse; + [SerializeField] [Range(0.0f, 0.15f)] float lineWidth_relToViewportHeight = 0.0f; + [SerializeField] DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid; + [SerializeField] float stylePatternScaleFactor = 1.0f; + [SerializeField] bool animationDuringEditMode = true; + [SerializeField] float animationSpeed = 0.0f; + LineAnimationProgress precedingLineAnimationProgress = new LineAnimationProgress(); + [SerializeField] bool enlargeSmallTextToThisMinTextSize = true; + [SerializeField] [Range(0.0f, 0.3f)] float enlargeSmallTextToThisMinRelTextSize_value = DrawScreenspace.minTextSize_relToViewportHeight; + [SerializeField] LineDrawer.EndPlatesConfig endPlatesConfig = LineDrawer.EndPlatesConfig.disabled; + [SerializeField] [Range(0.0f, 0.5f)] float endPlatesSize_relToViewportHeight = 0.1f; //is initially disabled due to "endPlatesConfig" + [SerializeField] [Range(0.0f, 0.5f)] float alphaFadeOutLength_0to1 = 0.0f; + [SerializeField] bool shiftTextPosOnLines_toNonIntersecting = false; + [SerializeField] [Range(0.05f, 10.0f)] float relSizeOfTextOnLines = 0.45f; + + //Vectors: + [SerializeField] LineDrawer.ConesConfig conesConfig = LineDrawer.ConesConfig.onlyAtEnd; + [SerializeField] [Range(0.0f, 0.3f)] float coneLength_relToViewportHeight = 0.05f; + [SerializeField] bool writeComponentValuesAsText = false; + + //Vectors With Extention: + [SerializeField] bool displayDistanceOutsideScreenBorder = true; + + //Blinking Line: + [SerializeField] Color blinkColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawBasics.defaultColor, 0.2f); + [SerializeField] float blinkDurationInSec = 0.5f; + + //Line under tension: + [SerializeField] [Range(0.001f, 2.0f)] public float relaxedLength_relToViewportHeight = 0.4f; + [SerializeField] public float stretchFactor_forStretchedTensionColor = 2.0f; + [SerializeField] public float stretchFactor_forSqueezedTensionColor = 0.0f; + [SerializeField] public DrawBasics.LineStyle lineStyle_underTension = DrawBasics.LineStyle.sine; + [SerializeField] public Color relaxedColor = UtilitiesDXXL_Colors.green_boolTrue; + [SerializeField] public Color color_forStretchedTension = UtilitiesDXXL_Colors.red_boolFalse; + [SerializeField] public Color color_forSqueezedTension = UtilitiesDXXL_Colors.red_boolFalse; + [SerializeField] [Range(0.0f, 1.0f)] public float alphaOfReferenceLengthDisplay = 0.1f; + + //Moving arrows line: + [SerializeField] [Range(0.0f, 0.15f)] float lineWidth_ofMovingArrowsLine_relToViewportHeight = 0.016f; + [SerializeField] float animationSpeed_ofMovingArrowsLine = 0.5f; + [SerializeField] [Range(0.02f, 0.5f)] float distanceBetweenArrows_relToViewportHeight = 0.11f; + [SerializeField] [Range(0.01f, 0.3f)] float lengthOfArrows_relToViewportHeight = 0.05f; + [SerializeField] bool backwardAnimationFlipsArrowDirection = true; + + //Line with alternating colors: + [SerializeField] Color alternatingColor = DrawBasics.defaultColor2_ofAlternatingColorLines; + [SerializeField] [Range(0.001f, 0.2f)] float lengthOfStripes_relToViewportHeight = 0.03f; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + + customVector2Configs[0].picker_isOutfolded = true; + customVector2Configs[0].source = CustomVector2Source.manualInput; + customVector2Configs[0].clipboardForManualInput = 0.4f * Vector2.one; + customVector2Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + + positionInsideViewport0to1 = new Vector2(0.3f, 0.3f);//-> initial line start position + positionInsideViewport0to1_v2 = new Vector2(0.7f, 0.7f);//-> initial line end position + } + + public override void InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy() + { + TryFetchCamOnThisGO_andDecideScreenspaceDefiningCamera(); + } + + public override void DrawVisualizedObject() + { + Camera usedCamera = Get_usedCamera("Shape Drawer Screenspace Component"); + if (usedCamera != null) + { + float used_enlargeSmallTextToThisMinRelTextSize_value = enlargeSmallTextToThisMinTextSize ? enlargeSmallTextToThisMinRelTextSize_value : 0.0f; + float used_endPlatesSize_relToViewportHeight = Set_endPlatesConfig_reversible(); + UtilitiesDXXL_DrawBasics.Set_shiftTextPosOnLines_toNonIntersecting_reversible(shiftTextPosOnLines_toNonIntersecting); + UtilitiesDXXL_DrawBasics.Set_relSizeOfTextOnLines_reversible(relSizeOfTextOnLines); + GetLineStartPosAndDirection(out Vector2 lineStartPosition, out Vector2 vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, usedCamera); + bool used_interpretDirectionAsUnwarped = false; //-> "GetLineStartPosAndDirection()" already cares for "interpretDirectionAsUnwarped" + + switch (lineType) + { + case LineDrawer.LineType.standardLine: + if (useDifferentEndColor) + { + precedingLineAnimationProgress = LineFrom_fadeableAnimSpeed_screenspace.InternalDraw_withColorFade(usedCamera, lineStartPosition, vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, startColor, endColor, lineWidth_relToViewportHeight, text_inclGlobalMarkupTags, used_interpretDirectionAsUnwarped, lineStyle, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, used_endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinRelTextSize_value, 0.0f); + } + else + { + precedingLineAnimationProgress = LineFrom_fadeableAnimSpeed_screenspace.InternalDraw(usedCamera, lineStartPosition, vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, startColor, lineWidth_relToViewportHeight, text_inclGlobalMarkupTags, used_interpretDirectionAsUnwarped, lineStyle, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, used_endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinRelTextSize_value, 0.0f); + } + break; + case LineDrawer.LineType.vector: + switch (conesConfig) + { + case LineDrawer.ConesConfig.bothSides: + DrawScreenspace.VectorFrom(usedCamera, lineStartPosition, vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, startColor, lineWidth_relToViewportHeight, text_inclGlobalMarkupTags, used_interpretDirectionAsUnwarped, coneLength_relToViewportHeight, true, writeComponentValuesAsText, used_endPlatesSize_relToViewportHeight, 0.0f); + break; + case LineDrawer.ConesConfig.onlyAtStart: + DrawScreenspace.VectorTo(usedCamera, -vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, lineStartPosition, startColor, lineWidth_relToViewportHeight, text_inclGlobalMarkupTags, used_interpretDirectionAsUnwarped, coneLength_relToViewportHeight, false, writeComponentValuesAsText, used_endPlatesSize_relToViewportHeight, 0.0f); + break; + case LineDrawer.ConesConfig.onlyAtEnd: + DrawScreenspace.VectorFrom(usedCamera, lineStartPosition, vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, startColor, lineWidth_relToViewportHeight, text_inclGlobalMarkupTags, used_interpretDirectionAsUnwarped, coneLength_relToViewportHeight, false, writeComponentValuesAsText, used_endPlatesSize_relToViewportHeight, 0.0f); + break; + default: + break; + } + break; + case LineDrawer.LineType.vectorWithExtention: + DrawEngineBasics.RayLineExtendedScreenspace(usedCamera, lineStartPosition, vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, startColor, lineWidth_relToViewportHeight, text_inclGlobalMarkupTags, used_interpretDirectionAsUnwarped, coneLength_relToViewportHeight, displayDistanceOutsideScreenBorder, 0.0f); + break; + case LineDrawer.LineType.blinkingLine: + float used_blinkDurationInSec = ((Application.isPlaying == false) && (animationDuringEditMode == false)) ? float.MaxValue : blinkDurationInSec; //-> this prevents a problem in the situation where "animationDuringEditMode" has been disabled in a blink phase where the line is not possible. Otherwise in such cases the line would permanently invisible. + DrawScreenspace.BlinkingRay(usedCamera, lineStartPosition, vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, startColor, used_blinkDurationInSec, lineWidth_relToViewportHeight, text_inclGlobalMarkupTags, used_interpretDirectionAsUnwarped, lineStyle, blinkColor, stylePatternScaleFactor, used_endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, used_enlargeSmallTextToThisMinRelTextSize_value, 0.0f); + break; + case LineDrawer.LineType.lineUnderTension: + DrawScreenspace.RayUnderTension(usedCamera, lineStartPosition, vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, relaxedLength_relToViewportHeight, relaxedColor, lineStyle_underTension, stretchFactor_forStretchedTensionColor, color_forStretchedTension, stretchFactor_forSqueezedTensionColor, color_forSqueezedTension, lineWidth_relToViewportHeight, text_inclGlobalMarkupTags, alphaOfReferenceLengthDisplay, used_interpretDirectionAsUnwarped, stylePatternScaleFactor, used_endPlatesSize_relToViewportHeight, used_enlargeSmallTextToThisMinRelTextSize_value, 0.0f); + break; + case LineDrawer.LineType.movingArrowsLine: + precedingLineAnimationProgress = MovingArrowsRay_fadeableAnimSpeed_screenspace.InternalDraw(usedCamera, lineStartPosition, vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, startColor, lineWidth_ofMovingArrowsLine_relToViewportHeight, distanceBetweenArrows_relToViewportHeight, lengthOfArrows_relToViewportHeight, text_inclGlobalMarkupTags, animationSpeed_ofMovingArrowsLine, precedingLineAnimationProgress, backwardAnimationFlipsArrowDirection, used_interpretDirectionAsUnwarped, used_endPlatesSize_relToViewportHeight, 0.0f); + break; + case LineDrawer.LineType.lineWithAlternatingColors: + precedingLineAnimationProgress = RayWithAlternatingColors_fadeableAnimSpeed_screenspace.InternalDraw(usedCamera, lineStartPosition, vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, startColor, alternatingColor, lineWidth_relToViewportHeight, lengthOfStripes_relToViewportHeight, text_inclGlobalMarkupTags, used_interpretDirectionAsUnwarped, animationSpeed, precedingLineAnimationProgress, used_endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, 0.0f); + break; + default: + break; + } + + UtilitiesDXXL_DrawBasics.Reverse_shiftTextPosOnLines_toNonIntersecting(); + UtilitiesDXXL_DrawBasics.Reverse_relSizeOfTextOnLines(); + Reverse_endPlatesConfig(); + + TrySheduleRepaintSceneViewForAnimationOutsidePlaymode(); + } + } + + void GetLineStartPosAndDirection(out Vector2 lineStartPosition, out Vector2 vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, Camera usedCamera) + { + Vector2 lineEndPosition; + switch (lineDefinitionMode) + { + case LineDrawer.LineDefinitionMode.startPositionAndEndPosition: + lineStartPosition = positionInsideViewport0to1; + lineEndPosition = positionInsideViewport0to1_v2; + vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace = lineEndPosition - lineStartPosition; + break; + case LineDrawer.LineDefinitionMode.startPositionAndDirectionVectorToEndPosition: + lineStartPosition = positionInsideViewport0to1; + vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace = Get_vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace(usedCamera); + break; + case LineDrawer.LineDefinitionMode.endPositionAndDirectionVectorToIt: + lineEndPosition = positionInsideViewport0to1_v2; + vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace = Get_vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace(usedCamera); + lineStartPosition = lineEndPosition - vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace; + break; + default: + lineStartPosition = Vector2.zero; + vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace = Vector2.one; + break; + } + } + + Vector2 Get_vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace(Camera usedCamera) + { + if (interpretDirectionAsUnwarped || (customVector2Configs[0].source == CustomVector2Source.rotationAroundZStartingFromRight)) + { + return DrawScreenspace.DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(Get_customVector2_1_inGlobalSpaceUnits(), usedCamera); + } + else + { + return Get_customVector2_1_inGlobalSpaceUnits(); + } + } + + float Set_endPlatesConfig_reversible() + { + if (endPlatesConfig == LineDrawer.EndPlatesConfig.disabled) + { + return 0.0f; + } + else + { + switch (endPlatesConfig) + { + case LineDrawer.EndPlatesConfig.bothSides: + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineStart_reversible(false); + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineEnd_reversible(false); + break; + case LineDrawer.EndPlatesConfig.onlyAtStart: + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineStart_reversible(false); + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineEnd_reversible(true); + break; + case LineDrawer.EndPlatesConfig.onlyAtEnd: + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineStart_reversible(true); + UtilitiesDXXL_DrawBasics.Set_disableEndPlates_atLineEnd_reversible(false); + break; + default: + break; + } + return endPlatesSize_relToViewportHeight; + } + } + + void Reverse_endPlatesConfig() + { + if (endPlatesConfig != LineDrawer.EndPlatesConfig.disabled) + { + UtilitiesDXXL_DrawBasics.Reverse_disableEndPlates_atLineStart(); + UtilitiesDXXL_DrawBasics.Reverse_disableEndPlates_atLineEnd(); + } + } + + void TrySheduleRepaintSceneViewForAnimationOutsidePlaymode() + { + if (animationDuringEditMode) + { + if (Application.isPlaying == false) + { + if (DrawnLineUsesAnimation(true)) + { + UtilitiesDXXL_Components.currentVirtualOnDrawGizmoCycle_shouldRepaintAllViews = true; + } + } + } + } + + public bool DrawnLineUsesAnimation(bool returnFalseForAnimationSpeedOfZero) + { + if (lineType == LineDrawer.LineType.standardLine) + { + if (UtilitiesDXXL_LineStyles.CheckIfLineStyleIsAnimatable(lineStyle)) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(animationSpeed)) + { + return (!returnFalseForAnimationSpeedOfZero); + } + else + { + return true; + } + } + } + + if (lineType == LineDrawer.LineType.lineWithAlternatingColors) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(animationSpeed)) + { + return (!returnFalseForAnimationSpeedOfZero); + } + else + { + return true; + } + } + + if (lineType == LineDrawer.LineType.movingArrowsLine) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(animationSpeed_ofMovingArrowsLine)) + { + return (!returnFalseForAnimationSpeedOfZero); + } + else + { + return true; + } + } + + if (lineType == LineDrawer.LineType.blinkingLine) + { + return true; + } + + return false; + } + + public float GetLineLength_relToViewportHeight() + { + Camera usedCamera = Get_usedCamera("Shape Drawer Screenspace Component"); + if (usedCamera != null) + { + GetLineStartPosAndDirection(out Vector2 lineStartPosition, out Vector2 vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, usedCamera); + Vector2 vector_fromLineStart_toLineEnd_inUnwarpedScreenspace = DrawScreenspace.DirectionInUnitsOfWarpedSpace_to_sameLookingDirectionInUnitsOfUnwarpedSpace(vector_fromLineStart_toLineEnd_inAspectWarpedScreenspace, usedCamera); + return vector_fromLineStart_toLineEnd_inUnwarpedScreenspace.magnitude; + } + else + { + return 1.0f; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/screenspace/LineDrawerScreenspace.cs.meta b/Runtime/DrawDebugLibrary/components/screenspace/LineDrawerScreenspace.cs.meta new file mode 100644 index 0000000..0f091c7 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace/LineDrawerScreenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8098e825ea019cd4d9096b73d43f298b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/screenspace/ShapeDrawerScreenspace.cs b/Runtime/DrawDebugLibrary/components/screenspace/ShapeDrawerScreenspace.cs new file mode 100644 index 0000000..cd6d5fb --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace/ShapeDrawerScreenspace.cs @@ -0,0 +1,126 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Screenspace/Shape Drawer Screenspace")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class ShapeDrawerScreenspace : VisualizerScreenspaceParent + { + [SerializeField] ShapeDrawer2D.ShapeType shapeType = ShapeDrawer2D.ShapeType.circle; + + //size definitions: + [SerializeField] [Range(0.0f, 1.5f)] float radius_relToViewportHeight = 0.05f; + [SerializeField] [Range(0.0f, 1.5f)] float width_relToViewportHeight_initialValue01 = 0.1f; + [SerializeField] [Range(0.0f, 1.5f)] float height_relToViewportHeight_initialValue01 = 0.1f; + [SerializeField] [Range(0.0f, 1.5f)] float height_relToViewportHeight_initialValue02 = 0.2f; + [SerializeField] [Range(0.0f, 1.5f)] float sizeOfIcon_relToViewportHeight = 0.1f; + + //other definitions: + [SerializeField] [Range(-360.0f, 360.0f)] float zRotationDegCC = 0.0f; + [SerializeField] Color color = DrawBasics.defaultColor; + [SerializeField] [Range(0.0f, 0.2f)] float linesWidth_relToViewportHeight = 0.0f; + [SerializeField] DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid; + [SerializeField] float stylePatternScaleFactor = 1.0f; + [SerializeField] DrawBasics.LineStyle fillStyle = DrawBasics.LineStyle.invisible; + [SerializeField] float shapeFillDensity = 1.0f; + [SerializeField] bool drawPointerIfOffscreen = true; + [SerializeField] bool addTextForOutsideDistance_toOffscreenPointer = true; + [SerializeField] DrawBasics.IconType iconType = DrawBasics.IconType.car; + [SerializeField] bool iconIsMirroredHorizontally = false; + [SerializeField] CapsuleDirection2D capusleDirection2D = CapsuleDirection2D.Vertical; + [SerializeField] ShapeDrawer.CornerOptionsForIrregularStar cornerOptionsForIrregularStar = ShapeDrawer.CornerOptionsForIrregularStar._5; + [SerializeField] bool drawHullEdgeLines_forScreenEncasingShapes = false; + [SerializeField] float dotDensity = 1.0f; + + public override void InitializeValues_onceInComponentLifetime() + { + TrySetTextToEmptyString(); + } + + public override void InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy() + { + TryFetchCamOnThisGO_andDecideScreenspaceDefiningCamera(); + } + + public override void DrawVisualizedObject() + { + Camera usedCamera = Get_usedCamera("Shape Drawer Screenspace Component"); + if (usedCamera != null) + { + UtilitiesDXXL_LineStyles.logWarningToConsole_forTooSmallPatternScaleFactor = false; + switch (shapeType) + { + case ShapeDrawer2D.ShapeType.circle: + float size_ofCircleHull = 2.0f * radius_relToViewportHeight; + + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + UtilitiesDXXL_Screenspace.DrawShape(usedCamera, positionInsideViewport0to1, DrawShapes.Shape2DType.circle, color, color, size_ofCircleHull, size_ofCircleHull, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, fillStyle, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, 0.0f, 1.0f, null, drawHullEdgeLines_forScreenEncasingShapes); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + break; + case ShapeDrawer2D.ShapeType.ellipse: + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + UtilitiesDXXL_Screenspace.DrawShape(usedCamera, positionInsideViewport0to1, DrawShapes.Shape2DType.circle, color, color, width_relToViewportHeight_initialValue01, height_relToViewportHeight_initialValue02, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, fillStyle, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, 0.0f, 1.0f, null, drawHullEdgeLines_forScreenEncasingShapes); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + break; + case ShapeDrawer2D.ShapeType.star: + UtilitiesDXXL_Screenspace.DrawShape(usedCamera, positionInsideViewport0to1, ShapeDrawer.Get_shape2DType_forIrregularStar(cornerOptionsForIrregularStar), color, color, width_relToViewportHeight_initialValue01, height_relToViewportHeight_initialValue01, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, DrawBasics.LineStyle.invisible, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, 0.0f, 1.0f, null, drawHullEdgeLines_forScreenEncasingShapes); + break; + case ShapeDrawer2D.ShapeType.capsule: + Vector2 sizeOfCapsule_relToViewportHeight = new Vector2(width_relToViewportHeight_initialValue01, height_relToViewportHeight_initialValue02); + + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + UtilitiesDXXL_Screenspace.Capsule(usedCamera, positionInsideViewport0to1, sizeOfCapsule_relToViewportHeight, color, capusleDirection2D, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, drawPointerIfOffscreen, lineStyle, stylePatternScaleFactor, fillStyle, addTextForOutsideDistance_toOffscreenPointer, 0.0f, drawHullEdgeLines_forScreenEncasingShapes); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + break; + case ShapeDrawer2D.ShapeType.icon: + DrawScreenspace.Icon(usedCamera, positionInsideViewport0to1, iconType, color, sizeOfIcon_relToViewportHeight, text_inclGlobalMarkupTags, zRotationDegCC, linesWidth_relToViewportHeight, drawPointerIfOffscreen, iconIsMirroredHorizontally, 0.0f); + break; + case ShapeDrawer2D.ShapeType.triangle: + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + UtilitiesDXXL_Screenspace.DrawShape(usedCamera, positionInsideViewport0to1, DrawShapes.Shape2DType.triangle, color, color, width_relToViewportHeight_initialValue01, height_relToViewportHeight_initialValue01, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, fillStyle, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, 0.0f, 1.0f, null, drawHullEdgeLines_forScreenEncasingShapes); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + break; + case ShapeDrawer2D.ShapeType.square: + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + UtilitiesDXXL_Screenspace.DrawShape(usedCamera, positionInsideViewport0to1, DrawShapes.Shape2DType.square, color, color, width_relToViewportHeight_initialValue01, height_relToViewportHeight_initialValue01, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, fillStyle, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, 0.0f, 1.0f, null, drawHullEdgeLines_forScreenEncasingShapes); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + break; + case ShapeDrawer2D.ShapeType.pentagon: + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + UtilitiesDXXL_Screenspace.DrawShape(usedCamera, positionInsideViewport0to1, DrawShapes.Shape2DType.pentagon, color, color, width_relToViewportHeight_initialValue01, height_relToViewportHeight_initialValue01, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, fillStyle, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, 0.0f, 1.0f, null, drawHullEdgeLines_forScreenEncasingShapes); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + break; + case ShapeDrawer2D.ShapeType.hexagon: + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + UtilitiesDXXL_Screenspace.DrawShape(usedCamera, positionInsideViewport0to1, DrawShapes.Shape2DType.hexagon, color, color, width_relToViewportHeight_initialValue01, height_relToViewportHeight_initialValue01, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, fillStyle, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, 0.0f, 1.0f, null, drawHullEdgeLines_forScreenEncasingShapes); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + break; + case ShapeDrawer2D.ShapeType.septagon: + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + UtilitiesDXXL_Screenspace.DrawShape(usedCamera, positionInsideViewport0to1, DrawShapes.Shape2DType.septagon, color, color, width_relToViewportHeight_initialValue01, height_relToViewportHeight_initialValue01, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, fillStyle, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, 0.0f, 1.0f, null, drawHullEdgeLines_forScreenEncasingShapes); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + break; + case ShapeDrawer2D.ShapeType.octagon: + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + UtilitiesDXXL_Screenspace.DrawShape(usedCamera, positionInsideViewport0to1, DrawShapes.Shape2DType.octagon, color, color, width_relToViewportHeight_initialValue01, height_relToViewportHeight_initialValue01, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, fillStyle, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, 0.0f, 1.0f, null, drawHullEdgeLines_forScreenEncasingShapes); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + break; + case ShapeDrawer2D.ShapeType.decagon: + UtilitiesDXXL_Shapes.Set_shapeFillDensity_reversible(shapeFillDensity); + UtilitiesDXXL_Screenspace.DrawShape(usedCamera, positionInsideViewport0to1, DrawShapes.Shape2DType.decagon, color, color, width_relToViewportHeight_initialValue01, height_relToViewportHeight_initialValue01, zRotationDegCC, linesWidth_relToViewportHeight, text_inclGlobalMarkupTags, lineStyle, stylePatternScaleFactor, fillStyle, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, 0.0f, 1.0f, null, drawHullEdgeLines_forScreenEncasingShapes); + UtilitiesDXXL_Shapes.Reverse_shapeFillDensity(); + break; + case ShapeDrawer2D.ShapeType.dot: + DrawScreenspace.Dot(usedCamera, positionInsideViewport0to1, radius_relToViewportHeight, color, text_inclGlobalMarkupTags, dotDensity, drawPointerIfOffscreen, 0.0f); + break; + default: + break; + } + UtilitiesDXXL_LineStyles.logWarningToConsole_forTooSmallPatternScaleFactor = true; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/screenspace/ShapeDrawerScreenspace.cs.meta b/Runtime/DrawDebugLibrary/components/screenspace/ShapeDrawerScreenspace.cs.meta new file mode 100644 index 0000000..b2145ca --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace/ShapeDrawerScreenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d5fdf0d5a1f81dc4eb379bd7b5e26d61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/screenspace/TagDrawerScreenspace.cs b/Runtime/DrawDebugLibrary/components/screenspace/TagDrawerScreenspace.cs new file mode 100644 index 0000000..797da7f --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace/TagDrawerScreenspace.cs @@ -0,0 +1,135 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Screenspace/Tag Drawer Screenspace")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class TagDrawerScreenspace : VisualizerScreenspaceParent + { + public enum TaggedPositionType { positionOnViewport, aGameobject, multipleGameobjects }; + [SerializeField] TaggedPositionType taggedPositionType = TaggedPositionType.positionOnViewport; + public enum PointerDirectionSpecificationType { fixedAngle, vanishingPointPosition }; + [SerializeField] PointerDirectionSpecificationType pointerDirectionSpecificationType = PointerDirectionSpecificationType.vanishingPointPosition; + + //both types: + [SerializeField] [Range(0.0f, 0.2f)] float linesWidth_relToViewportHeight = 0.0f; + [SerializeField] Color colorForText = DrawBasics.defaultColor; + [SerializeField] bool drawPointerIfOffscreen = true; + + //only for "positionOnViewport": + [SerializeField] bool forceTextSize = false; + [SerializeField] [Range(0.01f, 0.5f)] float forceTextSize_value = 0.1f; + [SerializeField] bool skipConeDrawing = false; + [SerializeField] bool addTextForOutsideDistance_toOffscreenPointer = true; + static float default_textOffsetDistance_relToViewportHeight = 0.2f; + [SerializeField] [Range(0.035f, 1.0f)] float textOffsetDistance_relToViewportHeight = default_textOffsetDistance_relToViewportHeight; + [SerializeField] [Range(-360f, 360.0f)] float fixedPointerDiretion_angledDegCC = -30.0f; + + //only for "aGameobject": + [SerializeField] bool differentBoxColor = false; + [SerializeField] Color differentBoxColor_value = UtilitiesDXXL_Colors.violet; + [SerializeField] bool encapsulateChildren = true; + + //only for "multipleGameobjects": + [SerializeField] InternalDXXL_TaggedScreenspaceObject[] taggedScreenspaceObjects; + + public override void InitializeValues_onceInComponentLifetime() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = "tag text"; + text_inclGlobalMarkupTags = "tag text"; + } + textSection_isOutfolded = true; + positionInsideViewport0to1 = new Vector2(0.35f, 0.35f); + positionInsideViewport0to1_v2 = new Vector2(0.5f, 0.5f); + } + + public override void InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy() + { + TryFetchCamOnThisGO_andDecideScreenspaceDefiningCamera(); + } + + public override void DrawVisualizedObject() + { + Camera usedCamera = Get_usedCamera("Tag Drawer Screenspace Component"); + if (usedCamera != null) + { + float used_relTextSizeScaling; + switch (taggedPositionType) + { + case TaggedPositionType.positionOnViewport: + used_relTextSizeScaling = Get_used_relTextSizeScaling(); + Get_vanishingPointSpecs(out Vector2 textOffsetDir, out Vector2 customTowardsPoint_ofDefaultTextOffsetDir, usedCamera); + DrawScreenspace.PointTag(usedCamera, positionInsideViewport0to1, text_inclGlobalMarkupTags, null, colorForText, drawPointerIfOffscreen, linesWidth_relToViewportHeight, textOffsetDistance_relToViewportHeight, textOffsetDir, used_relTextSizeScaling, skipConeDrawing, addTextForOutsideDistance_toOffscreenPointer, 0.0f, customTowardsPoint_ofDefaultTextOffsetDir); + break; + case TaggedPositionType.aGameobject: + Color used_colorForBox = differentBoxColor ? differentBoxColor_value : colorForText; + TagAGameobject(usedCamera, partnerGameobject, text_inclGlobalMarkupTags, used_colorForBox); + break; + case TaggedPositionType.multipleGameobjects: + if (taggedScreenspaceObjects != null) + { + for (int i = 0; i < taggedScreenspaceObjects.Length; i++) + { + taggedScreenspaceObjects[i].TryUseSeededColorFromGameobjectID(); + TagAGameobject(usedCamera, taggedScreenspaceObjects[i].gameobject, taggedScreenspaceObjects[i].text, taggedScreenspaceObjects[i].color); + } + } + break; + default: + break; + } + } + } + + void TagAGameobject(Camera usedCamera, GameObject gameobjectToTag, string textAtGameobject, Color used_colorForBox) + { + if (gameobjectToTag != null) + { + //float used_relTextSizeScaling = forceTextSize_value; //"TagGameObjectScreenspace()" uses a fixed text size indepentent of the box size. So an "absolute" forceTextSize_value can be used here as "relative scaler", because "relative" already means "relative to viewport height". And that is an "absolute" size in the sense, that it is "absoulte in viewportSpaceUnits" and not "relative to boxSize/pointerLength". + float used_relTextSizeScaling = 1.0f; //In the "aGameobject"-case the text size is not scaled via the "relTextSizeScaling" parameter but via "Text/Style/Size scaling" + DrawEngineBasics.TagGameObjectScreenspace(usedCamera, gameobjectToTag, textAtGameobject, colorForText, used_colorForBox, linesWidth_relToViewportHeight, drawPointerIfOffscreen, used_relTextSizeScaling, encapsulateChildren, 0.0f); + } + } + + float Get_used_relTextSizeScaling() + { + //This relative scaler is used to actually produce an "absolute" text size ("absoulte in viewportSpaceUnits") + if (forceTextSize) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(textOffsetDistance_relToViewportHeight) == false) + { + return ((forceTextSize_value * default_textOffsetDistance_relToViewportHeight) / (textOffsetDistance_relToViewportHeight * UtilitiesDXXL_DrawBasics.pointTagsTextSize_relToOffset)); + } + } + return 1.0f; + } + + void Get_vanishingPointSpecs(out Vector2 textOffsetDir, out Vector2 customTowardsPoint_ofDefaultTextOffsetDir, Camera usedCamera) + { + switch (pointerDirectionSpecificationType) + { + case PointerDirectionSpecificationType.fixedAngle: + Quaternion rotation_fromUp = Quaternion.AngleAxis(fixedPointerDiretion_angledDegCC, Vector3.forward); + Vector3 textOffsetDir_asV3 = rotation_fromUp * Vector3.up; + Vector2 textOffsetDir_inUnwarpedSpace = (new Vector2(textOffsetDir_asV3.x, textOffsetDir_asV3.y)); + Vector2 textOffsetDir_inWarpedSpace = DrawScreenspace.DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(textOffsetDir_inUnwarpedSpace, usedCamera); + textOffsetDir = textOffsetDir_inWarpedSpace; + customTowardsPoint_ofDefaultTextOffsetDir = default(Vector2); + break; + case PointerDirectionSpecificationType.vanishingPointPosition: + textOffsetDir = default(Vector2); + customTowardsPoint_ofDefaultTextOffsetDir = positionInsideViewport0to1_v2; + break; + default: + textOffsetDir = default(Vector2); + customTowardsPoint_ofDefaultTextOffsetDir = default(Vector2); + break; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/screenspace/TagDrawerScreenspace.cs.meta b/Runtime/DrawDebugLibrary/components/screenspace/TagDrawerScreenspace.cs.meta new file mode 100644 index 0000000..d12b4f0 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace/TagDrawerScreenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cba906df682cf2542baabe02418016ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/components/screenspace/TextDrawerScreenspace.cs b/Runtime/DrawDebugLibrary/components/screenspace/TextDrawerScreenspace.cs new file mode 100644 index 0000000..c2a5ff1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace/TextDrawerScreenspace.cs @@ -0,0 +1,109 @@ +namespace DrawXXL +{ + using UnityEngine; + + [HelpURL("https://www.symphonygames.net/drawxxldocumentation/index.html")] + [AddComponentMenu("Xeric Library/DebugDrawLibrary/Screenspace/Text Drawer Screenspace")] + [DefaultExecutionOrder(31000)] //negative numers are early, positive numbers are late. Range is till 32000 to both negative and positive direction. + public class TextDrawerScreenspace : VisualizerScreenspaceParent + { + [SerializeField] Color color = DrawBasics.defaultColor; + [SerializeField] [Range(0.001f, 1.0f)] float size_relToViewportHeight = 0.025f; + [SerializeField] DrawText.TextAnchorDXXL textAnchor = DrawText.TextAnchorDXXL.LowerLeft; + [SerializeField] public bool enclosingBox_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] DrawBasics.LineStyle enclosingBoxLineStyle = DrawBasics.LineStyle.invisible; + [SerializeField] float enclosingBox_lineWidth_relToTextSize = 0.0f; + [SerializeField] float enclosingBox_paddingSize_relToTextSize = 0.0f; + [SerializeField] bool autoLineBreakAtScreenBorder = true; + [SerializeField] bool autoFlipTextToPreventUpsideDown = true; + + [SerializeField] public bool forceTextEnlargementToThisMinWidth_relToViewportWidth_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] bool forceTextEnlargementToThisMinWidth_relToViewportWidth = false; + [SerializeField] [Range(0.003f, 2.0f)] float forceTextEnlargementToThisMinWidth_relToViewportWidth_value = 0.1f; + + [SerializeField] public bool forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] bool forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth = false; + [SerializeField] [Range(0.003f, 2.0f)] float forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value = 0.5f; + + [SerializeField] public bool autoLineBreakWidth_relToViewportWidth_isOutfolded = false; //is only "public" to silence the compiler warning saying that it is "never used". The compiler doesn't know that it is used via serialization. + [SerializeField] bool autoLineBreakWidth_relToViewportWidth = false; + [SerializeField] [Range(0.003f, 2.0f)] float autoLineBreakWidth_relToViewportWidth_value = 0.5f; + + public override void InitializeValues_onceInComponentLifetime() + { + if (text_exclGlobalMarkupTags == null || text_exclGlobalMarkupTags == "") + { + text_exclGlobalMarkupTags = "text to draw"; + text_inclGlobalMarkupTags = "text to draw"; + } + textSection_isOutfolded = true; + + customVector2Configs[0].picker_isOutfolded = false; + customVector2Configs[0].source = CustomVector2Source.rotationAroundZStartingFromRight; + customVector2Configs[0].clipboardForManualInput = Vector2.right; + customVector2Configs[0].vectorInterpretation = VectorInterpretation.globalSpace; + } + + public override void InitializeValues_alsoOnPlaymodeEnter_andOnComponentCreatedAsCopy() + { + TryFetchCamOnThisGO_andDecideScreenspaceDefiningCamera(); + } + + public override void DrawVisualizedObject() + { + Camera usedCamera = Get_usedCamera("Text Drawer Screenspace Component"); + if (usedCamera != null) + { + if (text_inclGlobalMarkupTags != null && text_inclGlobalMarkupTags != "") + { + if (UtilitiesDXXL_Math.ApproximatelyZero(size_relToViewportHeight) == false) + { + float used_forceTextEnlargementToThisMinWidth_relToViewportWidth_value = Get_used_forceTextEnlargementToThisMinWidth_relToViewportWidth_value(); + float used_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value = Get_used_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value(); + float used_autoLineBreakWidth_relToViewportWidth_value = Get_used_autoLineBreakWidth_relToViewportWidth_value(); + Vector2 textDir = Get_customVector2_1_inGlobalSpaceUnits(); + UtilitiesDXXL_Text.WriteScreenSpace(usedCamera, text_inclGlobalMarkupTags, positionInsideViewport0to1, color, size_relToViewportHeight, textDir, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, used_forceTextEnlargementToThisMinWidth_relToViewportWidth_value, used_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value, autoLineBreakAtScreenBorder, used_autoLineBreakWidth_relToViewportWidth_value, autoFlipTextToPreventUpsideDown, 0.0f, false); + } + } + } + } + + public float Get_used_forceTextEnlargementToThisMinWidth_relToViewportWidth_value() + { + if (forceTextEnlargementToThisMinWidth_relToViewportWidth) + { + return forceTextEnlargementToThisMinWidth_relToViewportWidth_value; + } + else + { + return 0.0f; + } + } + + public float Get_used_forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value() + { + if (forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth) + { + return forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth_value; + } + else + { + return 0.0f; + } + } + + public float Get_used_autoLineBreakWidth_relToViewportWidth_value() + { + if (autoLineBreakWidth_relToViewportWidth) + { + return autoLineBreakWidth_relToViewportWidth_value; + } + else + { + return 0.0f; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/components/screenspace/TextDrawerScreenspace.cs.meta b/Runtime/DrawDebugLibrary/components/screenspace/TextDrawerScreenspace.cs.meta new file mode 100644 index 0000000..047c0ca --- /dev/null +++ b/Runtime/DrawDebugLibrary/components/screenspace/TextDrawerScreenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9dd419436cc09154795ba70b6a3b5398 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/demo scene scripts.meta b/Runtime/DrawDebugLibrary/demo scene scripts.meta new file mode 100644 index 0000000..88ac194 --- /dev/null +++ b/Runtime/DrawDebugLibrary/demo scene scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 618c3fd65dc656e4a98862192db6fcb0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities.meta b/Runtime/DrawDebugLibrary/internal utilities.meta new file mode 100644 index 0000000..57ca645 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2727128a7064e524c93b10d835c313ab +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_AmplitudeDependentLineDetails.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_AmplitudeDependentLineDetails.cs new file mode 100644 index 0000000..634bd0c --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_AmplitudeDependentLineDetails.cs @@ -0,0 +1,18 @@ +namespace DrawXXL +{ + using UnityEngine; + public struct InternalDXXL_AmplitudeDependentLineDetails + { + public float lineWidth; + public bool isThinLine; + public bool enlargeSmallText; + public bool textDrawingIsSkipped_dueToLineIsTooShort; + public DrawBasics.LineStyle style; + public bool uses_endPlates; + public float endPlates_size; + public Vector3 amplitudeUp_normalized; + public Vector3 textDir_normalized; + public bool lengthOfDrawnLine_isFilled; + public float lengthOfDrawnLine; + } +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_AmplitudeDependentLineDetails.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_AmplitudeDependentLineDetails.cs.meta new file mode 100644 index 0000000..fc690b6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_AmplitudeDependentLineDetails.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8060474082aaa4042be40ef3514a3dad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_BoundsCamViewportSpace.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_BoundsCamViewportSpace.cs new file mode 100644 index 0000000..739a53a --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_BoundsCamViewportSpace.cs @@ -0,0 +1,824 @@ +namespace DrawXXL +{ + + using UnityEngine; + + + public class InternalDXXL_BoundsCamViewportSpace + { + public static Vector2 viewportCenter = new Vector2(0.5f, 0.5f); + public static InternalDXXL_BoundsCamViewportSpace wholeViewportAsBounds = new InternalDXXL_BoundsCamViewportSpace(viewportCenter, Vector2.one); + + public Vector2 center; + public float xMin; + public float xMax; + public float yMin; + public float yMax; + + public InternalDXXL_BoundsCamViewportSpace() + { + } + + public InternalDXXL_BoundsCamViewportSpace(Vector2 centerPos, Vector2 size) + { + center = centerPos; + float halfXSize = 0.5f * size.x; + float halfYSize = 0.5f * size.y; + xMin = center.x - halfXSize; + xMax = center.x + halfXSize; + yMin = center.y - halfYSize; + yMax = center.y + halfYSize; + } + + public void Recreate(Vector2 centerPos, Vector2 size) + { + center = centerPos; + float halfXSize = 0.5f * size.x; + float halfYSize = 0.5f * size.y; + xMin = center.x - halfXSize; + xMax = center.x + halfXSize; + yMin = center.y - halfYSize; + yMax = center.y + halfYSize; + } + + public InternalDXXL_BoundsCamViewportSpace GetCopy() + { + InternalDXXL_BoundsCamViewportSpace copiedBounds = new InternalDXXL_BoundsCamViewportSpace(center, new Vector2(xMax - xMin, yMax - yMin)); + return copiedBounds; + } + + public void Encapsulate(Vector2 pos) + { + if (pos.x < xMin) + { + xMin = pos.x; + center.x = 0.5f * (xMax + xMin); + } + else + { + if (pos.x > xMax) + { + xMax = pos.x; + center.x = 0.5f * (xMax + xMin); + } + } + + if (pos.y < yMin) + { + yMin = pos.y; + center.y = 0.5f * (yMax + yMin); + } + else + { + if (pos.y > yMax) + { + yMax = pos.y; + center.y = 0.5f * (yMax + yMin); + } + } + } + + public void EncapsulateButPreventGrowingIntoViewport(Vector2 pos) + { + if (pos.x < xMin) + { + if (xMin >= 1.0f) + { + xMin = Mathf.Max(pos.x, Mathf.Min(xMin, 1.01f)); + } + else + { + xMin = pos.x; + } + center.x = 0.5f * (xMax + xMin); + } + else + { + if (pos.x > xMax) + { + if (xMax <= 0.0f) + { + xMax = Mathf.Min(pos.x, Mathf.Max(xMax, -0.01f)); + } + else + { + xMax = pos.x; + } + center.x = 0.5f * (xMax + xMin); + } + } + + if (pos.y < yMin) + { + if (yMin >= 1.0f) + { + yMin = Mathf.Max(pos.y, Mathf.Min(yMin, 1.01f)); + } + else + { + yMin = pos.y; + } + center.y = 0.5f * (yMax + yMin); + } + else + { + if (pos.y > yMax) + { + if (yMax <= 0.0f) + { + yMax = Mathf.Min(pos.y, Mathf.Max(yMax, -0.01f)); + } + else + { + yMax = pos.y; + } + center.y = 0.5f * (yMax + yMin); + } + } + } + + public void Encapsulate(InternalDXXL_BoundsCamViewportSpace boundsToEncapsulate) + { + if (boundsToEncapsulate != null) + { + if (boundsToEncapsulate.xMin < xMin) + { + xMin = boundsToEncapsulate.xMin; + center.x = 0.5f * (xMax + xMin); + } + else + { + if (boundsToEncapsulate.xMax > xMax) + { + xMax = boundsToEncapsulate.xMax; + center.x = 0.5f * (xMax + xMin); + } + } + + if (boundsToEncapsulate.yMin < yMin) + { + yMin = boundsToEncapsulate.yMin; + center.y = 0.5f * (yMax + yMin); + } + else + { + if (boundsToEncapsulate.yMax > yMax) + { + yMax = boundsToEncapsulate.yMax; + center.y = 0.5f * (yMax + yMin); + } + } + } + } + + public void EncapsulateButPreventGrowingIntoViewport(InternalDXXL_BoundsCamViewportSpace boundsToEncapsulate) + { + if (boundsToEncapsulate != null) + { + if (boundsToEncapsulate.xMin < xMin) + { + if (xMin >= 1.0f) + { + xMin = Mathf.Max(boundsToEncapsulate.xMin, Mathf.Min(xMin, 1.01f)); + } + else + { + xMin = boundsToEncapsulate.xMin; + } + center.x = 0.5f * (xMax + xMin); + } + else + { + if (boundsToEncapsulate.xMax > xMax) + { + if (xMax <= 0.0f) + { + xMax = Mathf.Min(boundsToEncapsulate.xMax, Mathf.Max(xMax, -0.01f)); + } + else + { + xMax = boundsToEncapsulate.xMax; + } + center.x = 0.5f * (xMax + xMin); + } + } + + if (boundsToEncapsulate.yMin < yMin) + { + if (yMin >= 1.0f) + { + yMin = Mathf.Max(boundsToEncapsulate.yMin, Mathf.Min(yMin, 1.01f)); + } + else + { + yMin = boundsToEncapsulate.yMin; + } + center.y = 0.5f * (yMax + yMin); + } + else + { + if (boundsToEncapsulate.yMax > yMax) + { + if (yMax <= 0.0f) + { + yMax = Mathf.Min(boundsToEncapsulate.yMax, Mathf.Max(yMax, -0.01f)); + } + else + { + yMax = boundsToEncapsulate.yMax; + } + center.y = 0.5f * (yMax + yMin); + } + } + } + } + + public Vector2 GetNearestCorner(Vector2 posToWhichCornerShouldBeNearest) + { + if (center.x < posToWhichCornerShouldBeNearest.x) + { + if (center.y < posToWhichCornerShouldBeNearest.y) + { + return new Vector2(xMax, yMax); + } + else + { + return new Vector2(xMax, yMin); + } + } + else + { + if (center.y < posToWhichCornerShouldBeNearest.y) + { + return new Vector2(xMin, yMax); + } + else + { + return new Vector2(xMin, yMin); + } + } + } + + public Vector2 GetPosOutsideNearestCorner(Vector2 posToWhichCornerShouldBeNearest) + { + Vector2 nearestCorner = GetNearestCorner(posToWhichCornerShouldBeNearest); + Vector2 centerToNearestCorner = nearestCorner - center; + return (center + centerToNearestCorner * 1.01f); + } + + public Vector2 GetLowerLeftCorner() + { + return new Vector2(xMin, yMin); + } + + public Vector2 GetLowerRightCorner() + { + return new Vector2(xMax, yMin); + } + + public Vector2 GetUpperLeftCorner() + { + return new Vector2(xMin, yMax); + } + + public Vector2 GetUpperRightCorner() + { + return new Vector2(xMax, yMax); + } + + public bool IsCompletelyInsideViewport() + { + if (xMin >= 0.0f) + { + if (xMax <= 1.0f) + { + if (yMin >= 0.0f) + { + if (yMax <= 1.0f) + { + return true; + } + } + } + } + return false; + } + + public bool IsCompletelyOutsideViewport() + { + if (xMax < 0.0f || xMin > 1.0f || yMax < 0.0f || yMin > 1.0f) + { + return true; + } + return false; + } + + public bool HasVertEdgePartInsideViewport() + { + if (yMax >= 0.0f && yMin <= 1.0f) + { + if (xMin >= 0.0f && xMin <= 1.0f) + { + return true; + } + + if (xMax >= 0.0f && xMax <= 1.0f) + { + return true; + } + } + return false; + } + + public bool HasHorizEdgePartInsideViewport() + { + if (xMax >= 0.0f && xMin <= 1.0f) + { + if (yMin >= 0.0f && yMin <= 1.0f) + { + return true; + } + + if (yMax >= 0.0f && yMax <= 1.0f) + { + return true; + } + } + return false; + } + + public bool HasEdgePartInsideViewport() + { + if (HasVertEdgePartInsideViewport() || HasHorizEdgePartInsideViewport()) + { + return true; + } + else + { + return false; + } + } + + public bool HasCornerInsideViewport() + { + if (HasVertEdgePartInsideViewport() && HasHorizEdgePartInsideViewport()) + { + return true; + } + else + { + return false; + } + } + + public bool CompletelyEncapsulatesViewport() + { + if (xMin <= 0.0f) + { + if (xMax >= 1.0f) + { + if (yMin <= 0.0f) + { + if (yMax >= 1.0f) + { + return true; + } + } + } + } + return false; + } + + public static void ConstructAndOrEncapsulate(ref InternalDXXL_BoundsCamViewportSpace boundsToConstructOrGrow, Vector2 pos, bool preventGrowingIntoViewport) + { + if (boundsToConstructOrGrow == null) + { + if (preventGrowingIntoViewport) + { + if (IsInsideViewportInclBorder(pos)) + { + pos = GetViewportCenterPlumbIntersectionWithViewportBorderShifted(pos, 0.01f); + } + } + boundsToConstructOrGrow = new InternalDXXL_BoundsCamViewportSpace(pos, Vector2.zero); + } + else + { + if (preventGrowingIntoViewport) + { + boundsToConstructOrGrow.EncapsulateButPreventGrowingIntoViewport(pos); + } + else + { + boundsToConstructOrGrow.Encapsulate(pos); + } + } + } + + public static void ConstructAndOrEncapsulate(ref InternalDXXL_BoundsCamViewportSpace boundsToConstructOrGrow, InternalDXXL_BoundsCamViewportSpace boundsToEncapsulate, bool preventGrowingIntoViewport) + { + if (boundsToEncapsulate == null) + { + if (boundsToConstructOrGrow == null) + { + //Debug.LogError("Both 'boundsToConstructOrGrow' and 'boundsToEncapsulate' are 'null'. 'boundsToConstructOrGrow' is not constructed and remains 'null'."); + UtilitiesDXXL_Log.PrintErrorCode("3"); + } + } + else + { + if (boundsToConstructOrGrow == null) + { + if (boundsToEncapsulate.IsCompletelyOutsideViewport()) + { + boundsToConstructOrGrow = boundsToEncapsulate.GetCopy(); + } + else + { + Vector2 centerPosShiftedToOutsideViewport = GetViewportCenterPlumbIntersectionWithViewportBorderShifted(boundsToEncapsulate.center, 0.01f); + boundsToConstructOrGrow = new InternalDXXL_BoundsCamViewportSpace(centerPosShiftedToOutsideViewport, Vector2.zero); + } + } + else + { + if (preventGrowingIntoViewport) + { + boundsToConstructOrGrow.EncapsulateButPreventGrowingIntoViewport(boundsToEncapsulate); + } + else + { + boundsToConstructOrGrow.Encapsulate(boundsToEncapsulate); + } + } + } + } + + public static Vector2 GetViewportCenterPlumbIntersectionWithViewportBorder(Vector2 posToPlumbTowardsViewportCenter) + { + return GetViewportCenterPlumbIntersectionWithViewportBorderShifted(posToPlumbTowardsViewportCenter, 0.0f); + } + + static InternalDXXL_Line2D plumbLine = new InternalDXXL_Line2D(); + public static Vector2 GetViewportCenterPlumbIntersectionWithViewportBorderShifted(Vector2 posToPlumbTowardsViewportCenter, float shiftDistanceToOutsideOfViewport) + { + float onePlusShiftDistanceToOutside = 1.0f + shiftDistanceToOutsideOfViewport; + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(posToPlumbTowardsViewportCenter, viewportCenter)) + { + return new Vector2(-shiftDistanceToOutsideOfViewport, 0.25f); + } + else + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(posToPlumbTowardsViewportCenter.y, 0.5f)) + { + if (posToPlumbTowardsViewportCenter.x <= 0.5f) + { + return new Vector2(-shiftDistanceToOutsideOfViewport, 0.5f); + } + else + { + return new Vector2(onePlusShiftDistanceToOutside, 0.5f); + } + } + else + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(posToPlumbTowardsViewportCenter.x, 0.5f)) + { + if (posToPlumbTowardsViewportCenter.y <= 0.5f) + { + return new Vector2(0.5f, -shiftDistanceToOutsideOfViewport); + } + else + { + return new Vector2(0.5f, onePlusShiftDistanceToOutside); + } + } + else + { + plumbLine.Recalc_line_throughTwoPoints_returnSteepForVertLines(posToPlumbTowardsViewportCenter, viewportCenter); + if (posToPlumbTowardsViewportCenter.x <= 0.5f) + { + Vector2 intersectionWithLeftViewportBorder = new Vector2(-shiftDistanceToOutsideOfViewport, plumbLine.GetYatX(-shiftDistanceToOutsideOfViewport)); + if (intersectionWithLeftViewportBorder.y > -shiftDistanceToOutsideOfViewport && intersectionWithLeftViewportBorder.y < onePlusShiftDistanceToOutside) + { + return intersectionWithLeftViewportBorder; + } + else + { + if (posToPlumbTowardsViewportCenter.y > 0.5f) + { + return new Vector2(plumbLine.GetXatY(onePlusShiftDistanceToOutside), onePlusShiftDistanceToOutside); + } + else + { + return new Vector2(plumbLine.GetXatY(-shiftDistanceToOutsideOfViewport), -shiftDistanceToOutsideOfViewport); + } + } + } + else + { + Vector2 intersectionWithRightViewportBorder = new Vector2(onePlusShiftDistanceToOutside, plumbLine.GetYatX(onePlusShiftDistanceToOutside)); + if (intersectionWithRightViewportBorder.y > -shiftDistanceToOutsideOfViewport && intersectionWithRightViewportBorder.y < onePlusShiftDistanceToOutside) + { + return intersectionWithRightViewportBorder; + } + else + { + if (posToPlumbTowardsViewportCenter.y > 0.5f) + { + return new Vector2(plumbLine.GetXatY(onePlusShiftDistanceToOutside), onePlusShiftDistanceToOutside); + } + else + { + return new Vector2(plumbLine.GetXatY(-shiftDistanceToOutsideOfViewport), -shiftDistanceToOutsideOfViewport); + } + } + } + } + } + } + } + + public static Vector2 ClampIntoViewport(Vector2 posToClamp) + { + return new Vector2(Mathf.Clamp01(posToClamp.x), Mathf.Clamp01(posToClamp.y)); + } + + public static bool IsInsideViewportInclBorder(Vector2 pos) + { + if (pos.x >= 0.0f) + { + if (pos.x <= 1.0f) + { + if (pos.y >= 0.0f) + { + if (pos.y <= 1.0f) + { + return true; + } + } + } + } + return false; + } + + public static bool IsInsideViewportExclBorder(Vector2 pos) + { + if (pos.x > 0.0f) + { + if (pos.x < 1.0f) + { + if (pos.y > 0.0f) + { + if (pos.y < 1.0f) + { + return true; + } + } + } + } + return false; + } + + public static bool IsOutsideViewportInclBorder(Vector2 pos) + { + return !IsInsideViewportInclBorder(pos); + } + + public static bool IsOutsideViewportExclBorder(Vector2 pos) + { + return !IsInsideViewportExclBorder(pos); + } + + public static bool IsOutsideViewportWithPadding(Vector2 posToCheckIfOutside, float paddingHowMuchViewportGetsEnlargedForTheCheck) + { + if (posToCheckIfOutside.x < (-paddingHowMuchViewportGetsEnlargedForTheCheck)) + { + return true; + } + if (posToCheckIfOutside.x > (1.0f + paddingHowMuchViewportGetsEnlargedForTheCheck)) + { + return true; + } + if (posToCheckIfOutside.y < (-paddingHowMuchViewportGetsEnlargedForTheCheck)) + { + return true; + } + if (posToCheckIfOutside.y > (1.0f + paddingHowMuchViewportGetsEnlargedForTheCheck)) + { + return true; + } + return false; + } + + public static bool IsOutsideViewportXWithPadding(Vector2 posToCheckIfOutside, float paddingHowMuchViewportGetsEnlargedForTheCheck) + { + if (posToCheckIfOutside.x < (-paddingHowMuchViewportGetsEnlargedForTheCheck)) + { + return true; + } + if (posToCheckIfOutside.x > (1.0f + paddingHowMuchViewportGetsEnlargedForTheCheck)) + { + return true; + } + return false; + } + + public static bool IsOutsideViewportYWithPadding(Vector2 posToCheckIfOutside, float paddingHowMuchViewportGetsEnlargedForTheCheck) + { + if (posToCheckIfOutside.y < (-paddingHowMuchViewportGetsEnlargedForTheCheck)) + { + return true; + } + if (posToCheckIfOutside.y > (1.0f + paddingHowMuchViewportGetsEnlargedForTheCheck)) + { + return true; + } + return false; + } + + public bool LeftBorderCrossesCompletelyInsideViewport() + { + if (xMin > 0.0f && xMin < 1.0f) + { + if (yMin < 0.0f && yMax > 1.0f) + { + return true; + } + } + return false; + + } + + public bool RightBorderCrossesCompletelyInsideViewport() + { + if (xMax > 0.0f && xMax < 1.0f) + { + if (yMin < 0.0f && yMax > 1.0f) + { + return true; + } + } + return false; + } + + public bool LowerBorderCrossesCompletelyInsideViewport() + { + if (yMin > 0.0f && yMin < 1.0f) + { + if (xMin < 0.0f && xMax > 1.0f) + { + return true; + } + } + return false; + } + + public bool UpperBorderCrossesCompletelyInsideViewport() + { + if (yMax > 0.0f && yMax < 1.0f) + { + if (xMin < 0.0f && xMax > 1.0f) + { + return true; + } + } + return false; + } + + public Vector2 GetPosOnMostCenteredViewportCrossingEdge(float posOnEdge_as0to1OfViewport) + { + Vector2 mostCenteredPos = Vector2.zero; + float smallestDistanceToCenter = 1.0f; + + // float viewportCenter_1D = 0.5f; //-> makes the textPos flicker in common cases where edges are symetrical around a viewport0.5-axis + float viewportCenter_1D = 0.505f; //-> prevent textPos-flicker of common case where edges are symetrical around a viewport0.5-axis + + if (LeftBorderCrossesCompletelyInsideViewport()) + { + float distanceToCenter = Mathf.Abs(xMin - viewportCenter_1D); + if (distanceToCenter < smallestDistanceToCenter) + { + smallestDistanceToCenter = distanceToCenter; + mostCenteredPos = new Vector2(xMin, posOnEdge_as0to1OfViewport); + } + } + + if (RightBorderCrossesCompletelyInsideViewport()) + { + float distanceToCenter = Mathf.Abs(xMax - viewportCenter_1D); + + if (distanceToCenter < smallestDistanceToCenter) + { + smallestDistanceToCenter = distanceToCenter; + mostCenteredPos = new Vector2(xMax, posOnEdge_as0to1OfViewport); + } + } + + if (LowerBorderCrossesCompletelyInsideViewport()) + { + float distanceToCenter = Mathf.Abs(yMin - viewportCenter_1D); + if (distanceToCenter < smallestDistanceToCenter) + { + smallestDistanceToCenter = distanceToCenter; + mostCenteredPos = new Vector2(posOnEdge_as0to1OfViewport, yMin); + } + } + + if (UpperBorderCrossesCompletelyInsideViewport()) + { + float distanceToCenter = Mathf.Abs(yMax - viewportCenter_1D); + if (distanceToCenter < smallestDistanceToCenter) + { + smallestDistanceToCenter = distanceToCenter; + mostCenteredPos = new Vector2(posOnEdge_as0to1OfViewport, yMax); + } + } + + return mostCenteredPos; + } + + public void DrawViewportCrossingEdges(Camera camera, Color color, float lineWidth_relToViewportHeight, float durationInSec) + { + bool hasAlreadyDrawnHorizDottedLines = false; + bool hasAlreadyDrawnVertDottedLines = false; + + if (LeftBorderCrossesCompletelyInsideViewport()) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(xMin, 0.0f), new Vector2(xMin, 1.0f), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + if (hasAlreadyDrawnHorizDottedLines == false) + { + float rightEndOfDashedLine = Mathf.Min(0.995f, xMax); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(xMin, 0.005f), new Vector2(rightEndOfDashedLine, 0.005f), color, 0.0f, null, DrawBasics.LineStyle.dashed, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(xMin, 0.995f), new Vector2(rightEndOfDashedLine, 0.995f), color, 0.0f, null, DrawBasics.LineStyle.dashed, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + hasAlreadyDrawnHorizDottedLines = true; + } + } + + if (RightBorderCrossesCompletelyInsideViewport()) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(xMax, 0.0f), new Vector2(xMax, 1.0f), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + if (hasAlreadyDrawnHorizDottedLines == false) + { + float leftEndOfDashedLine = Mathf.Max(0.005f, xMin); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(xMax, 0.005f), new Vector2(leftEndOfDashedLine, 0.005f), color, 0.0f, null, DrawBasics.LineStyle.dashed, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(xMax, 0.995f), new Vector2(leftEndOfDashedLine, 0.995f), color, 0.0f, null, DrawBasics.LineStyle.dashed, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + hasAlreadyDrawnHorizDottedLines = true; + } + } + + if (LowerBorderCrossesCompletelyInsideViewport()) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.0f, yMin), new Vector2(1.0f, yMin), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + if (hasAlreadyDrawnVertDottedLines == false) + { + float upperEndOfDashedLine = Mathf.Min(0.995f, yMax); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.005f, yMin), new Vector2(0.005f, upperEndOfDashedLine), color, 0.0f, null, DrawBasics.LineStyle.dashed, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.995f, yMin), new Vector2(0.995f, upperEndOfDashedLine), color, 0.0f, null, DrawBasics.LineStyle.dashed, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + hasAlreadyDrawnVertDottedLines = true; + } + } + + if (UpperBorderCrossesCompletelyInsideViewport()) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.0f, yMax), new Vector2(1.0f, yMax), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + if (hasAlreadyDrawnVertDottedLines == false) + { + float lowerEndOfDashedLine = Mathf.Max(0.005f, yMin); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.005f, yMax), new Vector2(0.005f, lowerEndOfDashedLine), color, 0.0f, null, DrawBasics.LineStyle.dashed, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(0.995f, yMax), new Vector2(0.995f, lowerEndOfDashedLine), color, 0.0f, null, DrawBasics.LineStyle.dashed, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + hasAlreadyDrawnVertDottedLines = true; + } + } + } + + public void Draw(Camera camera, Color color, float lineWidth_relToViewportHeight, float durationInSec) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(xMin, yMin), new Vector2(xMin, yMax), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(xMax, yMin), new Vector2(xMax, yMax), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(xMin, yMin), new Vector2(xMax, yMin), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(xMin, yMax), new Vector2(xMax, yMax), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + public static void DrawViewportBorder(Camera camera, Color color, float lineWidth_relToViewportHeight, float offsetTowardsInsideOfViewport, float durationInSec) + { + float oneMinusOffset = 1.0f - offsetTowardsInsideOfViewport; + lineWidth_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth_relToViewportHeight); + float halfLineWidth_relToViewportHeight = 0.5f * lineWidth_relToViewportHeight; + float halfLineWidth_relToViewportWidth = halfLineWidth_relToViewportHeight / camera.aspect; + + //horiz Lines: + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(offsetTowardsInsideOfViewport - halfLineWidth_relToViewportWidth, offsetTowardsInsideOfViewport), new Vector2(oneMinusOffset + halfLineWidth_relToViewportWidth, offsetTowardsInsideOfViewport), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(offsetTowardsInsideOfViewport - halfLineWidth_relToViewportWidth, oneMinusOffset), new Vector2(oneMinusOffset + halfLineWidth_relToViewportWidth, oneMinusOffset), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + //vert Lines: + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(offsetTowardsInsideOfViewport, offsetTowardsInsideOfViewport - halfLineWidth_relToViewportHeight), new Vector2(offsetTowardsInsideOfViewport, oneMinusOffset + halfLineWidth_relToViewportHeight), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, new Vector2(oneMinusOffset, offsetTowardsInsideOfViewport - halfLineWidth_relToViewportHeight), new Vector2(oneMinusOffset, oneMinusOffset + halfLineWidth_relToViewportHeight), color, lineWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + public void PrintSpecsToLog() + { + Debug.Log("InternalDXXL_BoundsCamViewportSpace specs -> center: " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(center) + " xMin: " + xMin + " xMax: " + xMax + " yMin: " + yMin + " yMax: " + yMax); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_BoundsCamViewportSpace.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_BoundsCamViewportSpace.cs.meta new file mode 100644 index 0000000..7d58963 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_BoundsCamViewportSpace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a0930d2beb0cbc44b75973129d34b6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_CharConfig.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_CharConfig.cs new file mode 100644 index 0000000..ce427b7 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_CharConfig.cs @@ -0,0 +1,55 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class InternalDXXL_CharConfig + { + public char character; + public bool hasMissingSymbolDefinition = false; + public bool bold = false; + public bool italic = false; + public bool deleted = false; + public bool underlined = false; + public float size; + public float sizeScalingFactor = 1.0f; + public Color color; + public Vector3 pos; + public bool strippedDueToParsing = false; + public int numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself = 0; //"0" means "is not a lineBreak" + public bool isIcon = false; + public string iconString; + public List duplicatesPrintOffsets = new List(); + public int usedSlots_inDuplicatesPrintOffsetList; + ///for charsOnCircle: + public float coveredAngleDeg_onTheLineAtTheReferenceRadius; + public float coveredAngleDegOnOwnLine; + public bool sizeHasBeenScaledViaRichtextMarkup = false; + public Quaternion rotationFromCircleStart; + public Vector3 charUp; + //public Vector3 charDirection; + + public delegate void SetCharStyleProperty(ref InternalDXXL_CharConfig charToModify); + + public static void MarkAsBold(ref InternalDXXL_CharConfig charToMark) + { + charToMark.bold = true; + } + + public static void MarkAsItalic(ref InternalDXXL_CharConfig charToMark) + { + charToMark.italic = true; + } + + public static void MarkAsDeleted(ref InternalDXXL_CharConfig charToMark) + { + charToMark.deleted = true; + } + + public static void MarkAsUnderlined(ref InternalDXXL_CharConfig charToMark) + { + charToMark.underlined = true; + } + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_CharConfig.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_CharConfig.cs.meta new file mode 100644 index 0000000..62dc9ed --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_CharConfig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0a9a530d1b9692459a7e14d75f96e21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Edge.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Edge.cs new file mode 100644 index 0000000..98ec6d3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Edge.cs @@ -0,0 +1,46 @@ +namespace DrawXXL +{ + using UnityEngine; + public class InternalDXXL_Edge + { + public Vector3 start; + public Vector3 end; + public InternalDXXL_Line line = new InternalDXXL_Line(); + + public InternalDXXL_Edge() + { + + } + + public InternalDXXL_Edge(Vector3 startPos, Vector3 endPos) + { + start = startPos; + end = endPos; + } + + public void Recreate(Vector3 startPos, Vector3 endPos) + { + start = startPos; + end = endPos; + } + + public void CalcLine() + { + line.RecreateLineFromTwoPoints(start, end); + } + + public bool CheckIfLengthIsZero() + { + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start, end)) + { + return true; + } + else + { + return false; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Edge.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Edge.cs.meta new file mode 100644 index 0000000..e506585 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Edge.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34d7202acb90e654aba4f9b437380d89 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line.cs new file mode 100644 index 0000000..9528fd6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line.cs @@ -0,0 +1,226 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class InternalDXXL_Line + { + public Vector3 origin; + public Vector3 direction; + + public float length; + public Vector3 direction_normalized; + public bool originHasBeenRelocated = false; + Vector3 directionProlongedIntoStableFloatRegion; //not always filled + + public InternalDXXL_Line() + { + //x-axis through world origin: + origin = Vector3.zero; + direction = new Vector3(1.0f, 0.0f, 0.0f); + length = 1.0f; + direction_normalized = direction; + } + + public void RecreateLineFromTwoPoints(Vector3 point1, Vector3 point2) + { + origin = point1; + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(point1, point2)) + { + Debug.LogError("Cannot create a line3D with a zero-vector as direction. Provided points were " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(point1) + " and " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(point2) + " Now creating standard-line3D instead, which is x-Axis."); + origin = Vector3.zero; + direction = new Vector3(1.0f, 0.0f, 0.0f); + } + else + { + direction = point2 - point1; + if (CheckIfDirVectorIsZero(direction)) + { + Debug.LogError("Cannot create a line3D with a zero-vector as direction. Provided points were " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(point1) + " and " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(point2) + " Now creating standard-line3D instead, which is x-Axis."); + origin = Vector3.zero; + direction = new Vector3(1.0f, 0.0f, 0.0f); + } + } + + CalcLengthAndNormalizedDir(false); + RelocateFarAwayOrigins(); + } + + public void Recreate(Vector3 lineOrigin, Vector3 lineDirection, bool lineDir_isAlreadyGuaranteedNormalized) + { + origin = lineOrigin; + if (UtilitiesDXXL_Math.ApproximatelyZero(lineDirection)) + { + //Debug.LogError("'lineDirection' is zero -> Fallback to x-axis-line."); + UtilitiesDXXL_Log.PrintErrorCode("22"); + + direction = new Vector3(1.0f, 0.0f, 0.0f); + length = 1.0f; + direction_normalized = direction; + } + else + { + direction = lineDirection; + CalcLengthAndNormalizedDir(lineDir_isAlreadyGuaranteedNormalized); + RelocateFarAwayOrigins(); + } + } + + void CalcLengthAndNormalizedDir(bool direction_isAlreadyGuaranteedNormalized) + { + if (direction_isAlreadyGuaranteedNormalized) + { + length = 1.0f; + directionProlongedIntoStableFloatRegion = direction; + direction_normalized = direction; + } + else + { + length = direction.magnitude; + directionProlongedIntoStableFloatRegion = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(direction, out bool directionHasBeenRescaledIntoStableFloatRegion); + + if (directionHasBeenRescaledIntoStableFloatRegion) + { + float lengthOfProlongedDirection = directionProlongedIntoStableFloatRegion.magnitude; + direction_normalized = directionProlongedIntoStableFloatRegion / lengthOfProlongedDirection; + } + else + { + direction_normalized = direction / length; + } + } + } + + public Vector3 Get_intersectionPoint_withPlane_withoutParallelCheck(InternalDXXL_Plane plane) + { + float lenghtOfDirVector = ((plane.d - plane.a * origin.x - plane.b * origin.y - plane.c * origin.z) / (plane.a * direction_normalized.x + plane.b * direction_normalized.y + plane.c * direction_normalized.z)); + if (float.IsNaN(lenghtOfDirVector) || float.IsInfinity(lenghtOfDirVector)) + { + return new Vector3(float.NaN, float.NaN, float.NaN); + } + else + { + return (origin + lenghtOfDirVector * direction_normalized); + } + } + + + static bool CheckIfDirVectorIsZero(Vector3 dirVectorToCheck) + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(dirVectorToCheck.x, 0.0f)) + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(dirVectorToCheck.y, 0.0f)) + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(dirVectorToCheck.z, 0.0f)) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } + else + { + return false; + } + } + + + InternalDXXL_Plane universalUsablePlane = new InternalDXXL_Plane(); + public Vector3 Get_perpProjectionOfPoint_ontoThisLine(Vector3 pointToProject) + { + //plane-meaning: "plane_perpToLine_throughPointToProject" + universalUsablePlane.Recreate(pointToProject, direction_normalized); + return Get_intersectionPoint_withPlane_withoutParallelCheck(universalUsablePlane); + } + + public Vector3 Get_vectorFromPoint_perpOntoThisLine(Vector3 pointToGetVectorFor) + { + Vector3 givenPoints_perpProjection_ontoThisLine = Get_perpProjectionOfPoint_ontoThisLine(pointToGetVectorFor); + return givenPoints_perpProjection_ontoThisLine - pointToGetVectorFor; + } + + public Vector3 Get_vectorFromLine_perpToGivenPoint(Vector3 pointToGetVectorFor) + { + Vector3 givenPoints_perpProjection_ontoThisLine = Get_perpProjectionOfPoint_ontoThisLine(pointToGetVectorFor); + return pointToGetVectorFor - givenPoints_perpProjection_ontoThisLine; + } + + public Vector3 Get_randomPerpVectorAwayFromLine_notNormalized() + { + return Get_vectorFromLine_perpToGivenPoint(new Vector3(0.10293f, 1.315532f, 2.10928f)); //using a "randomSeldomPoint" + } + + public float Get_perpDistance_ofGivenPoint_toThisLine(Vector3 pointToGetDistanceFor) + { + return Get_vectorFromPoint_perpOntoThisLine(pointToGetDistanceFor).magnitude; + } + + + static InternalDXXL_Plane perpPlane_throughWorldOrigin = new InternalDXXL_Plane(); + static float maxAllowedDistance_aboveWhichOriginGetsRelocated = 100000.0f; + public void RelocateFarAwayOrigins() + { + float biggestAbsComponent_ofOrigin = UtilitiesDXXL_Math.GetBiggestAbsComponent(origin); + if (biggestAbsComponent_ofOrigin > maxAllowedDistance_aboveWhichOriginGetsRelocated) + { + //'origin' gets relocated because float positions become rough and uncertain over 100000.0f, which leads to undefined behaviour. + perpPlane_throughWorldOrigin.Recreate(Vector3.zero, direction_normalized); + origin = Get_intersectionPoint_withPlane_withoutParallelCheck(perpPlane_throughWorldOrigin); + originHasBeenRelocated = true; + } + + } + + public Vector3 Get_posOnLine_thatIsNearestTo_passingOtherLine(InternalDXXL_Line passingOtherLine) + { + if (UtilitiesDXXL_Math.Check_ifTwoVectorsAreApproxParallel_butCanHeadToDifferntDirs_expensiveButAccurate(direction_normalized, passingOtherLine.direction_normalized)) + { + return new Vector3(float.NaN, float.NaN, float.NaN); + } + + //plane-meaning: "plane_throughGivenLine_spannedFromThisLinesDirAndGivenLinesDir" + universalUsablePlane.Recreate(passingOtherLine.origin, passingOtherLine.origin + direction_normalized, passingOtherLine.origin + passingOtherLine.direction_normalized); + Vector3 normalOfOtherLine_insidePlaneThatIsSpannedByTheTwoLines = universalUsablePlane.Get_projectionOfVectorOntoPlane(passingOtherLine.Get_randomPerpVectorAwayFromLine_notNormalized()); + //plane-meaning: "plane_throughOtherLine_butMostPerpTo_passingDirOfThisLine" + universalUsablePlane.Recreate(passingOtherLine.origin, normalOfOtherLine_insidePlaneThatIsSpannedByTheTwoLines); + return this.Get_intersectionPoint_withPlane_withoutParallelCheck(universalUsablePlane); + } + + public bool ErrorLogForInvalidLineParameters() + { + if (UtilitiesDXXL_Math.FloatIsInvalid(origin.x) || UtilitiesDXXL_Math.FloatIsInvalid(origin.y) || UtilitiesDXXL_Math.FloatIsInvalid(origin.z)) + { + Debug.LogError("The Vector3 'origin' contains invalid float components: ( x is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(origin.x) + ", y is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(origin.y) + ", z is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(origin.z) + ")."); + return false; + } + else + { + if (UtilitiesDXXL_Math.FloatIsInvalid(direction.x) || UtilitiesDXXL_Math.FloatIsInvalid(direction.y) || UtilitiesDXXL_Math.FloatIsInvalid(direction.z)) + { + Debug.LogError("The Vector3 'direction' contains invalid float components: ( x is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(direction.x) + ", y is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(direction.y) + ", z is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(direction.z) + ")."); + return false; + } + else + { + if (UtilitiesDXXL_Math.FloatIsInvalid(direction_normalized.x) || UtilitiesDXXL_Math.FloatIsInvalid(direction_normalized.y) || UtilitiesDXXL_Math.FloatIsInvalid(direction_normalized.z)) + { + Debug.LogError("The Vector3 'direction_normalized' contains invalid float components: ( x is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(direction_normalized.x) + ", y is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(direction_normalized.y) + ", z is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(direction_normalized.z) + ")."); + return false; + } + else + { + return true; + } + } + } + } + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line.cs.meta new file mode 100644 index 0000000..a01294b --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 13e14a9e1c092e74da1af7c5995c60ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line2D.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line2D.cs new file mode 100644 index 0000000..f58d647 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line2D.cs @@ -0,0 +1,106 @@ +namespace DrawXXL +{ + using UnityEngine; + + + public class InternalDXXL_Line2D + { + public float m; + public float t; + + public InternalDXXL_Line2D() + { + m = 1.0f; + t = 0.0f; + } + + public void Recalc_line_throughTwoPoints_notVertLineProof(Vector2 firstPoint, Vector2 secondPoint) + { + m = (secondPoint.y - firstPoint.y) / (secondPoint.x - firstPoint.x); + t = firstPoint.y - m * firstPoint.x; + } + + public void Recalc_line_throughTwoPoints_returnSteepForVertLines(Vector2 firstPoint, Vector2 secondPoint) + { + float delta_x = secondPoint.x - firstPoint.x; + if (UtilitiesDXXL_Math.ApproximatelyZero(delta_x)) + { + m = 1000000.0f; + } + else + { + m = (secondPoint.y - firstPoint.y) / delta_x; + } + + t = firstPoint.y - m * firstPoint.x; + } + + + + + public float GetYatX(float givenX) + { + return (m * givenX + t); + } + + public float GetXatY(float givenY) + { + return (givenY - t) / m; + } + + InternalDXXL_Line2D perpLineThroughGivenPoint; + public Vector2 GetProjectionOfPointOntoLine(Vector2 pointToProject) + { + if (perpLineThroughGivenPoint == null) + { + perpLineThroughGivenPoint = Create_perpendicularLine_throughPoint_proofForGivenLineWithMOfZero(this, pointToProject); + } + else + { + perpLineThroughGivenPoint.Recalc_perpendicularLine_throughPoint_proofForGivenLineWithMOfZero(this, pointToProject); + } + return Get_intersectionPoint_ofTwoLines_notProofForParallel(this, perpLineThroughGivenPoint); + } + + public static InternalDXXL_Line2D Create_perpendicularLine_throughPoint_proofForGivenLineWithMOfZero(InternalDXXL_Line2D line_perpendicularToResultingLine, Vector2 throughtThisPoint) + { + InternalDXXL_Line2D line = new InternalDXXL_Line2D(); + line.m = Get_perpendicular_m_returnsSteepForZeros(line_perpendicularToResultingLine.m); + line.t = Get_t_ofLineThruPoint(throughtThisPoint, line.m); + return line; + } + + public void Recalc_perpendicularLine_throughPoint_proofForGivenLineWithMOfZero(InternalDXXL_Line2D line_perpendicularToResultingLine, Vector2 throughtThisPoint) + { + m = Get_perpendicular_m_returnsSteepForZeros(line_perpendicularToResultingLine.m); + t = Get_t_ofLineThruPoint(throughtThisPoint, m); + } + + public static float Get_perpendicular_m_returnsSteepForZeros(float given_m) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(given_m)) + { + return (100000.0f); + } + else + { + return (-1.0f / given_m); + } + } + + public static float Get_t_ofLineThruPoint(Vector2 givenPoint, float given_m) + { + return (givenPoint.y - given_m * givenPoint.x); + } + + public static Vector2 Get_intersectionPoint_ofTwoLines_notProofForParallel(InternalDXXL_Line2D firstLine, InternalDXXL_Line2D secondLine) + { + Vector2 intersectionPoint = new Vector2(); + intersectionPoint.x = (secondLine.t - firstLine.t) / (firstLine.m - secondLine.m); + intersectionPoint.y = firstLine.m * intersectionPoint.x + firstLine.t; + return intersectionPoint; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line2D.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line2D.cs.meta new file mode 100644 index 0000000..10e2d1c --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Line2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 555146743d444a7499b3c97a23f3e611 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LineParamsFromCamViewportSpace.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LineParamsFromCamViewportSpace.cs new file mode 100644 index 0000000..bb778cf --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LineParamsFromCamViewportSpace.cs @@ -0,0 +1,16 @@ +namespace DrawXXL +{ + using UnityEngine; + public class InternalDXXL_LineParamsFromCamViewportSpace + { + public Vector3 startAnchor_worldSpace; + public Vector3 endAnchor_worldSpace; + public float width_worldSpace; + public float animationSpeed_worldSpace; + public DrawBasics.LineStyle lineStyleForcedTo2D; + public float patternScaleFactor_worldSpace; + public float endPlatesSize_inAbsoluteWorldSpaceUnits; + public InternalDXXL_Plane camPlane = new InternalDXXL_Plane(); + public float enlargeSmallTextToThisMinTextSize_worldSpace; + } +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LineParamsFromCamViewportSpace.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LineParamsFromCamViewportSpace.cs.meta new file mode 100644 index 0000000..08377b1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LineParamsFromCamViewportSpace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e4b0382e41737d42ba9f39b0fec0822 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LogMessageForDrawing.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LogMessageForDrawing.cs new file mode 100644 index 0000000..11fd833 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LogMessageForDrawing.cs @@ -0,0 +1,19 @@ +namespace DrawXXL +{ + + using UnityEngine; + + + public class InternalDXXL_LogMessageForDrawing + { + //from Debug.Log()-Call: + public string logString; + public string stackTrace; + public LogType logType; + public int gameObjectsInstanceID; + //from LogsAtGameObject()-Parsing: + public string stringWithLogSymbolStackTraceAndLineBreak; + public string wholeTextWallForLogDisplayOfLastXLogs; + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LogMessageForDrawing.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LogMessageForDrawing.cs.meta new file mode 100644 index 0000000..705c1f8 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_LogMessageForDrawing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58d2168e098465f478f85035e0a0fa89 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_MarkupPhase.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_MarkupPhase.cs new file mode 100644 index 0000000..0aaa0e3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_MarkupPhase.cs @@ -0,0 +1,10 @@ +namespace DrawXXL +{ + public class InternalDXXL_MarkupPhase + { + public string unparsedValue; + public int i_firstChar; + public int i_lastChar; + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_MarkupPhase.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_MarkupPhase.cs.meta new file mode 100644 index 0000000..01634a3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_MarkupPhase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e7beae4ecd5da843b0f48d70ffe8a8b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Plane.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Plane.cs new file mode 100644 index 0000000..4f47aa1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Plane.cs @@ -0,0 +1,287 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class InternalDXXL_Plane + { + ///plane equation: a*x + b*y + c*z = d + + ///meaning of the parameters: + /// x-axisInterception = d / a + /// y-axisInterception = d / b + /// z-axisInterception = d / c + /// a, b und c define the planes normal vector as (a,b,c) + /// a = inverse of x-axisInterception * d + /// b = inverse of y-axisInterception * d + /// c = inverse of z-axisInterception * d + /// d = perpendicular distance to origin? + + public float a; + public float b; + public float c; + public float d; + + public Vector3 normalDir; //not necessarily normalized + + //not defined for every plane: + Vector3 triangleMountingPoint; + Vector3 triangleMountingPoint_toFirstTriangleCorner; + Vector3 triangleMountingPoint_toSecondTriangleCorner; + + //saving GC.Alloc: + public static InternalDXXL_Plane horizPlane_throughZeroOrigin = new InternalDXXL_Plane(Vector3.zero, Vector3.up); + public static InternalDXXL_Plane xyPlane_throughZeroOrigin = new InternalDXXL_Plane(Vector3.zero, Vector3.forward); + public static InternalDXXL_Plane zyPlane_throughZeroOrigin = new InternalDXXL_Plane(Vector3.zero, Vector3.right); + + public void Recreate(Vector3 point1, Vector3 point2, Vector3 point3) + { + triangleMountingPoint = point1; + triangleMountingPoint_toFirstTriangleCorner = point2 - point1; + triangleMountingPoint_toSecondTriangleCorner = point3 - point1; + normalDir = Vector3.Cross(triangleMountingPoint_toFirstTriangleCorner, triangleMountingPoint_toSecondTriangleCorner); + normalDir = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(normalDir); + + a = normalDir.x; + b = normalDir.y; + c = normalDir.z; + d = triangleMountingPoint.x * a + triangleMountingPoint.y * b + triangleMountingPoint.z * c; + + ErrorLogForInvalidPlanes(); + } + + public void Recreate(Vector3 point1, Vector3 point2, Vector3 point3, bool skipErrorOfNonValidPlane) + { + triangleMountingPoint = point1; + triangleMountingPoint_toFirstTriangleCorner = point2 - point1; + triangleMountingPoint_toSecondTriangleCorner = point3 - point1; + normalDir = Vector3.Cross(triangleMountingPoint_toFirstTriangleCorner, triangleMountingPoint_toSecondTriangleCorner); + normalDir = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(normalDir); + + a = normalDir.x; + b = normalDir.y; + c = normalDir.z; + d = triangleMountingPoint.x * a + triangleMountingPoint.y * b + triangleMountingPoint.z * c; + + if (skipErrorOfNonValidPlane == false) { ErrorLogForInvalidPlanes(); } + } + + void ErrorLogForInvalidPlanes() + { + if (CheckIfPlaneIsValid() == false) + { + Debug.LogError("All plane parameters are zero. Seems like you wanted to create a plane with three points that lie on a line and therefore don't describe a plane."); + } + } + + public bool CheckIfPlaneIsValid() + { + if (UtilitiesDXXL_Math.ApproximatelyZero(a)) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(b)) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(c)) + { + return false; + } + } + } + return true; + } + + public bool CheckIfPlaneIsValid(float floatCalculationErrorTolerancePadding) + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(0.0f, a, floatCalculationErrorTolerancePadding)) + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(0.0f, b, floatCalculationErrorTolerancePadding)) + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(0.0f, c, floatCalculationErrorTolerancePadding)) + { + return false; + } + } + } + return true; + } + + public InternalDXXL_Plane(Vector3 aPointOnThePlane, Vector3 normalOfThePlane_notNecessarilyNormalized) + { + normalDir = normalOfThePlane_notNecessarilyNormalized; + normalDir = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(normalDir); + + if (UtilitiesDXXL_Math.ApproximatelyZero(normalDir)) + { + Debug.LogError("Cannot create a plane with normal that has 0 lenght: " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(normalDir)); + } + + a = normalDir.x; + b = normalDir.y; + c = normalDir.z; + d = a * aPointOnThePlane.x + b * aPointOnThePlane.y + c * aPointOnThePlane.z; + } + + public void Recreate(Vector3 aPointOnThePlane, Vector3 normalOfThePlane_notNecessarilyNormalized) + { + normalDir = normalOfThePlane_notNecessarilyNormalized; + normalDir = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(normalDir); + + if (UtilitiesDXXL_Math.ApproximatelyZero(normalDir)) + { + Debug.LogError("Cannot create a plane with normal that has 0 lenght: " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(normalDir)); + } + + a = normalDir.x; + b = normalDir.y; + c = normalDir.z; + d = a * aPointOnThePlane.x + b * aPointOnThePlane.y + c * aPointOnThePlane.z; + } + + public InternalDXXL_Plane() + { + //default: xy-plane through origin + normalDir = new Vector3(0.0f, 0.0f, 1.0f); + a = normalDir.x; + b = normalDir.y; + c = normalDir.z; + d = 0.0f; + } + + public void TryRecreateAsCopyOfOther(InternalDXXL_Plane planeToCopyFieldsFrom) + { + if (planeToCopyFieldsFrom != null) + { + normalDir = planeToCopyFieldsFrom.normalDir; + a = planeToCopyFieldsFrom.a; + b = planeToCopyFieldsFrom.b; + c = planeToCopyFieldsFrom.c; + d = planeToCopyFieldsFrom.d; + } + } + + public bool CheckIfLineIsParallel(InternalDXXL_Line line3D) + { + return UtilitiesDXXL_Math.Check_ifVectors_arePerp(normalDir, line3D.direction_normalized); + } + + public static void Calc_intersectionLine_ofTwoPlanes(ref InternalDXXL_Line alreadyConstructedLineToFill, InternalDXXL_Plane plane1, InternalDXXL_Plane plane2) + { + Vector3 directionOfLine3D = Vector3.Cross(plane1.normalDir, plane2.normalDir); + directionOfLine3D = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(directionOfLine3D); + Vector3 aValidPointOnTheLine3D = default; + + bool lineIsParallelTo_yzPlane = UtilitiesDXXL_Math.ApproximatelyZero(directionOfLine3D.x); + if (lineIsParallelTo_yzPlane == false) + { + aValidPointOnTheLine3D.x = 0.0f; + aValidPointOnTheLine3D.z = (((plane2.d * plane1.b) - (plane1.d * plane2.b)) / ((plane2.c * plane1.b) - (plane1.c * plane2.b))); + + if (plane1.b != 0.0f) + { + aValidPointOnTheLine3D.y = ((plane1.d - plane1.c * aValidPointOnTheLine3D.z) / plane1.b); + } + else + { + aValidPointOnTheLine3D.y = ((plane2.d - plane2.c * aValidPointOnTheLine3D.z) / plane2.b); + } + } + else + { + bool lineIsParallelTo_xzPlane = UtilitiesDXXL_Math.ApproximatelyZero(directionOfLine3D.y); + if (lineIsParallelTo_xzPlane == false) + { + aValidPointOnTheLine3D.y = 0.0f; + aValidPointOnTheLine3D.x = (((plane2.c * plane1.d) - (plane1.c * plane2.d)) / ((plane2.c * plane1.a) - (plane1.c * plane2.a))); + + if (plane1.c != 0.0f) + { + aValidPointOnTheLine3D.z = ((plane1.d - plane1.a * aValidPointOnTheLine3D.x) / plane1.c); + } + else + { + aValidPointOnTheLine3D.z = ((plane2.d - plane2.a * aValidPointOnTheLine3D.x) / plane2.c); + } + } + else + { + bool lineIsParallelTo_xyPlane = UtilitiesDXXL_Math.ApproximatelyZero(directionOfLine3D.z); + if (lineIsParallelTo_xyPlane == false) + { + aValidPointOnTheLine3D.z = 0.0f; + aValidPointOnTheLine3D.y = (((plane2.a * plane1.d) - (plane1.a * plane2.d)) / ((plane2.a * plane1.b) - (plane1.a * plane2.b))); + + if (plane1.a != 0.0f) + { + aValidPointOnTheLine3D.x = ((plane1.d - plane1.b * aValidPointOnTheLine3D.y) / plane1.a); + } + else + { + aValidPointOnTheLine3D.x = ((plane2.d - plane2.b * aValidPointOnTheLine3D.y) / plane2.a); + } + } + else + { + //-> "directionOfLine3D" is zero + //-> the two planes are parallel + //-> "aValidPointOnTheLine3D" is undefined (=left at default of 0/0/0) + //-> "alreadyConstructedLineToFill.Recreate" will notify this via ErrorCode-Log + } + } + } + alreadyConstructedLineToFill.Recreate(aValidPointOnTheLine3D, directionOfLine3D, false); + } + + public Vector3 GetIntersectionWithLine(InternalDXXL_Line intersectingLine) + { + return intersectingLine.Get_intersectionPoint_withPlane_withoutParallelCheck(this); + } + + + static InternalDXXL_Line perpLine = new InternalDXXL_Line(); + public Vector3 Get_perpProjectionOfPointOnPlane(Vector3 pointToProjectOntoPlane) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(normalDir)) + { + Debug.LogError("not allowed: normal is zero: " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(normalDir)); + normalDir = Vector3.forward; + } + + perpLine.Recreate(pointToProjectOntoPlane, normalDir, false); + return perpLine.Get_intersectionPoint_withPlane_withoutParallelCheck(this); + } + + public Vector3 Get_perpVector_fromPlaneToPoint(Vector3 point_toWhichResultingVectorWillPoint) + { + Vector3 perpProjection_ofPointOnPlane = Get_perpProjectionOfPointOnPlane(point_toWhichResultingVectorWillPoint); + return (point_toWhichResultingVectorWillPoint - perpProjection_ofPointOnPlane); + } + + static InternalDXXL_Line customProjectionDirLine = new InternalDXXL_Line(); + public Vector3 Get_projectionOfPointOnPlane_alongCustomDir(Vector3 pointToProjectOntoPlane, Vector3 dir_alongWhichToProject) + { + customProjectionDirLine.Recreate(pointToProjectOntoPlane, dir_alongWhichToProject, false); + return customProjectionDirLine.Get_intersectionPoint_withPlane_withoutParallelCheck(this); + } + + public bool CheckIf_twoPoints_lieOnDifferentSidesOfThePlane_returnsFalseIfAGivenPointIsONplane(Vector3 point1, Vector3 point2) + { + return UtilitiesDXXL_Math.Check_ifVectorsPointAwayFromEachOther_perpCountsAsPointingInSameDir(Get_perpVector_fromPlaneToPoint(point1), Get_perpVector_fromPlaneToPoint(point2)); + } + + public Vector3 Get_projectionOfVectorOntoPlane(Vector3 vector_toProject) + { + return (Get_perpProjectionOfPointOnPlane(vector_toProject) - Get_perpProjectionOfPointOnPlane(Vector3.zero)); + } + + public Vector3 Get_projectionOfVectorOntoPlane_alongCustomDir(Vector3 vector_toProject, Vector3 dir_alongWhichToProject) + { + //-> doesn't contain parallel-check. Caller has to ensure that "dir_alongWhichToProject" is not parallel to plane + return (Get_projectionOfPointOnPlane_alongCustomDir(vector_toProject, dir_alongWhichToProject) - Get_projectionOfPointOnPlane_alongCustomDir(Vector3.zero, dir_alongWhichToProject)); + } + + public static bool IsHorizontal(InternalDXXL_Plane planeToCheckIfItIsHorizontal) + { + return (UtilitiesDXXL_Math.ApproximatelyZero(planeToCheckIfItIsHorizontal.normalDir.x) && UtilitiesDXXL_Math.ApproximatelyZero(planeToCheckIfItIsHorizontal.normalDir.z)); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Plane.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Plane.cs.meta new file mode 100644 index 0000000..ff6bacb --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_Plane.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e76a4edd855b5e43a46569a3d9c635c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_PolyFillLine.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_PolyFillLine.cs new file mode 100644 index 0000000..358fb3b --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_PolyFillLine.cs @@ -0,0 +1,94 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class InternalDXXL_PolyFillLine + { + public InternalDXXL_Plane plane_perpToPolygon; + public List fillLineAnchors = new List(); + public int usedSlotsInFillLineAnchorsList = 0; + + public InternalDXXL_PolyFillLine(Vector3 posOfPerpPlane, Vector3 normalOfPerpPlane) + { + plane_perpToPolygon = new InternalDXXL_Plane(posOfPerpPlane, normalOfPerpPlane); + } + + public void IntersectWithEdge(InternalDXXL_Edge intersectingEdge) + { + if (intersectingEdge.CheckIfLengthIsZero() == false) + { + if (plane_perpToPolygon.CheckIfLineIsParallel(intersectingEdge.line) == false) + { + Vector3 intersection_ofCurrCheckedEdge = plane_perpToPolygon.GetIntersectionWithLine(intersectingEdge.line); + Vector3 intersection_to_edgeStart = intersectingEdge.start - intersection_ofCurrCheckedEdge; + Vector3 intersection_to_edgeEnd = intersectingEdge.end - intersection_ofCurrCheckedEdge; + + if (UtilitiesDXXL_Math.ApproximatelyZero(intersection_to_edgeStart)) + { + AddToFillLineAnchorsList(intersection_ofCurrCheckedEdge); + } + else + { + if (UtilitiesDXXL_Math.ApproximatelyZero(intersection_to_edgeEnd)) + { + AddToFillLineAnchorsList(intersection_ofCurrCheckedEdge); + } + else + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointAwayFromEachOther_perpCountsAsPointingAwayFromEachOther(intersection_to_edgeStart, intersection_to_edgeEnd)) + { + AddToFillLineAnchorsList(intersection_ofCurrCheckedEdge); + } + } + } + } + } + } + + + public void RemoveDuplicateIntersections() + { + for (int i_ref = 0; i_ref < usedSlotsInFillLineAnchorsList; i_ref++) + { + for (int i_potDuplicate = usedSlotsInFillLineAnchorsList - 1; i_potDuplicate > i_ref; i_potDuplicate--) + { + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(fillLineAnchors[i_ref], fillLineAnchors[i_potDuplicate])) + { + RemoveAt_fromAStaticVectorList(i_potDuplicate); + } + } + } + } + + + + void AddToFillLineAnchorsList(Vector3 posToAdd) + { + //function returns "i_nextFreeSlot" + //function is not ensuring yet if addSlot is the next higher nonExisting-slot + if (usedSlotsInFillLineAnchorsList < fillLineAnchors.Count) + { + fillLineAnchors[usedSlotsInFillLineAnchorsList] = posToAdd; + } + else + { + fillLineAnchors.Add(posToAdd); + } + usedSlotsInFillLineAnchorsList++; + } + + + void RemoveAt_fromAStaticVectorList(int i_toRemove) + { + //function returns "i_nextFreeSlot" + //function is not checking yet if removeSlot already exists + fillLineAnchors.RemoveAt(i_toRemove); + usedSlotsInFillLineAnchorsList--; + } + + + } + + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_PolyFillLine.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_PolyFillLine.cs.meta new file mode 100644 index 0000000..92604da --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_PolyFillLine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b277ca234cdb6cd4a8a6e236e8561f8e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_SubMeshIdentifier.cs b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_SubMeshIdentifier.cs new file mode 100644 index 0000000..a36abfd --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_SubMeshIdentifier.cs @@ -0,0 +1,12 @@ +namespace DrawXXL +{ + public struct InternalDXXL_SubMeshIdentifier + { + public int lengthOfSubMesh_inVertices; + public int i_startOfSubMesh_insideTheFinalVertsList; + + public enum DepthTestType { meshIsHidableBehindOtherGeometry, meshAlwaysOverlaysOtherGeometry }; + public DepthTestType depthTestType; + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_SubMeshIdentifier.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_SubMeshIdentifier.cs.meta new file mode 100644 index 0000000..1454366 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/InternalDXXL_SubMeshIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73a840b7bb2987046b9fda80d51ee4d4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/ScreenRelativeValue.cs b/Runtime/DrawDebugLibrary/internal utilities/ScreenRelativeValue.cs new file mode 100644 index 0000000..ad8fde2 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/ScreenRelativeValue.cs @@ -0,0 +1,30 @@ +namespace DrawXXL +{ + using UnityEngine; + + /// + /// 替代 ShapeDrawer 中成对的 xxx / xxx_relToScreen 字段。 + /// 当 activeMode 为 absolute 时使用 absolute 值,为 relativeToScreen 时使用 relativeToScreen * screenHeightReference。 + /// + [System.Serializable] + public struct ScreenRelativeValue + { + public float absolute; + [Range(0.0f, 0.5f)] public float relativeToScreen; + public ScaleMode activeMode; + + public enum ScaleMode { absolute, relativeToScreen } + + public ScreenRelativeValue(float abs, float rel, ScaleMode mode) + { + absolute = abs; + relativeToScreen = rel; + activeMode = mode; + } + + public float GetValue(float screenHeightRef) + { + return activeMode == ScaleMode.relativeToScreen ? relativeToScreen * screenHeightRef : absolute; + } + } +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/ScreenRelativeValue.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/ScreenRelativeValue.cs.meta new file mode 100644 index 0000000..a624d0f --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/ScreenRelativeValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2fd4eb86e6a7f748970e96afab5c773 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/ScreenspaceShedulingStrucs.cs b/Runtime/DrawDebugLibrary/internal utilities/ScreenspaceShedulingStrucs.cs new file mode 100644 index 0000000..0aa521f --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/ScreenspaceShedulingStrucs.cs @@ -0,0 +1,4193 @@ +namespace DrawXXL +{ + using DrawXXL; + using UnityEngine; + using System.Collections.Generic; + + //-> The purpose of these struct is to delay the drawing for screenspace shapes+lines + //-> When calling a DrawXXL.DrawSomethingToScreenspace-function it is unknown when inside the Update() cycle the user called it. + //-> The camera position and stance may get changed after the drawXXLline-call, but the transformation has already been done with the old camera postion and stance + //-> To prevent that all ScreenspaceDrawings get sheduled and finally executed as late as possible in the Update-cylce, so that any camera position changes have already been done. + + public struct TextScreenspace_3Dpos_dirViaVec_cam + { + public Camera screenCamera; + public string text; + public Vector3 position_in3DWorldspace; + public Color color; + public float size_relToViewportHeight; + public Vector2 textDirection; + public DrawText.TextAnchorDXXL textAnchor; + public float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + public float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + public bool autoLineBreakAtViewportBorder; + public float autoLineBreakWidth_relToViewportWidth; + public bool autoFlipTextToPreventUpsideDown; + public float durationInSec; + + public TextScreenspace_3Dpos_dirViaVec_cam(Camera screenCamera, string text, Vector3 position_in3DWorldspace, Color color, float size_relToViewportHeight, Vector2 textDirection, DrawText.TextAnchorDXXL textAnchor, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, bool autoLineBreakAtViewportBorder, float autoLineBreakWidth_relToViewportWidth, bool autoFlipTextToPreventUpsideDown, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.textDirection = textDirection; + this.textAnchor = textAnchor; + this.forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + this.forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + this.autoLineBreakAtViewportBorder = autoLineBreakAtViewportBorder; + this.autoLineBreakWidth_relToViewportWidth = autoLineBreakWidth_relToViewportWidth; + this.autoFlipTextToPreventUpsideDown = autoFlipTextToPreventUpsideDown; + this.durationInSec = durationInSec; + } + } + + public struct TextScreenspace_2Dpos_dirViaVec_cam + { + public Camera screenCamera; + public string text; + public Vector2 position_in2DViewportSpace; + public Color color; + public float size_relToViewportHeight; + public Vector2 textDirection; + public DrawText.TextAnchorDXXL textAnchor; + public float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + public float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + public bool autoLineBreakAtViewportBorder; + public float autoLineBreakWidth_relToViewportWidth; + public bool autoFlipTextToPreventUpsideDown; + public float durationInSec; + + public TextScreenspace_2Dpos_dirViaVec_cam(Camera screenCamera, string text, Vector2 position_in2DViewportSpace, Color color, float size_relToViewportHeight, Vector2 textDirection, DrawText.TextAnchorDXXL textAnchor, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, bool autoLineBreakAtViewportBorder, float autoLineBreakWidth_relToViewportWidth, bool autoFlipTextToPreventUpsideDown, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.textDirection = textDirection; + this.textAnchor = textAnchor; + this.forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + this.forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + this.autoLineBreakAtViewportBorder = autoLineBreakAtViewportBorder; + this.autoLineBreakWidth_relToViewportWidth = autoLineBreakWidth_relToViewportWidth; + this.autoFlipTextToPreventUpsideDown = autoFlipTextToPreventUpsideDown; + this.durationInSec = durationInSec; + } + } + + public struct TextScreenspaceFramed_3Dpos_dirViaVec_cam + { + public Camera screenCamera; + public string text; + public Vector3 position_in3DWorldspace; + public Color color; + public float size_relToViewportHeight; + public Vector2 textDirection; + public DrawText.TextAnchorDXXL textAnchor; + public DrawBasics.LineStyle enclosingBoxLineStyle; + public float enclosingBox_lineWidth_relToTextSize; + public float enclosingBox_paddingSize_relToTextSize; + public float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + public float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + public bool autoLineBreakAtViewportBorder; + public float autoLineBreakWidth_relToViewportWidth; + public bool autoFlipTextToPreventUpsideDown; + public float durationInSec; + public TextScreenspaceFramed_3Dpos_dirViaVec_cam(Camera screenCamera, string text, Vector3 position_in3DWorldspace, Color color, float size_relToViewportHeight, Vector2 textDirection, DrawText.TextAnchorDXXL textAnchor, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, bool autoLineBreakAtViewportBorder, float autoLineBreakWidth_relToViewportWidth, bool autoFlipTextToPreventUpsideDown, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.textDirection = textDirection; + this.textAnchor = textAnchor; + this.enclosingBoxLineStyle = enclosingBoxLineStyle; + this.enclosingBox_lineWidth_relToTextSize = enclosingBox_lineWidth_relToTextSize; + this.enclosingBox_paddingSize_relToTextSize = enclosingBox_paddingSize_relToTextSize; + this.forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + this.forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + this.autoLineBreakAtViewportBorder = autoLineBreakAtViewportBorder; + this.autoLineBreakWidth_relToViewportWidth = autoLineBreakWidth_relToViewportWidth; + this.autoFlipTextToPreventUpsideDown = autoFlipTextToPreventUpsideDown; + this.durationInSec = durationInSec; + } + } + + public struct TextScreenspaceFramed_2Dpos_dirViaVec_cam + { + public Camera screenCamera; + public string text; + public Vector2 position_in2DViewportSpace; + public Color color; + public float size_relToViewportHeight; + public Vector2 textDirection; + public DrawText.TextAnchorDXXL textAnchor; + public DrawBasics.LineStyle enclosingBoxLineStyle; + public float enclosingBox_lineWidth_relToTextSize; + public float enclosingBox_paddingSize_relToTextSize; + public float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + public float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + public bool autoLineBreakAtViewportBorder; + public float autoLineBreakWidth_relToViewportWidth; + public bool autoFlipTextToPreventUpsideDown; + public float durationInSec; + public TextScreenspaceFramed_2Dpos_dirViaVec_cam(Camera screenCamera, string text, Vector2 position_in2DViewportSpace, Color color, float size_relToViewportHeight, Vector2 textDirection, DrawText.TextAnchorDXXL textAnchor, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, bool autoLineBreakAtViewportBorder, float autoLineBreakWidth_relToViewportWidth, bool autoFlipTextToPreventUpsideDown, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.textDirection = textDirection; + this.textAnchor = textAnchor; + this.enclosingBoxLineStyle = enclosingBoxLineStyle; + this.enclosingBox_lineWidth_relToTextSize = enclosingBox_lineWidth_relToTextSize; + this.enclosingBox_paddingSize_relToTextSize = enclosingBox_paddingSize_relToTextSize; + this.forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + this.forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + this.autoLineBreakAtViewportBorder = autoLineBreakAtViewportBorder; + this.autoLineBreakWidth_relToViewportWidth = autoLineBreakWidth_relToViewportWidth; + this.autoFlipTextToPreventUpsideDown = autoFlipTextToPreventUpsideDown; + this.durationInSec = durationInSec; + } + } + + public struct TextScreenspace_3Dpos_dirViaAngle_cam + { + public Camera screenCamera; + public string text; + public Vector3 position_in3DWorldspace; + public Color color; + public float size_relToViewportHeight; + public float zRotationDegCC; + public DrawText.TextAnchorDXXL textAnchor; + public float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + public float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + public bool autoLineBreakAtViewportBorder; + public float autoLineBreakWidth_relToViewportWidth; + public bool autoFlipTextToPreventUpsideDown; + public float durationInSec; + public TextScreenspace_3Dpos_dirViaAngle_cam(Camera screenCamera, string text, Vector3 position_in3DWorldspace, Color color, float size_relToViewportHeight, float zRotationDegCC, DrawText.TextAnchorDXXL textAnchor, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, bool autoLineBreakAtViewportBorder, float autoLineBreakWidth_relToViewportWidth, bool autoFlipTextToPreventUpsideDown, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.zRotationDegCC = zRotationDegCC; + this.textAnchor = textAnchor; + this.forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + this.forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + this.autoLineBreakAtViewportBorder = autoLineBreakAtViewportBorder; + this.autoLineBreakWidth_relToViewportWidth = autoLineBreakWidth_relToViewportWidth; + this.autoFlipTextToPreventUpsideDown = autoFlipTextToPreventUpsideDown; + this.durationInSec = durationInSec; + } + } + + public struct TextScreenspace_2Dpos_dirViaAngle_cam + { + public Camera screenCamera; + public string text; + public Vector2 position_in2DViewportSpace; + public Color color; + public float size_relToViewportHeight; + public float zRotationDegCC; + public DrawText.TextAnchorDXXL textAnchor; + public float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + public float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + public bool autoLineBreakAtViewportBorder; + public float autoLineBreakWidth_relToViewportWidth; + public bool autoFlipTextToPreventUpsideDown; + public float durationInSec; + + public TextScreenspace_2Dpos_dirViaAngle_cam(Camera screenCamera, string text, Vector2 position_in2DViewportSpace, Color color, float size_relToViewportHeight, float zRotationDegCC, DrawText.TextAnchorDXXL textAnchor, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, bool autoLineBreakAtViewportBorder, float autoLineBreakWidth_relToViewportWidth, bool autoFlipTextToPreventUpsideDown, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.zRotationDegCC = zRotationDegCC; + this.textAnchor = textAnchor; + this.forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + this.forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + this.autoLineBreakAtViewportBorder = autoLineBreakAtViewportBorder; + this.autoLineBreakWidth_relToViewportWidth = autoLineBreakWidth_relToViewportWidth; + this.autoFlipTextToPreventUpsideDown = autoFlipTextToPreventUpsideDown; + this.durationInSec = durationInSec; + } + } + + public struct TextScreenspaceFramed_3Dpos_dirViaAngle_cam + { + public Camera screenCamera; + public string text; + public Vector3 position_in3DWorldspace; + public Color color; + public float size_relToViewportHeight; + public float zRotationDegCC; + public DrawText.TextAnchorDXXL textAnchor; + public DrawBasics.LineStyle enclosingBoxLineStyle; + public float enclosingBox_lineWidth_relToTextSize; + public float enclosingBox_paddingSize_relToTextSize; + public float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + public float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + public bool autoLineBreakAtViewportBorder; + public float autoLineBreakWidth_relToViewportWidth; + public bool autoFlipTextToPreventUpsideDown; + public float durationInSec; + + public TextScreenspaceFramed_3Dpos_dirViaAngle_cam(Camera screenCamera, string text, Vector3 position_in3DWorldspace, Color color, float size_relToViewportHeight, float zRotationDegCC, DrawText.TextAnchorDXXL textAnchor, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, bool autoLineBreakAtViewportBorder, float autoLineBreakWidth_relToViewportWidth, bool autoFlipTextToPreventUpsideDown, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.zRotationDegCC = zRotationDegCC; + this.textAnchor = textAnchor; + this.enclosingBoxLineStyle = enclosingBoxLineStyle; + this.enclosingBox_lineWidth_relToTextSize = enclosingBox_lineWidth_relToTextSize; + this.enclosingBox_paddingSize_relToTextSize = enclosingBox_paddingSize_relToTextSize; + this.forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + this.forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + this.autoLineBreakAtViewportBorder = autoLineBreakAtViewportBorder; + this.autoLineBreakWidth_relToViewportWidth = autoLineBreakWidth_relToViewportWidth; + this.autoFlipTextToPreventUpsideDown = autoFlipTextToPreventUpsideDown; + this.durationInSec = durationInSec; + } + } + + public struct TextScreenspaceFramed_2Dpos_dirViaAngle_cam + { + public Camera screenCamera; + public string text; + public Vector2 position_in2DViewportSpace; + public Color color; + public float size_relToViewportHeight; + public float zRotationDegCC; + public DrawText.TextAnchorDXXL textAnchor; + public DrawBasics.LineStyle enclosingBoxLineStyle; + public float enclosingBox_lineWidth_relToTextSize; + public float enclosingBox_paddingSize_relToTextSize; + public float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + public float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + public bool autoLineBreakAtViewportBorder; + public float autoLineBreakWidth_relToViewportWidth; + public bool autoFlipTextToPreventUpsideDown; + public float durationInSec; + + public TextScreenspaceFramed_2Dpos_dirViaAngle_cam(Camera screenCamera, string text, Vector2 position_in2DViewportSpace, Color color, float size_relToViewportHeight, float zRotationDegCC, DrawText.TextAnchorDXXL textAnchor, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextBlockEnlargementToThisMinWidth_relToViewportWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth, bool autoLineBreakAtViewportBorder, float autoLineBreakWidth_relToViewportWidth, bool autoFlipTextToPreventUpsideDown, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.zRotationDegCC = zRotationDegCC; + this.textAnchor = textAnchor; + this.enclosingBoxLineStyle = enclosingBoxLineStyle; + this.enclosingBox_lineWidth_relToTextSize = enclosingBox_lineWidth_relToTextSize; + this.enclosingBox_paddingSize_relToTextSize = enclosingBox_paddingSize_relToTextSize; + this.forceTextBlockEnlargementToThisMinWidth_relToViewportWidth = forceTextBlockEnlargementToThisMinWidth_relToViewportWidth; + this.forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth = forceRestrictTextBlockSizeToThisMaxTextWidth_relToViewportWidth; + this.autoLineBreakAtViewportBorder = autoLineBreakAtViewportBorder; + this.autoLineBreakWidth_relToViewportWidth = autoLineBreakWidth_relToViewportWidth; + this.autoFlipTextToPreventUpsideDown = autoFlipTextToPreventUpsideDown; + this.durationInSec = durationInSec; + } + } + + public struct TextOnCircleScreenspace_viaStartPos_cam + { + public Camera screenCamera; + public string text; + public Vector2 textStartPos; + public Vector2 circleCenterPosition; + public Color color; + public float size_relToViewportHeight; + public DrawText.TextAnchorCircledDXXL textAnchor; + public float autoLineBreakAngleDeg; + public float durationInSec; + + public TextOnCircleScreenspace_viaStartPos_cam(Camera screenCamera, string text, Vector2 textStartPos, Vector2 circleCenterPosition, Color color, float size_relToViewportHeight, DrawText.TextAnchorCircledDXXL textAnchor, float autoLineBreakAngleDeg, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.textStartPos = textStartPos; + this.circleCenterPosition = circleCenterPosition; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.textAnchor = textAnchor; + this.autoLineBreakAngleDeg = autoLineBreakAngleDeg; + this.durationInSec = durationInSec; + } + } + + public struct TextOnCircleScreenspace_dirViaVecUp_cam + { + public Camera screenCamera; + public string text; + public Vector2 circleCenterPosition; + public float radius_relToViewportHeight; + public Color color; + public float size_relToViewportHeight; + public Vector2 textsInitialUp; + public DrawText.TextAnchorCircledDXXL textAnchor; + public float autoLineBreakAngleDeg; + public float durationInSec; + + public TextOnCircleScreenspace_dirViaVecUp_cam(Camera screenCamera, string text, Vector2 circleCenterPosition, float radius_relToViewportHeight, Color color, float size_relToViewportHeight, Vector2 textsInitialUp, DrawText.TextAnchorCircledDXXL textAnchor, float autoLineBreakAngleDeg, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.circleCenterPosition = circleCenterPosition; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.textsInitialUp = textsInitialUp; + this.textAnchor = textAnchor; + this.autoLineBreakAngleDeg = autoLineBreakAngleDeg; + this.durationInSec = durationInSec; + } + } + + public struct TextOnCircleScreenspace_dirViaAngle_cam + { + public Camera screenCamera; + public string text; + public Vector2 circleCenterPosition; + public float radius_relToViewportHeight; + public Color color; + public float size_relToViewportHeight; + public float initialTextDirection_as_zRotationDegCCfromCamUp; + public DrawText.TextAnchorCircledDXXL textAnchor; + public float autoLineBreakAngleDeg; + public float durationInSec; + + public TextOnCircleScreenspace_dirViaAngle_cam(Camera screenCamera, string text, Vector2 circleCenterPosition, float radius_relToViewportHeight, Color color, float size_relToViewportHeight, float initialTextDirection_as_zRotationDegCCfromCamUp, DrawText.TextAnchorCircledDXXL textAnchor, float autoLineBreakAngleDeg, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.text = text; + this.circleCenterPosition = circleCenterPosition; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.initialTextDirection_as_zRotationDegCCfromCamUp = initialTextDirection_as_zRotationDegCCfromCamUp; + this.textAnchor = textAnchor; + this.autoLineBreakAngleDeg = autoLineBreakAngleDeg; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfBool_screenspace_3Dpos + { + public bool[] boolArray; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfBool_screenspace_3Dpos(bool[] boolArray, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.boolArray = boolArray; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfBool_screenspace_3Dpos_cam + { + public Camera screenCamera; + public bool[] boolArray; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfBool_screenspace_3Dpos_cam(Camera screenCamera, bool[] boolArray, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.boolArray = boolArray; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfBool_screenspace_2Dpos + { + public bool[] boolArray; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfBool_screenspace_2Dpos(bool[] boolArray, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.boolArray = boolArray; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfBool_screenspace_2Dpos_cam + { + public Camera screenCamera; + public bool[] boolArray; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfBool_screenspace_2Dpos_cam(Camera screenCamera, bool[] boolArray, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.boolArray = boolArray; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfBool_screenspace_3Dpos + { + public List boolList; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfBool_screenspace_3Dpos(List boolList, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.boolList = boolList; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfBool_screenspace_3Dpos_cam + { + public Camera screenCamera; + public List boolList; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfBool_screenspace_3Dpos_cam(Camera screenCamera, List boolList, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.boolList = boolList; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfBool_screenspace_2Dpos + { + public List boolList; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfBool_screenspace_2Dpos(List boolList, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.boolList = boolList; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfBool_screenspace_2Dpos_cam + { + public Camera screenCamera; + public List boolList; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfBool_screenspace_2Dpos_cam(Camera screenCamera, List boolList, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.boolList = boolList; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfInt_screenspace_3Dpos + { + public int[] intArray; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfInt_screenspace_3Dpos(int[] intArray, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.intArray = intArray; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfInt_screenspace_3Dpos_cam + { + public Camera screenCamera; + public int[] intArray; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfInt_screenspace_3Dpos_cam(Camera screenCamera, int[] intArray, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.intArray = intArray; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfInt_screenspace_2Dpos + { + public int[] intArray; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfInt_screenspace_2Dpos(int[] intArray, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.intArray = intArray; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfInt_screenspace_2Dpos_cam + { + public Camera screenCamera; + public int[] intArray; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfInt_screenspace_2Dpos_cam(Camera screenCamera, int[] intArray, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.intArray = intArray; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfInt_screenspace_3Dpos + { + public List intList; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfInt_screenspace_3Dpos(List intList, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.intList = intList; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfInt_screenspace_3Dpos_cam + { + public Camera screenCamera; + public List intList; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfInt_screenspace_3Dpos_cam(Camera screenCamera, List intList, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.intList = intList; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfInt_screenspace_2Dpos + { + public List intList; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfInt_screenspace_2Dpos(List intList, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.intList = intList; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfInt_screenspace_2Dpos_cam + { + public Camera screenCamera; + public List intList; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfInt_screenspace_2Dpos_cam(Camera screenCamera, List intList, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.intList = intList; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfFloat_screenspace_3Dpos + { + public float[] floatArray; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfFloat_screenspace_3Dpos(float[] floatArray, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.floatArray = floatArray; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfFloat_screenspace_3Dpos_cam + { + public Camera screenCamera; + public float[] floatArray; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfFloat_screenspace_3Dpos_cam(Camera screenCamera, float[] floatArray, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.floatArray = floatArray; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfFloat_screenspace_2Dpos + { + public float[] floatArray; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfFloat_screenspace_2Dpos(float[] floatArray, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.floatArray = floatArray; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfFloat_screenspace_2Dpos_cam + { + public Camera screenCamera; + public float[] floatArray; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfFloat_screenspace_2Dpos_cam(Camera screenCamera, float[] floatArray, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.floatArray = floatArray; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfFloat_screenspace_3Dpos + { + public List floatList; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfFloat_screenspace_3Dpos(List floatList, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.floatList = floatList; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfFloat_screenspace_3Dpos_cam + { + public Camera screenCamera; + public List floatList; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfFloat_screenspace_3Dpos_cam(Camera screenCamera, List floatList, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.floatList = floatList; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfFloat_screenspace_2Dpos + { + public List floatList; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfFloat_screenspace_2Dpos(List floatList, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.floatList = floatList; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfFloat_screenspace_2Dpos_cam + { + public Camera screenCamera; + public List floatList; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfFloat_screenspace_2Dpos_cam(Camera screenCamera, List floatList, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.floatList = floatList; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfString_screenspace_3Dpos + { + public string[] stringArray; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfString_screenspace_3Dpos(string[] stringArray, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.stringArray = stringArray; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfString_screenspace_3Dpos_cam + { + public Camera screenCamera; + public string[] stringArray; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfString_screenspace_3Dpos_cam(Camera screenCamera, string[] stringArray, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.stringArray = stringArray; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfString_screenspace_2Dpos + { + public string[] stringArray; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfString_screenspace_2Dpos(string[] stringArray, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.stringArray = stringArray; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfString_screenspace_2Dpos_cam + { + public Camera screenCamera; + public string[] stringArray; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfString_screenspace_2Dpos_cam(Camera screenCamera, string[] stringArray, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.stringArray = stringArray; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfString_screenspace_3Dpos + { + public List stringList; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfString_screenspace_3Dpos(List stringList, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.stringList = stringList; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfString_screenspace_3Dpos_cam + { + public Camera screenCamera; + public List stringList; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfString_screenspace_3Dpos_cam(Camera screenCamera, List stringList, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.stringList = stringList; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfString_screenspace_2Dpos + { + public List stringList; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfString_screenspace_2Dpos(List stringList, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.stringList = stringList; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfString_screenspace_2Dpos_cam + { + public Camera screenCamera; + public List stringList; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfString_screenspace_2Dpos_cam(Camera screenCamera, List stringList, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.stringList = stringList; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector2_screenspace_3Dpos + { + public Vector2[] vector2Array; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector2_screenspace_3Dpos(Vector2[] vector2Array, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector2Array = vector2Array; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector2_screenspace_3Dpos_cam + { + public Camera screenCamera; + public Vector2[] vector2Array; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector2_screenspace_3Dpos_cam(Camera screenCamera, Vector2[] vector2Array, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector2Array = vector2Array; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector2_screenspace_2Dpos + { + public Vector2[] vector2Array; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector2_screenspace_2Dpos(Vector2[] vector2Array, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector2Array = vector2Array; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector2_screenspace_2Dpos_cam + { + public Camera screenCamera; + public Vector2[] vector2Array; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector2_screenspace_2Dpos_cam(Camera screenCamera, Vector2[] vector2Array, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector2Array = vector2Array; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector2_screenspace_3Dpos + { + public List vector2List; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector2_screenspace_3Dpos(List vector2List, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector2List = vector2List; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector2_screenspace_3Dpos_cam + { + public Camera screenCamera; + public List vector2List; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector2_screenspace_3Dpos_cam(Camera screenCamera, List vector2List, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector2List = vector2List; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector2_screenspace_2Dpos + { + public List vector2List; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector2_screenspace_2Dpos(List vector2List, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector2List = vector2List; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector2_screenspace_2Dpos_cam + { + public Camera screenCamera; + public List vector2List; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector2_screenspace_2Dpos_cam(Camera screenCamera, List vector2List, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector2List = vector2List; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector3_screenspace_3Dpos + { + public Vector3[] vector3Array; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector3_screenspace_3Dpos(Vector3[] vector3Array, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector3Array = vector3Array; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector3_screenspace_3Dpos_cam + { + public Camera screenCamera; + public Vector3[] vector3Array; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector3_screenspace_3Dpos_cam(Camera screenCamera, Vector3[] vector3Array, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector3Array = vector3Array; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector3_screenspace_2Dpos + { + public Vector3[] vector3Array; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector3_screenspace_2Dpos(Vector3[] vector3Array, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector3Array = vector3Array; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector3_screenspace_2Dpos_cam + { + public Camera screenCamera; + public Vector3[] vector3Array; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector3_screenspace_2Dpos_cam(Camera screenCamera, Vector3[] vector3Array, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector3Array = vector3Array; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector3_screenspace_3Dpos + { + public List vector3List; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector3_screenspace_3Dpos(List vector3List, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector3List = vector3List; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector3_screenspace_3Dpos_cam + { + public Camera screenCamera; + public List vector3List; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector3_screenspace_3Dpos_cam(Camera screenCamera, List vector3List, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector3List = vector3List; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector3_screenspace_2Dpos + { + public List vector3List; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector3_screenspace_2Dpos(List vector3List, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector3List = vector3List; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector3_screenspace_2Dpos_cam + { + public Camera screenCamera; + public List vector3List; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector3_screenspace_2Dpos_cam(Camera screenCamera, List vector3List, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector3List = vector3List; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector4_screenspace_3Dpos + { + public Vector4[] vector4Array; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector4_screenspace_3Dpos(Vector4[] vector4Array, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector4Array = vector4Array; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector4_screenspace_3Dpos_cam + { + public Camera screenCamera; + public Vector4[] vector4Array; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector4_screenspace_3Dpos_cam(Camera screenCamera, Vector4[] vector4Array, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector4Array = vector4Array; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector4_screenspace_2Dpos + { + public Vector4[] vector4Array; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector4_screenspace_2Dpos(Vector4[] vector4Array, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector4Array = vector4Array; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ArrayOfVector4_screenspace_2Dpos_cam + { + public Camera screenCamera; + public Vector4[] vector4Array; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ArrayOfVector4_screenspace_2Dpos_cam(Camera screenCamera, Vector4[] vector4Array, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector4Array = vector4Array; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector4_screenspace_3Dpos + { + public List vector4List; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector4_screenspace_3Dpos(List vector4List, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector4List = vector4List; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector4_screenspace_3Dpos_cam + { + public Camera screenCamera; + public List vector4List; + public Vector3 position_in3DWorldspace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector4_screenspace_3Dpos_cam(Camera screenCamera, List vector4List, Vector3 position_in3DWorldspace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector4List = vector4List; + this.position_in3DWorldspace = position_in3DWorldspace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector4_screenspace_2Dpos + { + public List vector4List; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector4_screenspace_2Dpos(List vector4List, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.vector4List = vector4List; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct ListOfVector4_screenspace_2Dpos_cam + { + public Camera screenCamera; + public List vector4List; + public Vector2 position_in2DViewportSpace; + public Color color; + public string title; + public float textSize_relToViewportHeight; + public float forceHeightOfWholeTableBox_relToViewportHeight; + public bool position_isTopLeft_notLowLeft; + public float durationInSec; + + public ListOfVector4_screenspace_2Dpos_cam(Camera screenCamera, List vector4List, Vector2 position_in2DViewportSpace, Color color, string title, float textSize_relToViewportHeight, float forceHeightOfWholeTableBox_relToViewportHeight, bool position_isTopLeft_notLowLeft, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.vector4List = vector4List; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.color = color; + this.title = title; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.forceHeightOfWholeTableBox_relToViewportHeight = forceHeightOfWholeTableBox_relToViewportHeight; + this.position_isTopLeft_notLowLeft = position_isTopLeft_notLowLeft; + this.durationInSec = durationInSec; + } + } + + public struct TagGameObjectScreenspace + { + public Camera screenCamera; + public GameObject gameObject; + public string text; + public Color colorForText; + public Color colorForTagBox; + public float linesWidth_relToViewportHeight; + public bool drawPointerIfOffscreen; + public float relTextSizeScaling; + public bool encapsulateChildren; + public float durationInSec; + + public TagGameObjectScreenspace(Camera screenCamera, GameObject gameObject, string text, Color colorForText, Color colorForTagBox, float linesWidth_relToViewportHeight, bool drawPointerIfOffscreen, float relTextSizeScaling, bool encapsulateChildren, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.gameObject = gameObject; + this.text = text; + this.colorForText = colorForText; + this.colorForTagBox = colorForTagBox; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.relTextSizeScaling = relTextSizeScaling; + this.encapsulateChildren = encapsulateChildren; + this.durationInSec = durationInSec; + } + } + + public struct GridScreenspace + { + public Camera camera; + public Color color; + public float linesWidth_relToViewportHeight; + public bool drawTenthLines; + public bool drawHundredthLines; + public DrawEngineBasics.GridScreenspaceMode gridScreenspaceMode; + public float durationInSec; + + public GridScreenspace(Camera camera, Color color, float linesWidth_relToViewportHeight, bool drawTenthLines, bool drawHundredthLines, DrawEngineBasics.GridScreenspaceMode gridScreenspaceMode, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.camera = camera; + this.color = color; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.drawTenthLines = drawTenthLines; + this.drawHundredthLines = drawHundredthLines; + this.gridScreenspaceMode = gridScreenspaceMode; + this.durationInSec = durationInSec; + } + } + + public struct BoolDisplayerScreenspace_3Dpos + { + public bool boolValueToDisplay; + public string boolName; + public Vector3 position_in3DWorldspace; + public float size_relToViewportHeight; + public Color color_forTextAndFrame; + public Color overwriteColor_forTrue; + public Color overwriteColor_forFalse; + public float durationInSec; + + public BoolDisplayerScreenspace_3Dpos(bool boolValueToDisplay, string boolName, Vector3 position_in3DWorldspace, float size_relToViewportHeight, Color color_forTextAndFrame, Color overwriteColor_forTrue, Color overwriteColor_forFalse, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.boolValueToDisplay = boolValueToDisplay; + this.boolName = boolName; + this.position_in3DWorldspace = position_in3DWorldspace; + this.size_relToViewportHeight = size_relToViewportHeight; + this.color_forTextAndFrame = color_forTextAndFrame; + this.overwriteColor_forTrue = overwriteColor_forTrue; + this.overwriteColor_forFalse = overwriteColor_forFalse; + this.durationInSec = durationInSec; + } + } + + public struct BoolDisplayerScreenspace_3Dpos_cam + { + public Camera screenCamera; + public bool boolValueToDisplay; + public string boolName; + public Vector3 position_in3DWorldspace; + public float size_relToViewportHeight; + public Color color_forTextAndFrame; + public Color overwriteColor_forTrue; + public Color overwriteColor_forFalse; + public float durationInSec; + + public BoolDisplayerScreenspace_3Dpos_cam(Camera screenCamera, bool boolValueToDisplay, string boolName, Vector3 position_in3DWorldspace, float size_relToViewportHeight, Color color_forTextAndFrame, Color overwriteColor_forTrue, Color overwriteColor_forFalse, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.boolValueToDisplay = boolValueToDisplay; + this.boolName = boolName; + this.position_in3DWorldspace = position_in3DWorldspace; + this.size_relToViewportHeight = size_relToViewportHeight; + this.color_forTextAndFrame = color_forTextAndFrame; + this.overwriteColor_forTrue = overwriteColor_forTrue; + this.overwriteColor_forFalse = overwriteColor_forFalse; + this.durationInSec = durationInSec; + } + } + + public struct BoolDisplayerScreenspace_2Dpos_cam + { + public Camera screenCamera; + public bool boolValueToDisplay; + public string boolName; + public Vector2 position_in2DViewportSpace; + public float size_relToViewportHeight; + public Color color_forTextAndFrame; + public Color overwriteColor_forTrue; + public Color overwriteColor_forFalse; + public float durationInSec; + + public BoolDisplayerScreenspace_2Dpos_cam(Camera screenCamera, bool boolValueToDisplay, string boolName, Vector2 position_in2DViewportSpace, float size_relToViewportHeight, Color color_forTextAndFrame, Color overwriteColor_forTrue, Color overwriteColor_forFalse, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.screenCamera = screenCamera; + this.boolValueToDisplay = boolValueToDisplay; + this.boolName = boolName; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.size_relToViewportHeight = size_relToViewportHeight; + this.color_forTextAndFrame = color_forTextAndFrame; + this.overwriteColor_forTrue = overwriteColor_forTrue; + this.overwriteColor_forFalse = overwriteColor_forFalse; + this.durationInSec = durationInSec; + } + } + + public struct LogsOnScreen + { + public Camera cameraWhereToDraw; + public bool drawNormalPrio; + public bool drawWarningPrio; + public bool drawErrorPrio; + public int maxNumberOfDisplayedLogMessages; + public float textSize_relToViewportHeight; + public Color textColor; + public bool stackTraceForNormalPrio; + public bool stackTraceForWarningPrio; + public bool stackTraceForErrorPrio; + public float durationInSec; + public bool logListenerWasActive; //-> additional member that deviates from the normal pattern inside this script file. This is for keeping the functionality that the log listener can be activated and deactivated for different code blocks. + + public LogsOnScreen(Camera cameraWhereToDraw, bool drawNormalPrio, bool drawWarningPrio, bool drawErrorPrio, int maxNumberOfDisplayedLogMessages, float textSize_relToViewportHeight, Color textColor, bool stackTraceForNormalPrio, bool stackTraceForWarningPrio, bool stackTraceForErrorPrio, float durationInSec, bool logListenerWasActive) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.cameraWhereToDraw = cameraWhereToDraw; + this.drawNormalPrio = drawNormalPrio; + this.drawWarningPrio = drawWarningPrio; + this.drawErrorPrio = drawErrorPrio; + this.maxNumberOfDisplayedLogMessages = maxNumberOfDisplayedLogMessages; + this.textSize_relToViewportHeight = textSize_relToViewportHeight; + this.textColor = textColor; + this.stackTraceForNormalPrio = stackTraceForNormalPrio; + this.stackTraceForWarningPrio = stackTraceForWarningPrio; + this.stackTraceForErrorPrio = stackTraceForErrorPrio; + this.durationInSec = durationInSec; + this.logListenerWasActive = logListenerWasActive; + } + } + + public struct ScreenspaceLine + { + public Camera targetCamera; + public Vector2 start; + public Vector2 end; + public Color color; + public float width_relToViewportHeight; + public string text; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float animationSpeed; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceLine(Camera targetCamera, Vector2 start, Vector2 end, Color color, float width_relToViewportHeight, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.end = end; + this.color = color; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.animationSpeed = animationSpeed; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceRay + { + public Camera targetCamera; + public Vector2 start; + public Vector2 direction; + public Color color; + public float width_relToViewportHeight; + public string text; + public bool interpretDirectionAsUnwarped; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float animationSpeed; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceRay(Camera targetCamera, Vector2 start, Vector2 direction, Color color, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.direction = direction; + this.color = color; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.interpretDirectionAsUnwarped = interpretDirectionAsUnwarped; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.animationSpeed = animationSpeed; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineFrom + { + public Camera targetCamera; + public Vector2 start; + public Vector2 direction; + public Color color; + public float width_relToViewportHeight; + public string text; + public bool interpretDirectionAsUnwarped; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float animationSpeed; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceLineFrom(Camera targetCamera, Vector2 start, Vector2 direction, Color color, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.direction = direction; + this.color = color; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.interpretDirectionAsUnwarped = interpretDirectionAsUnwarped; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.animationSpeed = animationSpeed; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineTo + { + public Camera targetCamera; + public Vector2 direction; + public Vector2 end; + public Color color; + public float width_relToViewportHeight; + public string text; + public bool interpretDirectionAsUnwarped; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float animationSpeed; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceLineTo(Camera targetCamera, Vector2 direction, Vector2 end, Color color, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.direction = direction; + this.end = end; + this.color = color; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.interpretDirectionAsUnwarped = interpretDirectionAsUnwarped; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.animationSpeed = animationSpeed; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineColorFade + { + public Camera targetCamera; + public Vector2 start; + public Vector2 end; + public Color startColor; + public Color endColor; + public float width_relToViewportHeight; + public string text; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float animationSpeed; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceLineColorFade(Camera targetCamera, Vector2 start, Vector2 end, Color startColor, Color endColor, float width_relToViewportHeight, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.end = end; + this.startColor = startColor; + this.endColor = endColor; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.animationSpeed = animationSpeed; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceRayColorFade + { + public Camera targetCamera; + public Vector2 start; + public Vector2 direction; + public Color startColor; + public Color endColor; + public float width_relToViewportHeight; + public string text; + public bool interpretDirectionAsUnwarped; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float animationSpeed; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceRayColorFade(Camera targetCamera, Vector2 start, Vector2 direction, Color startColor, Color endColor, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.direction = direction; + this.startColor = startColor; + this.endColor = endColor; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.interpretDirectionAsUnwarped = interpretDirectionAsUnwarped; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.animationSpeed = animationSpeed; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineFrom_withColorFade + { + public Camera targetCamera; + public Vector2 start; + public Vector2 direction; + public Color startColor; + public Color endColor; + public float width_relToViewportHeight; + public string text; + public bool interpretDirectionAsUnwarped; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float animationSpeed; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceLineFrom_withColorFade(Camera targetCamera, Vector2 start, Vector2 direction, Color startColor, Color endColor, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.direction = direction; + this.startColor = startColor; + this.endColor = endColor; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.interpretDirectionAsUnwarped = interpretDirectionAsUnwarped; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.animationSpeed = animationSpeed; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineTo_withColorFade + { + public Camera targetCamera; + public Vector2 direction; + public Vector2 end; + public Color startColor; + public Color endColor; + public float width_relToViewportHeight; + public string text; + public bool interpretDirectionAsUnwarped; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float animationSpeed; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceLineTo_withColorFade(Camera targetCamera, Vector2 direction, Vector2 end, Color startColor, Color endColor, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.direction = direction; + this.end = end; + this.startColor = startColor; + this.endColor = endColor; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.interpretDirectionAsUnwarped = interpretDirectionAsUnwarped; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.animationSpeed = animationSpeed; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineCircled_angleToAngle_cam + { + public Camera targetCamera; + public Vector2 circleCenter; + public float startAngleDegCC_relativeToUp; + public float endAngleDegCC_relativeToUp; + public float radius_relToViewportHeight; + public Color color; + public float width_relToViewportHeight; + public string text; + public bool skipFallbackDisplayOfZeroAngles; + public float minAngleDeg_withoutTextLineBreak; + public DrawText.TextAnchorCircledDXXL textAnchor; + public float durationInSec; + public ScreenspaceLineCircled_angleToAngle_cam(Camera targetCamera, Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius_relToViewportHeight, Color color, float width_relToViewportHeight, string text, bool skipFallbackDisplayOfZeroAngles, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.circleCenter = circleCenter; + this.startAngleDegCC_relativeToUp = startAngleDegCC_relativeToUp; + this.endAngleDegCC_relativeToUp = endAngleDegCC_relativeToUp; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.skipFallbackDisplayOfZeroAngles = skipFallbackDisplayOfZeroAngles; + this.minAngleDeg_withoutTextLineBreak = minAngleDeg_withoutTextLineBreak; + this.textAnchor = textAnchor; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineCircled_angleFromStartPos_cam + { + public Camera targetCamera; + public Vector2 startPos; + public Vector2 circleCenter; + public float turnAngleDegCC; + public Color color; + public float width_relToViewportHeight; + public string text; + public bool skipFallbackDisplayOfZeroAngles; + public float minAngleDeg_withoutTextLineBreak; + public DrawText.TextAnchorCircledDXXL textAnchor; + public float durationInSec; + public ScreenspaceLineCircled_angleFromStartPos_cam(Camera targetCamera, Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color, float width_relToViewportHeight, string text, bool skipFallbackDisplayOfZeroAngles, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.startPos = startPos; + this.circleCenter = circleCenter; + this.turnAngleDegCC = turnAngleDegCC; + this.color = color; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.skipFallbackDisplayOfZeroAngles = skipFallbackDisplayOfZeroAngles; + this.minAngleDeg_withoutTextLineBreak = minAngleDeg_withoutTextLineBreak; + this.textAnchor = textAnchor; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCircleSegment_angleToAngle_cam + { + public Camera targetCamera; + public Vector2 circleCenter; + public float startAngleDegCC_relativeToUp; + public float endAngleDegCC_relativeToUp; + public float radius_relToViewportHeight; + public Color color; + public string text; + public float radiusPortionWhereDrawFillStarts; + public bool skipFallbackDisplayOfZeroAngles; + public float fillDensity; + public float minAngleDeg_withoutTextLineBreak; + public float durationInSec; + public ScreenspaceCircleSegment_angleToAngle_cam(Camera targetCamera, Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius_relToViewportHeight, Color color, string text, float radiusPortionWhereDrawFillStarts, bool skipFallbackDisplayOfZeroAngles, float fillDensity, float minAngleDeg_withoutTextLineBreak, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.circleCenter = circleCenter; + this.startAngleDegCC_relativeToUp = startAngleDegCC_relativeToUp; + this.endAngleDegCC_relativeToUp = endAngleDegCC_relativeToUp; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.text = text; + this.radiusPortionWhereDrawFillStarts = radiusPortionWhereDrawFillStarts; + this.skipFallbackDisplayOfZeroAngles = skipFallbackDisplayOfZeroAngles; + this.fillDensity = fillDensity; + this.minAngleDeg_withoutTextLineBreak = minAngleDeg_withoutTextLineBreak; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCircleSegment_angleFromStartPos_cam + { + public Camera targetCamera; + public Vector2 startPosOnPerimeter; + public Vector2 circleCenter; + public float turnAngleDegCC; + public Color color; + public string text; + public float radiusPortionWhereDrawFillStarts; + public bool skipFallbackDisplayOfZeroAngles; + public float fillDensity; + public float minAngleDeg_withoutTextLineBreak; + public float durationInSec; + public ScreenspaceCircleSegment_angleFromStartPos_cam(Camera targetCamera, Vector2 startPosOnPerimeter, Vector2 circleCenter, float turnAngleDegCC, Color color, string text, float radiusPortionWhereDrawFillStarts, bool skipFallbackDisplayOfZeroAngles, float fillDensity, float minAngleDeg_withoutTextLineBreak, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.startPosOnPerimeter = startPosOnPerimeter; + this.circleCenter = circleCenter; + this.turnAngleDegCC = turnAngleDegCC; + this.color = color; + this.text = text; + this.radiusPortionWhereDrawFillStarts = radiusPortionWhereDrawFillStarts; + this.skipFallbackDisplayOfZeroAngles = skipFallbackDisplayOfZeroAngles; + this.fillDensity = fillDensity; + this.minAngleDeg_withoutTextLineBreak = minAngleDeg_withoutTextLineBreak; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineString_array_cam + { + public Camera targetCamera; + public Vector2[] points; + public Color color; + public bool closeGapBetweenLastAndFirstPoint; + public float width_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float durationInSec; + public ScreenspaceLineString_array_cam(Camera targetCamera, Vector2[] points, Color color, bool closeGapBetweenLastAndFirstPoint, float width_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle style, float stylePatternScaleFactor, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.points = points; + this.color = color; + this.closeGapBetweenLastAndFirstPoint = closeGapBetweenLastAndFirstPoint; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineString_list_cam + { + public Camera targetCamera; + public List points; + public Color color; + public bool closeGapBetweenLastAndFirstPoint; + public float width_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float durationInSec; + public ScreenspaceLineString_list_cam(Camera targetCamera, List points, Color color, bool closeGapBetweenLastAndFirstPoint, float width_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle style, float stylePatternScaleFactor, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.points = points; + this.color = color; + this.closeGapBetweenLastAndFirstPoint = closeGapBetweenLastAndFirstPoint; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineStringColorFade_array_cam + { + public Camera targetCamera; + public Vector2[] points; + public Color startColor; + public Color endColor; + public bool closeGapBetweenLastAndFirstPoint; + public float width_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float durationInSec; + public ScreenspaceLineStringColorFade_array_cam(Camera targetCamera, Vector2[] points, Color startColor, Color endColor, bool closeGapBetweenLastAndFirstPoint, float width_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle style, float stylePatternScaleFactor, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.points = points; + this.startColor = startColor; + this.endColor = endColor; + this.closeGapBetweenLastAndFirstPoint = closeGapBetweenLastAndFirstPoint; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineStringColorFade_list_cam + { + public Camera targetCamera; + public List points; + public Color startColor; + public Color endColor; + public bool closeGapBetweenLastAndFirstPoint; + public float width_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle style; + public float stylePatternScaleFactor; + public float durationInSec; + public ScreenspaceLineStringColorFade_list_cam(Camera targetCamera, List points, Color startColor, Color endColor, bool closeGapBetweenLastAndFirstPoint, float width_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle style, float stylePatternScaleFactor, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.points = points; + this.startColor = startColor; + this.endColor = endColor; + this.closeGapBetweenLastAndFirstPoint = closeGapBetweenLastAndFirstPoint; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.style = style; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceShape_3Dpos + { + public Vector3 centerPosition_in3DWorldspace; + public DrawShapes.Shape2DType shape; + public Color color; + public float width_relToViewportHeight; + public float height_relToViewportHeight; + public float zRotationDegCC; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceShape_3Dpos(Vector3 centerPosition_in3DWorldspace, DrawShapes.Shape2DType shape, Color color, float width_relToViewportHeight, float height_relToViewportHeight, float zRotationDegCC, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.centerPosition_in3DWorldspace = centerPosition_in3DWorldspace; + this.shape = shape; + this.color = color; + this.width_relToViewportHeight = width_relToViewportHeight; + this.height_relToViewportHeight = height_relToViewportHeight; + this.zRotationDegCC = zRotationDegCC; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceShape_3Dpos_cam + { + public Camera targetCamera; + public Vector3 centerPosition_in3DWorldspace; + public DrawShapes.Shape2DType shape; + public Color color; + public float width_relToViewportHeight; + public float height_relToViewportHeight; + public float zRotationDegCC; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceShape_3Dpos_cam(Camera targetCamera, Vector3 centerPosition_in3DWorldspace, DrawShapes.Shape2DType shape, Color color, float width_relToViewportHeight, float height_relToViewportHeight, float zRotationDegCC, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.centerPosition_in3DWorldspace = centerPosition_in3DWorldspace; + this.shape = shape; + this.color = color; + this.width_relToViewportHeight = width_relToViewportHeight; + this.height_relToViewportHeight = height_relToViewportHeight; + this.zRotationDegCC = zRotationDegCC; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceShape_2Dpos_cam + { + public Camera targetCamera; + public Vector2 centerPosition_in2DViewportSpace; + public DrawShapes.Shape2DType shape; + public Color color; + public float width_relToViewportHeight; + public float height_relToViewportHeight; + public float zRotationDegCC; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceShape_2Dpos_cam(Camera targetCamera, Vector2 centerPosition_in2DViewportSpace, DrawShapes.Shape2DType shape, Color color, float width_relToViewportHeight, float height_relToViewportHeight, float zRotationDegCC, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.centerPosition_in2DViewportSpace = centerPosition_in2DViewportSpace; + this.shape = shape; + this.color = color; + this.width_relToViewportHeight = width_relToViewportHeight; + this.height_relToViewportHeight = height_relToViewportHeight; + this.zRotationDegCC = zRotationDegCC; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceRectangle + { + public Camera targetCamera; + public Vector2 lowLeftCorner; + public float width_relToScreenWidth; + public float height_relToScreenHeight; + public Color color; + public DrawShapes.Shape2DType shape; + public float linesWidth_relToScreenHeight; + public string text; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public float durationInSec; + public ScreenspaceRectangle(Camera targetCamera, Vector2 lowLeftCorner, float width_relToScreenWidth, float height_relToScreenHeight, Color color, DrawShapes.Shape2DType shape, float linesWidth_relToScreenHeight, string text, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.lowLeftCorner = lowLeftCorner; + this.width_relToScreenWidth = width_relToScreenWidth; + this.height_relToScreenHeight = height_relToScreenHeight; + this.color = color; + this.shape = shape; + this.linesWidth_relToScreenHeight = linesWidth_relToScreenHeight; + this.text = text; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceBox_rect_cam + { + public Camera targetCamera; + public Rect rect; + public Color color; + public float zRotationDegCC; + public DrawShapes.Shape2DType shape; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceBox_rect_cam(Camera targetCamera, Rect rect, Color color, float zRotationDegCC, DrawShapes.Shape2DType shape, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.rect = rect; + this.color = color; + this.zRotationDegCC = zRotationDegCC; + this.shape = shape; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceBox_3Dpos_vec + { + public Vector3 centerPosition_in3DWorldspace; + public Vector2 size_relToViewportHeight; + public Color color; + public float zRotationDegCC; + public DrawShapes.Shape2DType shape; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool forceSizeInterpretationToWarpedViewportSpace; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceBox_3Dpos_vec(Vector3 centerPosition_in3DWorldspace, Vector2 size_relToViewportHeight, Color color, float zRotationDegCC, DrawShapes.Shape2DType shape, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool forceSizeInterpretationToWarpedViewportSpace, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.centerPosition_in3DWorldspace = centerPosition_in3DWorldspace; + this.size_relToViewportHeight = size_relToViewportHeight; + this.color = color; + this.zRotationDegCC = zRotationDegCC; + this.shape = shape; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.forceSizeInterpretationToWarpedViewportSpace = forceSizeInterpretationToWarpedViewportSpace; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceBox_3Dpos_vec_cam + { + public Camera targetCamera; + public Vector3 centerPosition_in3DWorldspace; + public Vector2 size_relToViewportHeight; + public Color color; + public float zRotationDegCC; + public DrawShapes.Shape2DType shape; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool forceSizeInterpretationToWarpedViewportSpace; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceBox_3Dpos_vec_cam(Camera targetCamera, Vector3 centerPosition_in3DWorldspace, Vector2 size_relToViewportHeight, Color color, float zRotationDegCC, DrawShapes.Shape2DType shape, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool forceSizeInterpretationToWarpedViewportSpace, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.centerPosition_in3DWorldspace = centerPosition_in3DWorldspace; + this.size_relToViewportHeight = size_relToViewportHeight; + this.color = color; + this.zRotationDegCC = zRotationDegCC; + this.shape = shape; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.forceSizeInterpretationToWarpedViewportSpace = forceSizeInterpretationToWarpedViewportSpace; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceBox_2Dpos_vec_cam + { + public Camera targetCamera; + public Vector2 centerPosition_in2DViewportSpace; + public Vector2 size_relToViewportHeight; + public Color color; + public float zRotationDegCC; + public DrawShapes.Shape2DType shape; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool forceSizeInterpretationToWarpedViewportSpace; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceBox_2Dpos_vec_cam(Camera targetCamera, Vector2 centerPosition_in2DViewportSpace, Vector2 size_relToViewportHeight, Color color, float zRotationDegCC, DrawShapes.Shape2DType shape, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool forceSizeInterpretationToWarpedViewportSpace, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.centerPosition_in2DViewportSpace = centerPosition_in2DViewportSpace; + this.size_relToViewportHeight = size_relToViewportHeight; + this.color = color; + this.zRotationDegCC = zRotationDegCC; + this.shape = shape; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.forceSizeInterpretationToWarpedViewportSpace = forceSizeInterpretationToWarpedViewportSpace; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCircle_rect_cam + { + public Camera targetCamera; + public Rect rect; + public Color color; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCircle_rect_cam(Camera targetCamera, Rect rect, Color color, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.rect = rect; + this.color = color; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCircle_3Dpos_vecRad + { + public Vector3 centerPosition_in3DWorldspace; + public float radius_relToViewportHeight; + public Color color; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCircle_3Dpos_vecRad(Vector3 centerPosition_in3DWorldspace, float radius_relToViewportHeight, Color color, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.centerPosition_in3DWorldspace = centerPosition_in3DWorldspace; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCircle_3Dpos_vecRad_cam + { + public Camera targetCamera; + public Vector3 centerPosition_in3DWorldspace; + public float radius_relToViewportHeight; + public Color color; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCircle_3Dpos_vecRad_cam(Camera targetCamera, Vector3 centerPosition_in3DWorldspace, float radius_relToViewportHeight, Color color, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.centerPosition_in3DWorldspace = centerPosition_in3DWorldspace; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCircle_2Dpos_vecRad_cam + { + public Camera targetCamera; + public Vector2 centerPosition_in2DViewportSpace; + public float radius_relToViewportHeight; + public Color color; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCircle_2Dpos_vecRad_cam(Camera targetCamera, Vector2 centerPosition_in2DViewportSpace, float radius_relToViewportHeight, Color color, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.centerPosition_in2DViewportSpace = centerPosition_in2DViewportSpace; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCapsule_3Dpos_vecC1C2Pos + { + public Vector3 posOfCircle1_in3DWorldspace; + public Vector3 posOfCircle2_in3DWorldspace; + public float radius_relToViewportHeight; + public Color color; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCapsule_3Dpos_vecC1C2Pos(Vector3 posOfCircle1_in3DWorldspace, Vector3 posOfCircle2_in3DWorldspace, float radius_relToViewportHeight, Color color, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.posOfCircle1_in3DWorldspace = posOfCircle1_in3DWorldspace; + this.posOfCircle2_in3DWorldspace = posOfCircle2_in3DWorldspace; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam + { + public Camera targetCamera; + public Vector3 posOfCircle1_in3DWorldspace; + public Vector3 posOfCircle2_in3DWorldspace; + public float radius_relToViewportHeight; + public Color color; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCapsule_3Dpos_vecC1C2Pos_cam(Camera targetCamera, Vector3 posOfCircle1_in3DWorldspace, Vector3 posOfCircle2_in3DWorldspace, float radius_relToViewportHeight, Color color, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.posOfCircle1_in3DWorldspace = posOfCircle1_in3DWorldspace; + this.posOfCircle2_in3DWorldspace = posOfCircle2_in3DWorldspace; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam + { + public Camera targetCamera; + public Vector2 posOfCircle1_in2DViewportSpace; + public Vector2 posOfCircle2_in2DViewportSpace; + public float radius_relToViewportHeight; + public Color color; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCapsule_2Dpos_vecC1C2Pos_cam(Camera targetCamera, Vector2 posOfCircle1_in2DViewportSpace, Vector2 posOfCircle2_in2DViewportSpace, float radius_relToViewportHeight, Color color, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.posOfCircle1_in2DViewportSpace = posOfCircle1_in2DViewportSpace; + this.posOfCircle2_in2DViewportSpace = posOfCircle2_in2DViewportSpace; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCapsule_rect_cam + { + public Camera targetCamera; + public Rect rect; + public Color color; + public CapsuleDirection2D capsuleDirection; + public float zRotationDegCC; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCapsule_rect_cam(Camera targetCamera, Rect rect, Color color, CapsuleDirection2D capsuleDirection, float zRotationDegCC, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.rect = rect; + this.color = color; + this.capsuleDirection = capsuleDirection; + this.zRotationDegCC = zRotationDegCC; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCapsule_3Dpos_vecPosSize + { + public Vector3 centerPosition_in3DWorldspace; + public Vector2 size_relToViewportHeight; + public Color color; + public CapsuleDirection2D capsuleDirection; + public float zRotationDegCC; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool forceSizeInterpretationToWarpedViewportSpace; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCapsule_3Dpos_vecPosSize(Vector3 centerPosition_in3DWorldspace, Vector2 size_relToViewportHeight, Color color, CapsuleDirection2D capsuleDirection, float zRotationDegCC, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool forceSizeInterpretationToWarpedViewportSpace, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.centerPosition_in3DWorldspace = centerPosition_in3DWorldspace; + this.size_relToViewportHeight = size_relToViewportHeight; + this.color = color; + this.capsuleDirection = capsuleDirection; + this.zRotationDegCC = zRotationDegCC; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.forceSizeInterpretationToWarpedViewportSpace = forceSizeInterpretationToWarpedViewportSpace; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCapsule_3Dpos_vecPosSize_cam + { + public Camera targetCamera; + public Vector3 centerPosition_in3DWorldspace; + public Vector2 size_relToViewportHeight; + public Color color; + public CapsuleDirection2D capsuleDirection; + public float zRotationDegCC; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool forceSizeInterpretationToWarpedViewportSpace; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCapsule_3Dpos_vecPosSize_cam(Camera targetCamera, Vector3 centerPosition_in3DWorldspace, Vector2 size_relToViewportHeight, Color color, CapsuleDirection2D capsuleDirection, float zRotationDegCC, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool forceSizeInterpretationToWarpedViewportSpace, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.centerPosition_in3DWorldspace = centerPosition_in3DWorldspace; + this.size_relToViewportHeight = size_relToViewportHeight; + this.color = color; + this.capsuleDirection = capsuleDirection; + this.zRotationDegCC = zRotationDegCC; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.forceSizeInterpretationToWarpedViewportSpace = forceSizeInterpretationToWarpedViewportSpace; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceCapsule_2Dpos_vecPosSize_cam + { + public Camera targetCamera; + public Vector2 centerPosition_in2DViewportSpace; + public Vector2 size_relToViewportHeight; + public Color color; + public CapsuleDirection2D capsuleDirection; + public float zRotationDegCC; + public float linesWidth_relToViewportHeight; + public string text; + public bool drawPointerIfOffscreen; + public DrawBasics.LineStyle lineStyle; + public float stylePatternScaleFactor; + public DrawBasics.LineStyle fillStyle; + public bool forceSizeInterpretationToWarpedViewportSpace; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspaceCapsule_2Dpos_vecPosSize_cam(Camera targetCamera, Vector2 centerPosition_in2DViewportSpace, Vector2 size_relToViewportHeight, Color color, CapsuleDirection2D capsuleDirection, float zRotationDegCC, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool forceSizeInterpretationToWarpedViewportSpace, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.centerPosition_in2DViewportSpace = centerPosition_in2DViewportSpace; + this.size_relToViewportHeight = size_relToViewportHeight; + this.color = color; + this.capsuleDirection = capsuleDirection; + this.zRotationDegCC = zRotationDegCC; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.text = text; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.lineStyle = lineStyle; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.fillStyle = fillStyle; + this.forceSizeInterpretationToWarpedViewportSpace = forceSizeInterpretationToWarpedViewportSpace; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspacePointArray + { + public Camera targetCamera; + public Vector2[] points; + public Color color; + public float sizeOfMarkingCross_relToViewportHeight; + public float markingCrossLinesWidth_relToViewportHeight; + public bool drawCoordsAsText; + public float durationInSec; + public ScreenspacePointArray(Camera targetCamera, Vector2[] points, Color color, float sizeOfMarkingCross_relToViewportHeight, float markingCrossLinesWidth_relToViewportHeight, bool drawCoordsAsText, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.points = points; + this.color = color; + this.sizeOfMarkingCross_relToViewportHeight = sizeOfMarkingCross_relToViewportHeight; + this.markingCrossLinesWidth_relToViewportHeight = markingCrossLinesWidth_relToViewportHeight; + this.drawCoordsAsText = drawCoordsAsText; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspacePointList + { + public Camera targetCamera; + public List points; + public Color color; + public float sizeOfMarkingCross_relToViewportHeight; + public float markingCrossLinesWidth_relToViewportHeight; + public bool drawCoordsAsText; + public float durationInSec; + public ScreenspacePointList(Camera targetCamera, List points, Color color, float sizeOfMarkingCross_relToViewportHeight, float markingCrossLinesWidth_relToViewportHeight, bool drawCoordsAsText, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.points = points; + this.color = color; + this.sizeOfMarkingCross_relToViewportHeight = sizeOfMarkingCross_relToViewportHeight; + this.markingCrossLinesWidth_relToViewportHeight = markingCrossLinesWidth_relToViewportHeight; + this.drawCoordsAsText = drawCoordsAsText; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspacePoint + { + public Vector2 position; + public Color color; + public float sizeOfMarkingCross_relToViewportHeight; + public float zRotationDegCC; + public float markingCrossLinesWidth_relToViewportHeight; + public bool drawPointerIfOffscreen; + public string text; + public bool pointer_as_textAttachStyle; + public bool drawCoordsAsText; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspacePoint(Vector2 position, Color color, float sizeOfMarkingCross_relToViewportHeight, float zRotationDegCC, float markingCrossLinesWidth_relToViewportHeight, bool drawPointerIfOffscreen, string text, bool pointer_as_textAttachStyle, bool drawCoordsAsText, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.position = position; + this.color = color; + this.sizeOfMarkingCross_relToViewportHeight = sizeOfMarkingCross_relToViewportHeight; + this.zRotationDegCC = zRotationDegCC; + this.markingCrossLinesWidth_relToViewportHeight = markingCrossLinesWidth_relToViewportHeight; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.text = text; + this.pointer_as_textAttachStyle = pointer_as_textAttachStyle; + this.drawCoordsAsText = drawCoordsAsText; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspacePoint_prioText_cam + { + public Camera targetCamera; + public Vector2 position; + public string text; + public Color color; + public float sizeOfMarkingCross_relToViewportHeight; + public float markingCrossLinesWidth_relToViewportHeight; + public float zRotationDegCC; + public bool drawPointerIfOffscreen; + public bool pointer_as_textAttachStyle; + public bool drawCoordsAsText; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public ScreenspacePoint_prioText_cam(Camera targetCamera, Vector2 position, string text, Color color, float sizeOfMarkingCross_relToViewportHeight, float markingCrossLinesWidth_relToViewportHeight, float zRotationDegCC, bool drawPointerIfOffscreen, bool pointer_as_textAttachStyle, bool drawCoordsAsText, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.position = position; + this.text = text; + this.color = color; + this.sizeOfMarkingCross_relToViewportHeight = sizeOfMarkingCross_relToViewportHeight; + this.markingCrossLinesWidth_relToViewportHeight = markingCrossLinesWidth_relToViewportHeight; + this.zRotationDegCC = zRotationDegCC; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.pointer_as_textAttachStyle = pointer_as_textAttachStyle; + this.drawCoordsAsText = drawCoordsAsText; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspacePointTag_3Dpos + { + public Vector3 position_in3DWorldspace; + public string text; + public string titleText; + public Color color; + public bool drawPointerIfOffscreen; + public float linesWidth_relToViewportHeight; + public float size_asTextOffsetDistance_relToViewportHeight; + public Vector2 textOffsetDirection; + public float textSizeScaleFactor; + public bool skipConeDrawing; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public Vector2 customTowardsPoint_ofDefaultTextOffsetDirection; + public ScreenspacePointTag_3Dpos(Vector3 position_in3DWorldspace, string text, string titleText, Color color, bool drawPointerIfOffscreen, float linesWidth_relToViewportHeight, float size_asTextOffsetDistance_relToViewportHeight, Vector2 textOffsetDirection, float textSizeScaleFactor, bool skipConeDrawing, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec, Vector2 customTowardsPoint_ofDefaultTextOffsetDirection) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.position_in3DWorldspace = position_in3DWorldspace; + this.text = text; + this.titleText = titleText; + this.color = color; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.size_asTextOffsetDistance_relToViewportHeight = size_asTextOffsetDistance_relToViewportHeight; + this.textOffsetDirection = textOffsetDirection; + this.textSizeScaleFactor = textSizeScaleFactor; + this.skipConeDrawing = skipConeDrawing; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + this.customTowardsPoint_ofDefaultTextOffsetDirection = customTowardsPoint_ofDefaultTextOffsetDirection; + } + } + + public struct ScreenspacePointTag_3Dpos_cam + { + public Camera targetCamera; + public Vector3 position_in3DWorldspace; + public string text; + public string titleText; + public Color color; + public bool drawPointerIfOffscreen; + public float linesWidth_relToViewportHeight; + public float size_asTextOffsetDistance_relToViewportHeight; + public Vector2 textOffsetDirection; + public float textSizeScaleFactor; + public bool skipConeDrawing; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public Vector2 customTowardsPoint_ofDefaultTextOffsetDirection; + public ScreenspacePointTag_3Dpos_cam(Camera targetCamera, Vector3 position_in3DWorldspace, string text, string titleText, Color color, bool drawPointerIfOffscreen, float linesWidth_relToViewportHeight, float size_asTextOffsetDistance_relToViewportHeight, Vector2 textOffsetDirection, float textSizeScaleFactor, bool skipConeDrawing, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec, Vector2 customTowardsPoint_ofDefaultTextOffsetDirection) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.position_in3DWorldspace = position_in3DWorldspace; + this.text = text; + this.titleText = titleText; + this.color = color; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.size_asTextOffsetDistance_relToViewportHeight = size_asTextOffsetDistance_relToViewportHeight; + this.textOffsetDirection = textOffsetDirection; + this.textSizeScaleFactor = textSizeScaleFactor; + this.skipConeDrawing = skipConeDrawing; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + this.customTowardsPoint_ofDefaultTextOffsetDirection = customTowardsPoint_ofDefaultTextOffsetDirection; + } + } + + public struct ScreenspacePointTag_2Dpos_cam + { + public Camera targetCamera; + public Vector2 position_in2DViewportSpace; + public string text; + public string titleText; + public Color color; + public bool drawPointerIfOffscreen; + public float linesWidth_relToViewportHeight; + public float size_asTextOffsetDistance_relToViewportHeight; + public Vector2 textOffsetDirection; + public float textSizeScaleFactor; + public bool skipConeDrawing; + public bool addTextForOutsideDistance_toOffscreenPointer; + public float durationInSec; + public Vector2 customTowardsPoint_ofDefaultTextOffsetDirection; + public ScreenspacePointTag_2Dpos_cam(Camera targetCamera, Vector2 position_in2DViewportSpace, string text, string titleText, Color color, bool drawPointerIfOffscreen, float linesWidth_relToViewportHeight, float size_asTextOffsetDistance_relToViewportHeight, Vector2 textOffsetDirection, float textSizeScaleFactor, bool skipConeDrawing, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec, Vector2 customTowardsPoint_ofDefaultTextOffsetDirection) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.text = text; + this.titleText = titleText; + this.color = color; + this.drawPointerIfOffscreen = drawPointerIfOffscreen; + this.linesWidth_relToViewportHeight = linesWidth_relToViewportHeight; + this.size_asTextOffsetDistance_relToViewportHeight = size_asTextOffsetDistance_relToViewportHeight; + this.textOffsetDirection = textOffsetDirection; + this.textSizeScaleFactor = textSizeScaleFactor; + this.skipConeDrawing = skipConeDrawing; + this.addTextForOutsideDistance_toOffscreenPointer = addTextForOutsideDistance_toOffscreenPointer; + this.durationInSec = durationInSec; + this.customTowardsPoint_ofDefaultTextOffsetDirection = customTowardsPoint_ofDefaultTextOffsetDirection; + } + } + + public struct ScreenspaceVectorFrom + { + public Camera targetCamera; + public Vector2 vectorStartPos; + public Vector2 vector; + public Color color; + public float lineWidth_relToViewportHeight; + public string text; + public bool interpretVectorAsUnwarped; + public float coneLength_relToViewportHeight; + public bool pointerAtBothSides; + public bool writeComponentValuesAsText; + public float endPlatesSize_relToViewportHeight; + public float durationInSec; + public ScreenspaceVectorFrom(Camera targetCamera, Vector2 vectorStartPos, Vector2 vector, Color color, float lineWidth_relToViewportHeight, string text, bool interpretVectorAsUnwarped, float coneLength_relToViewportHeight, bool pointerAtBothSides, bool writeComponentValuesAsText, float endPlatesSize_relToViewportHeight, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.vectorStartPos = vectorStartPos; + this.vector = vector; + this.color = color; + this.lineWidth_relToViewportHeight = lineWidth_relToViewportHeight; + this.text = text; + this.interpretVectorAsUnwarped = interpretVectorAsUnwarped; + this.coneLength_relToViewportHeight = coneLength_relToViewportHeight; + this.pointerAtBothSides = pointerAtBothSides; + this.writeComponentValuesAsText = writeComponentValuesAsText; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceVectorTo + { + public Camera targetCamera; + public Vector2 vector; + public Vector2 vectorEndPos; + public Color color; + public float lineWidth_relToViewportHeight; + public string text; + public bool interpretVectorAsUnwarped; + public float coneLength_relToViewportHeight; + public bool pointerAtBothSides; + public bool writeComponentValuesAsText; + public float endPlatesSize_relToViewportHeight; + public float durationInSec; + public ScreenspaceVectorTo(Camera targetCamera, Vector2 vector, Vector2 vectorEndPos, Color color, float lineWidth_relToViewportHeight, string text, bool interpretVectorAsUnwarped, float coneLength_relToViewportHeight, bool pointerAtBothSides, bool writeComponentValuesAsText, float endPlatesSize_relToViewportHeight, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.vector = vector; + this.vectorEndPos = vectorEndPos; + this.color = color; + this.lineWidth_relToViewportHeight = lineWidth_relToViewportHeight; + this.text = text; + this.interpretVectorAsUnwarped = interpretVectorAsUnwarped; + this.coneLength_relToViewportHeight = coneLength_relToViewportHeight; + this.pointerAtBothSides = pointerAtBothSides; + this.writeComponentValuesAsText = writeComponentValuesAsText; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceVectorCircled_angleToAngle_cam + { + public Camera targetCamera; + public Vector2 circleCenter; + public float startAngleDegCC_relativeToUp; + public float endAngleDegCC_relativeToUp; + public float radius_relToViewportHeight; + public Color color; + public float lineWidth_relToViewportHeight; + public string text; + public float coneLength_relToViewportHeight; + public bool skipFallbackDisplayOfZeroAngles; + public bool pointerAtBothSides; + public float minAngleDeg_withoutTextLineBreak; + public DrawText.TextAnchorCircledDXXL textAnchor; + public float durationInSec; + public ScreenspaceVectorCircled_angleToAngle_cam(Camera targetCamera, Vector2 circleCenter, float startAngleDegCC_relativeToUp, float endAngleDegCC_relativeToUp, float radius_relToViewportHeight, Color color, float lineWidth_relToViewportHeight, string text, float coneLength_relToViewportHeight, bool skipFallbackDisplayOfZeroAngles, bool pointerAtBothSides, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.circleCenter = circleCenter; + this.startAngleDegCC_relativeToUp = startAngleDegCC_relativeToUp; + this.endAngleDegCC_relativeToUp = endAngleDegCC_relativeToUp; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.lineWidth_relToViewportHeight = lineWidth_relToViewportHeight; + this.text = text; + this.coneLength_relToViewportHeight = coneLength_relToViewportHeight; + this.skipFallbackDisplayOfZeroAngles = skipFallbackDisplayOfZeroAngles; + this.pointerAtBothSides = pointerAtBothSides; + this.minAngleDeg_withoutTextLineBreak = minAngleDeg_withoutTextLineBreak; + this.textAnchor = textAnchor; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceVectorCircled_angleFromStartPos_cam + { + public Camera targetCamera; + public Vector2 startPos; + public Vector2 circleCenter; + public float turnAngleDegCC; + public Color color; + public float lineWidth_relToViewportHeight; + public string text; + public float coneLength_relToViewportHeight; + public bool skipFallbackDisplayOfZeroAngles; + public bool pointerAtBothSides; + public float minAngleDeg_withoutTextLineBreak; + public DrawText.TextAnchorCircledDXXL textAnchor; + public float durationInSec; + public ScreenspaceVectorCircled_angleFromStartPos_cam(Camera targetCamera, Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color, float lineWidth_relToViewportHeight, string text, float coneLength_relToViewportHeight, bool skipFallbackDisplayOfZeroAngles, bool pointerAtBothSides, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.startPos = startPos; + this.circleCenter = circleCenter; + this.turnAngleDegCC = turnAngleDegCC; + this.color = color; + this.lineWidth_relToViewportHeight = lineWidth_relToViewportHeight; + this.text = text; + this.coneLength_relToViewportHeight = coneLength_relToViewportHeight; + this.skipFallbackDisplayOfZeroAngles = skipFallbackDisplayOfZeroAngles; + this.pointerAtBothSides = pointerAtBothSides; + this.minAngleDeg_withoutTextLineBreak = minAngleDeg_withoutTextLineBreak; + this.textAnchor = textAnchor; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceIcon_3Dpos + { + public Vector3 position_in3DWorldspace; + public DrawBasics.IconType icon; + public Color color; + public float size_relToViewportHeight; + public string text; + public float zRotationDegCC; + public float strokeWidth_relToViewportHeight; + public bool displayPointerIfOffscreen; + public bool mirrorHorizontally; + public float durationInSec; + public ScreenspaceIcon_3Dpos(Vector3 position_in3DWorldspace, DrawBasics.IconType icon, Color color, float size_relToViewportHeight, string text, float zRotationDegCC, float strokeWidth_relToViewportHeight, bool displayPointerIfOffscreen, bool mirrorHorizontally, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.position_in3DWorldspace = position_in3DWorldspace; + this.icon = icon; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.text = text; + this.zRotationDegCC = zRotationDegCC; + this.strokeWidth_relToViewportHeight = strokeWidth_relToViewportHeight; + this.displayPointerIfOffscreen = displayPointerIfOffscreen; + this.mirrorHorizontally = mirrorHorizontally; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceIcon_3Dpos_cam + { + public Camera targetCamera; + public Vector3 position_in3DWorldspace; + public DrawBasics.IconType icon; + public Color color; + public float size_relToViewportHeight; + public string text; + public float zRotationDegCC; + public float strokeWidth_relToViewportHeight; + public bool displayPointerIfOffscreen; + public bool mirrorHorizontally; + public float durationInSec; + public ScreenspaceIcon_3Dpos_cam(Camera targetCamera, Vector3 position_in3DWorldspace, DrawBasics.IconType icon, Color color, float size_relToViewportHeight, string text, float zRotationDegCC, float strokeWidth_relToViewportHeight, bool displayPointerIfOffscreen, bool mirrorHorizontally, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.position_in3DWorldspace = position_in3DWorldspace; + this.icon = icon; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.text = text; + this.zRotationDegCC = zRotationDegCC; + this.strokeWidth_relToViewportHeight = strokeWidth_relToViewportHeight; + this.displayPointerIfOffscreen = displayPointerIfOffscreen; + this.mirrorHorizontally = mirrorHorizontally; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceIcon_2Dpos_cam + { + public Camera targetCamera; + public Vector2 position_in2DViewportSpace; + public DrawBasics.IconType icon; + public Color color; + public float size_relToViewportHeight; + public string text; + public float zRotationDegCC; + public float strokeWidth_relToViewportHeight; + public bool displayPointerIfOffscreen; + public bool mirrorHorizontally; + public float durationInSec; + public ScreenspaceIcon_2Dpos_cam(Camera targetCamera, Vector2 position_in2DViewportSpace, DrawBasics.IconType icon, Color color, float size_relToViewportHeight, string text, float zRotationDegCC, float strokeWidth_relToViewportHeight, bool displayPointerIfOffscreen, bool mirrorHorizontally, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.icon = icon; + this.color = color; + this.size_relToViewportHeight = size_relToViewportHeight; + this.text = text; + this.zRotationDegCC = zRotationDegCC; + this.strokeWidth_relToViewportHeight = strokeWidth_relToViewportHeight; + this.displayPointerIfOffscreen = displayPointerIfOffscreen; + this.mirrorHorizontally = mirrorHorizontally; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceDot_3Dpos + { + public Vector3 position_in3DWorldspace; + public float radius_relToViewportHeight; + public Color color; + public string text; + public float density; + public bool displayPointerIfOffscreen; + public float durationInSec; + public ScreenspaceDot_3Dpos(Vector3 position_in3DWorldspace, float radius_relToViewportHeight, Color color, string text, float density, bool displayPointerIfOffscreen, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.position_in3DWorldspace = position_in3DWorldspace; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.text = text; + this.density = density; + this.displayPointerIfOffscreen = displayPointerIfOffscreen; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceDot_3Dpos_cam + { + public Camera targetCamera; + public Vector3 position_in3DWorldspace; + public float radius_relToViewportHeight; + public Color color; + public string text; + public float density; + public bool displayPointerIfOffscreen; + public float durationInSec; + public ScreenspaceDot_3Dpos_cam(Camera targetCamera, Vector3 position_in3DWorldspace, float radius_relToViewportHeight, Color color, string text, float density, bool displayPointerIfOffscreen, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.position_in3DWorldspace = position_in3DWorldspace; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.text = text; + this.density = density; + this.displayPointerIfOffscreen = displayPointerIfOffscreen; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceDot_2Dpos_cam + { + public Camera targetCamera; + public Vector2 position_in2DViewportSpace; + public float radius_relToViewportHeight; + public Color color; + public string text; + public float density; + public bool displayPointerIfOffscreen; + public float durationInSec; + public ScreenspaceDot_2Dpos_cam(Camera targetCamera, Vector2 position_in2DViewportSpace, float radius_relToViewportHeight, Color color, string text, float density, bool displayPointerIfOffscreen, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.position_in2DViewportSpace = position_in2DViewportSpace; + this.radius_relToViewportHeight = radius_relToViewportHeight; + this.color = color; + this.text = text; + this.density = density; + this.displayPointerIfOffscreen = displayPointerIfOffscreen; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceMovingArrowsRay + { + public Camera targetCamera; + public Vector2 start; + public Vector2 direction; + public Color color; + public float lineWidth_relToViewportHeight; + public float distanceBetweenArrows_relToViewportHeight; + public float lengthOfArrows_relToViewportHeight; + public string text; + public float animationSpeed; + public bool backwardAnimationFlipsArrowDirection; + public bool interpretDirectionAsUnwarped; + public float endPlatesSize_relToViewportHeight; + public float durationInSec; + public ScreenspaceMovingArrowsRay(Camera targetCamera, Vector2 start, Vector2 direction, Color color, float lineWidth_relToViewportHeight, float distanceBetweenArrows_relToViewportHeight, float lengthOfArrows_relToViewportHeight, string text, float animationSpeed, bool backwardAnimationFlipsArrowDirection, bool interpretDirectionAsUnwarped, float endPlatesSize_relToViewportHeight, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.direction = direction; + this.color = color; + this.lineWidth_relToViewportHeight = lineWidth_relToViewportHeight; + this.distanceBetweenArrows_relToViewportHeight = distanceBetweenArrows_relToViewportHeight; + this.lengthOfArrows_relToViewportHeight = lengthOfArrows_relToViewportHeight; + this.text = text; + this.animationSpeed = animationSpeed; + this.backwardAnimationFlipsArrowDirection = backwardAnimationFlipsArrowDirection; + this.interpretDirectionAsUnwarped = interpretDirectionAsUnwarped; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceMovingArrowsLine + { + public Camera targetCamera; + public Vector2 start; + public Vector2 end; + public Color color; + public float lineWidth_relToViewportHeight; + public float distanceBetweenArrows_relToViewportHeight; + public float lengthOfArrows_relToViewportHeight; + public string text; + public float animationSpeed; + public bool backwardAnimationFlipsArrowDirection; + public float endPlatesSize_relToViewportHeight; + public float durationInSec; + public ScreenspaceMovingArrowsLine(Camera targetCamera, Vector2 start, Vector2 end, Color color, float lineWidth_relToViewportHeight, float distanceBetweenArrows_relToViewportHeight, float lengthOfArrows_relToViewportHeight, string text, float animationSpeed, bool backwardAnimationFlipsArrowDirection, float endPlatesSize_relToViewportHeight, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.end = end; + this.color = color; + this.lineWidth_relToViewportHeight = lineWidth_relToViewportHeight; + this.distanceBetweenArrows_relToViewportHeight = distanceBetweenArrows_relToViewportHeight; + this.lengthOfArrows_relToViewportHeight = lengthOfArrows_relToViewportHeight; + this.text = text; + this.animationSpeed = animationSpeed; + this.backwardAnimationFlipsArrowDirection = backwardAnimationFlipsArrowDirection; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceRayWithAlternatingColors + { + public Camera targetCamera; + public Vector2 start; + public Vector2 direction; + public Color color1; + public Color color2; + public float lineWidth_relToViewportHeight; + public float lengthOfStripes_relToViewportHeight; + public string text; + public bool interpretDirectionAsUnwarped; + public float animationSpeed; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float durationInSec; + public ScreenspaceRayWithAlternatingColors(Camera targetCamera, Vector2 start, Vector2 direction, Color color1, Color color2, float lineWidth_relToViewportHeight, float lengthOfStripes_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, float animationSpeed, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.direction = direction; + this.color1 = color1; + this.color2 = color2; + this.lineWidth_relToViewportHeight = lineWidth_relToViewportHeight; + this.lengthOfStripes_relToViewportHeight = lengthOfStripes_relToViewportHeight; + this.text = text; + this.interpretDirectionAsUnwarped = interpretDirectionAsUnwarped; + this.animationSpeed = animationSpeed; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineWithAlternatingColors + { + public Camera targetCamera; + public Vector2 start; + public Vector2 end; + public Color color1; + public Color color2; + public float lineWidth_relToViewportHeight; + public float lengthOfStripes_relToViewportHeight; + public string text; + public float animationSpeed; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float durationInSec; + public ScreenspaceLineWithAlternatingColors(Camera targetCamera, Vector2 start, Vector2 end, Color color1, Color color2, float lineWidth_relToViewportHeight, float lengthOfStripes_relToViewportHeight, string text, float animationSpeed, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.end = end; + this.color1 = color1; + this.color2 = color2; + this.lineWidth_relToViewportHeight = lineWidth_relToViewportHeight; + this.lengthOfStripes_relToViewportHeight = lengthOfStripes_relToViewportHeight; + this.text = text; + this.animationSpeed = animationSpeed; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceBlinkingRay + { + public Camera targetCamera; + public Vector2 start; + public Vector2 direction; + public Color primaryColor; + public float blinkDurationInSec; + public float width_relToViewportHeight; + public string text; + public bool interpretDirectionAsUnwarped; + public DrawBasics.LineStyle style; + public Color blinkColor; + public float stylePatternScaleFactor; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceBlinkingRay(Camera targetCamera, Vector2 start, Vector2 direction, Color primaryColor, float blinkDurationInSec, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, Color blinkColor, float stylePatternScaleFactor, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.direction = direction; + this.primaryColor = primaryColor; + this.blinkDurationInSec = blinkDurationInSec; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.interpretDirectionAsUnwarped = interpretDirectionAsUnwarped; + this.style = style; + this.blinkColor = blinkColor; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceBlinkingLine + { + public Camera targetCamera; + public Vector2 start; + public Vector2 end; + public Color primaryColor; + public float blinkDurationInSec; + public float width_relToViewportHeight; + public string text; + public DrawBasics.LineStyle style; + public Color blinkColor; + public float stylePatternScaleFactor; + public float endPlatesSize_relToViewportHeight; + public float alphaFadeOutLength_0to1; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceBlinkingLine(Camera targetCamera, Vector2 start, Vector2 end, Color primaryColor, float blinkDurationInSec, float width_relToViewportHeight, string text, DrawBasics.LineStyle style, Color blinkColor, float stylePatternScaleFactor, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.end = end; + this.primaryColor = primaryColor; + this.blinkDurationInSec = blinkDurationInSec; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.style = style; + this.blinkColor = blinkColor; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.alphaFadeOutLength_0to1 = alphaFadeOutLength_0to1; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceRayUnderTension + { + public Camera targetCamera; + public Vector2 start; + public Vector2 direction; + public float relaxedLength_relToViewportHeight; + public Color relaxedColor; + public DrawBasics.LineStyle style; + public float stretchFactor_forStretchedTensionColor; + public Color color_forStretchedTension; + public float stretchFactor_forSqueezedTensionColor; + public Color color_forSqueezedTension; + public float width_relToViewportHeight; + public string text; + public float alphaOfReferenceLengthDisplay; + public bool interpretDirectionAsUnwarped; + public float stylePatternScaleFactor; + public float endPlatesSize_relToViewportHeight; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceRayUnderTension(Camera targetCamera, Vector2 start, Vector2 direction, float relaxedLength_relToViewportHeight, Color relaxedColor, DrawBasics.LineStyle style, float stretchFactor_forStretchedTensionColor, Color color_forStretchedTension, float stretchFactor_forSqueezedTensionColor, Color color_forSqueezedTension, float width_relToViewportHeight, string text, float alphaOfReferenceLengthDisplay, bool interpretDirectionAsUnwarped, float stylePatternScaleFactor, float endPlatesSize_relToViewportHeight, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.direction = direction; + this.relaxedLength_relToViewportHeight = relaxedLength_relToViewportHeight; + this.relaxedColor = relaxedColor; + this.style = style; + this.stretchFactor_forStretchedTensionColor = stretchFactor_forStretchedTensionColor; + this.color_forStretchedTension = color_forStretchedTension; + this.stretchFactor_forSqueezedTensionColor = stretchFactor_forSqueezedTensionColor; + this.color_forSqueezedTension = color_forSqueezedTension; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.alphaOfReferenceLengthDisplay = alphaOfReferenceLengthDisplay; + this.interpretDirectionAsUnwarped = interpretDirectionAsUnwarped; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceLineUnderTension + { + public Camera targetCamera; + public Vector2 start; + public Vector2 end; + public float relaxedLength_relToViewportHeight; + public Color relaxedColor; + public DrawBasics.LineStyle style; + public float stretchFactor_forStretchedTensionColor; + public Color color_forStretchedTension; + public float stretchFactor_forSqueezedTensionColor; + public Color color_forSqueezedTension; + public float width_relToViewportHeight; + public string text; + public float alphaOfReferenceLengthDisplay; + public float stylePatternScaleFactor; + public float endPlatesSize_relToViewportHeight; + public float enlargeSmallTextToThisMinRelTextSize; + public float durationInSec; + public ScreenspaceLineUnderTension(Camera targetCamera, Vector2 start, Vector2 end, float relaxedLength_relToViewportHeight, Color relaxedColor, DrawBasics.LineStyle style, float stretchFactor_forStretchedTensionColor, Color color_forStretchedTension, float stretchFactor_forSqueezedTensionColor, Color color_forSqueezedTension, float width_relToViewportHeight, string text, float alphaOfReferenceLengthDisplay, float stylePatternScaleFactor, float endPlatesSize_relToViewportHeight, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.start = start; + this.end = end; + this.relaxedLength_relToViewportHeight = relaxedLength_relToViewportHeight; + this.relaxedColor = relaxedColor; + this.style = style; + this.stretchFactor_forStretchedTensionColor = stretchFactor_forStretchedTensionColor; + this.color_forStretchedTension = color_forStretchedTension; + this.stretchFactor_forSqueezedTensionColor = stretchFactor_forSqueezedTensionColor; + this.color_forSqueezedTension = color_forSqueezedTension; + this.width_relToViewportHeight = width_relToViewportHeight; + this.text = text; + this.alphaOfReferenceLengthDisplay = alphaOfReferenceLengthDisplay; + this.stylePatternScaleFactor = stylePatternScaleFactor; + this.endPlatesSize_relToViewportHeight = endPlatesSize_relToViewportHeight; + this.enlargeSmallTextToThisMinRelTextSize = enlargeSmallTextToThisMinRelTextSize; + this.durationInSec = durationInSec; + } + } + + public struct ScreenspaceVisualizeAutomaticCameraForDrawing + { + public bool visualizeFrustum; + public bool logPositionToConsole; + public Color color; + public float durationInSec; + public ScreenspaceVisualizeAutomaticCameraForDrawing(bool visualizeFrustum, bool logPositionToConsole, Color color, float durationInSec) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.visualizeFrustum = visualizeFrustum; + this.logPositionToConsole = logPositionToConsole; + this.color = color; + this.durationInSec = durationInSec; + } + } + + public struct DrawScreenspaceChart + { + public Camera targetCamera; + public bool chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight; + public float durationInSec; + public ChartDrawing concernedChartDrawing; //-> additional member that deviates from the normal pattern inside this script file, because charts are instances, not static fields + public DrawScreenspaceChart(Camera targetCamera, bool chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight, float durationInSec, ChartDrawing concernedChartDrawing) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight = chartWidth_isDefinedRelTo_cameraWidth_notCameraHeight; + this.durationInSec = durationInSec; + this.concernedChartDrawing = concernedChartDrawing; + } + } + + public struct DrawScreenspacePieChart + { + public Camera targetCamera; + public bool chartSize_isDefinedRelTo_cameraWidth_notCameraHeight; + public float durationInSec; + public PieChartDrawing concernedPieChartDrawing; //-> additional member that deviates from the normal pattern inside this script file, because charts are instances, not static fields + + public DrawScreenspacePieChart(Camera targetCamera, bool chartSize_isDefinedRelTo_cameraWidth_notCameraHeight, float durationInSec, PieChartDrawing concernedPieChartDrawing) + { + DrawXXL_LinesManager.instance.atLeastOneScreenspaceLineHasBeenSheduledToLateInsideLateUpdate = true; + + this.targetCamera = targetCamera; + this.chartSize_isDefinedRelTo_cameraWidth_notCameraHeight = chartSize_isDefinedRelTo_cameraWidth_notCameraHeight; + this.durationInSec = durationInSec; + this.concernedPieChartDrawing = concernedPieChartDrawing; + } + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/ScreenspaceShedulingStrucs.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/ScreenspaceShedulingStrucs.cs.meta new file mode 100644 index 0000000..024f04d --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/ScreenspaceShedulingStrucs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3ddab6e6348aa05488dacb977763cebf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Bezier.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Bezier.cs new file mode 100644 index 0000000..1fd33dd --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Bezier.cs @@ -0,0 +1,863 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_Bezier + { + public static void BezierSegmentQuadratic(bool is2D, Vector3 startPosition, Vector3 endPosition, Vector3 controlPosInBetween, Color color, string text, float width, int straightSubDivisions, float textSize, bool drawIngameWarningTextForZeroExtent, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (drawIngameWarningTextForZeroExtent) + { + if (UtilitiesDXXL_Math.CheckIf_vectorsAreApproximatelyEqual(startPosition, endPosition, controlPosInBetween)) + { + if (is2D) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(startPosition, "[ BezierQuadratic2D with extent of 0]
" + text, color, width, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_DrawBasics.PointFallback(startPosition, "[ BezierQuadratic with extent of 0]
" + text, color, width, durationInSec, hiddenByNearerObjects); + } + return; + } + } + + straightSubDivisions = Mathf.Clamp(straightSubDivisions, 4, 1000); + InternalDXXL_Plane preferredAmplitudeDir = is2D ? UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero : null; + Vector3 prevPointOnBezierCurve = startPosition; + float progress0to1_perStraightSubDivision = 1.0f / (float)straightSubDivisions; + for (int i = 1; i < straightSubDivisions; i++) + { + float progress_0to1 = progress0to1_perStraightSubDivision * i; + float oneMinusProgress0to1 = 1.0f - progress_0to1; + float factor1 = oneMinusProgress0to1 * oneMinusProgress0to1; + float factor2 = 2.0f * oneMinusProgress0to1 * progress_0to1; + float factor3 = progress_0to1 * progress_0to1; + Vector3 currPointOnBezierCurve = factor1 * startPosition + factor2 * controlPosInBetween + factor3 * endPosition; + UtilitiesDXXL_DrawBasics.Line(prevPointOnBezierCurve, currPointOnBezierCurve, color, width, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, preferredAmplitudeDir, is2D, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + prevPointOnBezierCurve = currPointOnBezierCurve; + } + UtilitiesDXXL_DrawBasics.Line(prevPointOnBezierCurve, endPosition, color, width, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, preferredAmplitudeDir, is2D, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + + if (text != null && text != "") + { + if (is2D) + { + UtilitiesDXXL_Text.Write2DFramed(text, startPosition, color, textSize, default(Vector2), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, startPosition.z, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Text.WriteFramed(text, startPosition, color, textSize, default(Vector3), default(Vector3), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + } + } + + public static void BezierSegmentCubic(bool is2D, Vector3 startPosition, Vector3 endPosition, Vector3 controlPosOfStartDirection, Vector3 controlPosOfEndDirection, Color color, string text, float width, int straightSubDivisions, float textSize, bool drawIngameWarningTextForZeroExtent, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (drawIngameWarningTextForZeroExtent) + { + if (UtilitiesDXXL_Math.CheckIf_vectorsAreApproximatelyEqual(startPosition, endPosition, controlPosOfStartDirection, controlPosOfEndDirection)) + { + if (is2D) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(startPosition, "[ BezierCubic2D with extent of 0]
" + text, color, width, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_DrawBasics.PointFallback(startPosition, "[ BezierCubic with extent of 0]
" + text, color, width, durationInSec, hiddenByNearerObjects); + } + return; + } + } + + straightSubDivisions = Mathf.Clamp(straightSubDivisions, 4, 1000); + InternalDXXL_Plane preferredAmplitudeDir = is2D ? UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero : null; + Vector3 prevPointOnBezierCurve = startPosition; + float progress0to1_perStraightSubDivision = 1.0f / (float)straightSubDivisions; + for (int i = 1; i < straightSubDivisions; i++) + { + float progress_0to1 = progress0to1_perStraightSubDivision * i; + float progress_0to1_sqr = progress_0to1 * progress_0to1; + float oneMinusProgress0to1 = 1.0f - progress_0to1; + float oneMinusProgress0to1_sqr = oneMinusProgress0to1 * oneMinusProgress0to1; + float factor1 = oneMinusProgress0to1 * oneMinusProgress0to1_sqr; + float factor2 = 3.0f * oneMinusProgress0to1_sqr * progress_0to1; + float factor3 = 3.0f * oneMinusProgress0to1 * progress_0to1_sqr; + float factor4 = progress_0to1 * progress_0to1_sqr; + Vector3 currPointOnBezierCurve = factor1 * startPosition + factor2 * controlPosOfStartDirection + factor3 * controlPosOfEndDirection + factor4 * endPosition; + UtilitiesDXXL_DrawBasics.Line(prevPointOnBezierCurve, currPointOnBezierCurve, color, width, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, preferredAmplitudeDir, is2D, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + prevPointOnBezierCurve = currPointOnBezierCurve; + } + UtilitiesDXXL_DrawBasics.Line(prevPointOnBezierCurve, endPosition, color, width, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, preferredAmplitudeDir, is2D, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + + if (text != null && text != "") + { + if (is2D) + { + UtilitiesDXXL_Text.Write2DFramed(text, startPosition, color, textSize, default(Vector2), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, startPosition.z, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Text.WriteFramed(text, startPosition, color, textSize, default(Vector3), default(Vector3), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + } + } + + public delegate Vector3 FlexibleGetPosAtIndex(T collection, int i_whereToObtain, out bool itemIsNull); + public delegate Vector3 FlexibleGetDirectionControlPosOfTransform(T collection, int i_transformWhereToObtain); + public static Vector3 GetPositionsFromGameObjectsArray(GameObject[] points, int i_whereToObtain, out bool itemIsNull) + { + if (points[i_whereToObtain] == null) + { + itemIsNull = true; + return Vector3.zero; + } + else + { + itemIsNull = false; + return points[i_whereToObtain].transform.position; + } + } + public static Vector3 GetPositionsFromGameObjectsList(List points, int i_whereToObtain, out bool itemIsNull) + { + if (points[i_whereToObtain] == null) + { + itemIsNull = true; + return Vector3.zero; + } + else + { + itemIsNull = false; + return points[i_whereToObtain].transform.position; + } + } + + public static Vector3 GetPositionsFromTransformsArray(Transform[] points, int i_whereToObtain, out bool itemIsNull) + { + if (points[i_whereToObtain] == null) + { + itemIsNull = true; + return Vector3.zero; + } + else + { + itemIsNull = false; + return points[i_whereToObtain].position; + } + } + public static Vector3 GetPositionsFromTransformsList(List points, int i_whereToObtain, out bool itemIsNull) + { + if (points[i_whereToObtain] == null) + { + itemIsNull = true; + return Vector3.zero; + } + else + { + itemIsNull = false; + return points[i_whereToObtain].position; + } + } + + public static Vector3 GetPositionsFromVector3Array(Vector3[] points, int i_whereToObtain, out bool itemIsNull) + { + Vector3 vectorAtRequestedPos = points[i_whereToObtain]; + if (UtilitiesDXXL_Math.FloatIsInvalid(vectorAtRequestedPos.x) || UtilitiesDXXL_Math.FloatIsInvalid(vectorAtRequestedPos.y) || UtilitiesDXXL_Math.FloatIsInvalid(vectorAtRequestedPos.z)) + { + itemIsNull = true; + return Vector3.zero; + } + else + { + itemIsNull = false; + return points[i_whereToObtain]; + } + } + public static Vector3 GetPositionsFromVector3List(List points, int i_whereToObtain, out bool itemIsNull) + { + Vector3 vectorAtRequestedPos = points[i_whereToObtain]; + if (UtilitiesDXXL_Math.FloatIsInvalid(vectorAtRequestedPos.x) || UtilitiesDXXL_Math.FloatIsInvalid(vectorAtRequestedPos.y) || UtilitiesDXXL_Math.FloatIsInvalid(vectorAtRequestedPos.z)) + { + itemIsNull = true; + return Vector3.zero; + } + else + { + itemIsNull = false; + return points[i_whereToObtain]; + } + } + + public static Vector3 GetForwardControlPosFromGameObjectsArray(GameObject[] points, int i_whereToObtain) + { + return (points[i_whereToObtain].transform.position + points[i_whereToObtain].transform.forward * points[i_whereToObtain].transform.localScale.z); + } + public static Vector3 GetForwardControlPosFromGameObjectsList(List points, int i_whereToObtain) + { + return (points[i_whereToObtain].transform.position + points[i_whereToObtain].transform.forward * points[i_whereToObtain].transform.localScale.z); + } + + public static Vector3 GetForwardControlPosFromTransformsArray(Transform[] points, int i_whereToObtain) + { + return (points[i_whereToObtain].position + points[i_whereToObtain].forward * points[i_whereToObtain].localScale.z); + } + public static Vector3 GetForwardControlPosFromTransformsList(List points, int i_whereToObtain) + { + return (points[i_whereToObtain].position + points[i_whereToObtain].forward * points[i_whereToObtain].localScale.z); + } + + + public static Vector3 GetBackwardControlPosFromGameObjectsArray(GameObject[] points, int i_whereToObtain) + { + return (points[i_whereToObtain].transform.position - points[i_whereToObtain].transform.forward * points[i_whereToObtain].transform.localScale.y); + } + public static Vector3 GetBackwardControlPosFromGameObjectsList(List points, int i_whereToObtain) + { + return (points[i_whereToObtain].transform.position - points[i_whereToObtain].transform.forward * points[i_whereToObtain].transform.localScale.y); + } + + public static Vector3 GetBackwardControlPosFromTransformsArray(Transform[] points, int i_whereToObtain) + { + return (points[i_whereToObtain].position - points[i_whereToObtain].forward * points[i_whereToObtain].localScale.y); + } + public static Vector3 GetBackwardControlPosFromTransformsList(List points, int i_whereToObtain) + { + return (points[i_whereToObtain].position - points[i_whereToObtain].forward * points[i_whereToObtain].localScale.y); + } + + public static Vector3 GetPositions3DFromGameObjectsArray_2D(GameObject[] points, int i_whereToObtain, out bool itemIsNull) + { + if (points[i_whereToObtain] == null) + { + itemIsNull = true; + return new Vector3(0.0f, 0.0f, currentZPos); + } + else + { + itemIsNull = false; + return new Vector3(points[i_whereToObtain].transform.position.x, points[i_whereToObtain].transform.position.y, currentZPos); + } + } + public static Vector3 GetPositions3DFromGameObjectsList_2D(List points, int i_whereToObtain, out bool itemIsNull) + { + if (points[i_whereToObtain] == null) + { + itemIsNull = true; + return new Vector3(0.0f, 0.0f, currentZPos); + } + else + { + itemIsNull = false; + return new Vector3(points[i_whereToObtain].transform.position.x, points[i_whereToObtain].transform.position.y, currentZPos); + } + } + + public static Vector3 GetPositions3DFromTransformsArray_2D(Transform[] points, int i_whereToObtain, out bool itemIsNull) + { + if (points[i_whereToObtain] == null) + { + itemIsNull = true; + return new Vector3(0.0f, 0.0f, currentZPos); + } + else + { + itemIsNull = false; + return new Vector3(points[i_whereToObtain].position.x, points[i_whereToObtain].position.y, currentZPos); + } + } + public static Vector3 GetPositions3DFromTransformsList_2D(List points, int i_whereToObtain, out bool itemIsNull) + { + if (points[i_whereToObtain] == null) + { + itemIsNull = true; + return new Vector3(0.0f, 0.0f, currentZPos); + } + else + { + itemIsNull = false; + return new Vector3(points[i_whereToObtain].position.x, points[i_whereToObtain].position.y, currentZPos); + } + } + + public static Vector3 GetPositions3DFromVector2Array_2D(Vector2[] points, int i_whereToObtain, out bool itemIsNull) + { + Vector2 vectorAtRequestedPos = points[i_whereToObtain]; + if (UtilitiesDXXL_Math.FloatIsInvalid(vectorAtRequestedPos.x) || UtilitiesDXXL_Math.FloatIsInvalid(vectorAtRequestedPos.y)) + { + itemIsNull = true; + return Vector2.zero; + } + else + { + itemIsNull = false; + return new Vector3(points[i_whereToObtain].x, points[i_whereToObtain].y, currentZPos); + } + } + public static Vector3 GetPositions3DFromVector2List_2D(List points, int i_whereToObtain, out bool itemIsNull) + { + Vector2 vectorAtRequestedPos = points[i_whereToObtain]; + if (UtilitiesDXXL_Math.FloatIsInvalid(vectorAtRequestedPos.x) || UtilitiesDXXL_Math.FloatIsInvalid(vectorAtRequestedPos.y)) + { + itemIsNull = true; + return Vector2.zero; + } + else + { + itemIsNull = false; + return new Vector3(points[i_whereToObtain].x, points[i_whereToObtain].y, currentZPos); + } + } + + public static Vector3 GetForwardControlPos3DFromGameObjectsArray_2D(GameObject[] points, int i_whereToObtain) + { + Vector3 pos3D_notYetForcedToDrawZPos = (points[i_whereToObtain].transform.position + points[i_whereToObtain].transform.right * points[i_whereToObtain].transform.localScale.x); + return new Vector3(pos3D_notYetForcedToDrawZPos.x, pos3D_notYetForcedToDrawZPos.y, currentZPos); + + } + public static Vector3 GetForwardControlPos3DFromGameObjectsList_2D(List points, int i_whereToObtain) + { + Vector3 pos3D_notYetForcedToDrawZPos = (points[i_whereToObtain].transform.position + points[i_whereToObtain].transform.right * points[i_whereToObtain].transform.localScale.x); + return new Vector3(pos3D_notYetForcedToDrawZPos.x, pos3D_notYetForcedToDrawZPos.y, currentZPos); + } + + public static Vector3 GetForwardControlPos3DFromTransformsArray_2D(Transform[] points, int i_whereToObtain) + { + Vector3 pos3D_notYetForcedToDrawZPos = (points[i_whereToObtain].position + points[i_whereToObtain].right * points[i_whereToObtain].localScale.x); + return new Vector3(pos3D_notYetForcedToDrawZPos.x, pos3D_notYetForcedToDrawZPos.y, currentZPos); + } + public static Vector3 GetForwardControlPos3DFromTransformsList_2D(List points, int i_whereToObtain) + { + Vector3 pos3D_notYetForcedToDrawZPos = (points[i_whereToObtain].position + points[i_whereToObtain].right * points[i_whereToObtain].localScale.x); + return new Vector3(pos3D_notYetForcedToDrawZPos.x, pos3D_notYetForcedToDrawZPos.y, currentZPos); + } + + public static Vector3 GetBackwardControlPos3DFromGameObjectsArray_2D(GameObject[] points, int i_whereToObtain) + { + Vector3 pos3D_notYetForcedToDrawZPos = (points[i_whereToObtain].transform.position - points[i_whereToObtain].transform.right * points[i_whereToObtain].transform.localScale.y); + return new Vector3(pos3D_notYetForcedToDrawZPos.x, pos3D_notYetForcedToDrawZPos.y, currentZPos); + } + public static Vector3 GetBackwardControlPos3DFromGameObjectsList_2D(List points, int i_whereToObtain) + { + Vector3 pos3D_notYetForcedToDrawZPos = (points[i_whereToObtain].transform.position - points[i_whereToObtain].transform.right * points[i_whereToObtain].transform.localScale.y); + return new Vector3(pos3D_notYetForcedToDrawZPos.x, pos3D_notYetForcedToDrawZPos.y, currentZPos); + } + + public static Vector3 GetBackwardControlPos3DFromTransformsArray_2D(Transform[] points, int i_whereToObtain) + { + Vector3 pos3D_notYetForcedToDrawZPos = (points[i_whereToObtain].position - points[i_whereToObtain].right * points[i_whereToObtain].localScale.y); + return new Vector3(pos3D_notYetForcedToDrawZPos.x, pos3D_notYetForcedToDrawZPos.y, currentZPos); + } + public static Vector3 GetBackwardControlPos3DFromTransformsList_2D(List points, int i_whereToObtain) + { + Vector3 pos3D_notYetForcedToDrawZPos = (points[i_whereToObtain].position - points[i_whereToObtain].right * points[i_whereToObtain].localScale.y); + return new Vector3(pos3D_notYetForcedToDrawZPos.x, pos3D_notYetForcedToDrawZPos.y, currentZPos); + } + + static float currentZPos; + public static void BezierSpline(bool is2D, float customZPos_for2D, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, FlexibleGetDirectionControlPosOfTransform GetForwardControlPos, FlexibleGetDirectionControlPosOfTransform GetBackwardControlPos, int lengthOfCollection, Color color, DrawBasics.BezierPosInterpretation interpretationOfPointsCollection, string text, float width, bool closeGapFromEndToStart, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 textPosition; + bool textPosition_hasBeenAssigned; + currentZPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(customZPos_for2D); + switch (interpretationOfPointsCollection) + { + case DrawBasics.BezierPosInterpretation.start_control1_control2_endIsNextStart: + textPosition = DrawSpline_case_start_control1_control2_endIsNextStart(is2D, out textPosition_hasBeenAssigned, ref text, bezierPointCollection, GetPos, lengthOfCollection, color, interpretationOfPointsCollection, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + break; + + case DrawBasics.BezierPosInterpretation.start_control1_endIsNextStart: + textPosition = DrawSpline_case_start_control1_endIsNextStart(is2D, out textPosition_hasBeenAssigned, ref text, bezierPointCollection, GetPos, lengthOfCollection, color, interpretationOfPointsCollection, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + break; + + case DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsAligned: + textPosition = DrawSpline_case_onlySegmentStartPoints_backwardForwardIsAligned(is2D, out textPosition_hasBeenAssigned, bezierPointCollection, GetPos, GetForwardControlPos, GetBackwardControlPos, lengthOfCollection, color, interpretationOfPointsCollection, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + break; + + case DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsMirrored: + textPosition = DrawSpline_case_onlySegmentStartPoints_backwardForwardIsMirrored(is2D, out textPosition_hasBeenAssigned, bezierPointCollection, GetPos, GetForwardControlPos, lengthOfCollection, color, interpretationOfPointsCollection, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + break; + + case DrawBasics.BezierPosInterpretation.onlySegmentStartPoints_backwardForwardIsKinked: + textPosition = DrawSpline_case_onlySegmentStartPoints_backwardForwardIsKinked(is2D, out textPosition_hasBeenAssigned, bezierPointCollection, GetPos, GetForwardControlPos, lengthOfCollection, color, interpretationOfPointsCollection, width, closeGapFromEndToStart, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + break; + + default: + textPosition = Vector3.zero; + textPosition_hasBeenAssigned = false; + Debug.LogError("BezierPosInterpretation of '" + interpretationOfPointsCollection + "' not implemented -> DrawBezierSpline not executed."); + break; + } + + if (text != null && text != "") + { + if (textPosition_hasBeenAssigned) + { + UtilitiesDXXL_Text.WriteFramed(text, textPosition, color, textSize, default(Vector3), default(Vector3), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + else + { + Debug.Log("No ingame position for the text of the BezierSpline could be appointed -> Fallback to log console. The text is: " + text); + } + } + } + + static Vector3 DrawSpline_case_start_control1_control2_endIsNextStart(bool is2D, out bool textPosition_hasAlreadyBeenAssigned, ref string text, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, int lengthOfCollection, Color color, DrawBasics.BezierPosInterpretation interpretationOfPointsCollection, float width, bool closeGapFromEndToStart, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + textPosition_hasAlreadyBeenAssigned = false; + Vector3 textPosition = Vector3.zero; + + if (lengthOfCollection < 3) + { + Debug.LogError("Bezier spline with BezierPosInterpretation of '" + interpretationOfPointsCollection + "' needs at least 3 control points, but the specified collection has only " + lengthOfCollection + " -> drawing skipped."); + } + else + { + bool splineHasAlreadyCommunicatedANullItem = false; //preventing log spam and many drawn lines (for multiple fallback texts) + int i_startOfCurrSegment = 0; + int i_endOfCurrSegment = i_startOfCurrSegment + 3; + int maxNumberOfWhileLoops = 10000; //prevent freeze/endless loops + int i_whileLoop = 0; + while (i_endOfCurrSegment < lengthOfCollection) + { + TryDrawCubicSegment_ofSplineCase_start_control1_control2_endIsNextStart(is2D, i_startOfCurrSegment, i_endOfCurrSegment, bezierPointCollection, GetPos, i_whileLoop, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + i_startOfCurrSegment = i_endOfCurrSegment; + i_endOfCurrSegment = i_startOfCurrSegment + 3; + + i_whileLoop++; + if (i_whileLoop > maxNumberOfWhileLoops) + { + Debug.LogError("Too many Bezier Segments (more than " + maxNumberOfWhileLoops + "). Drawing aborted."); + break; + } + } + + if ((i_startOfCurrSegment + 2) < lengthOfCollection) + { + //two splineDefiningCollectionPoints more than '3 points per segment (+1 final)' scheme: + //->one to little for another segment + if (closeGapFromEndToStart) + { + TryDrawCubicSegment_ofSplineCase_start_control1_control2_endIsNextStart(is2D, i_startOfCurrSegment, 0, bezierPointCollection, GetPos, i_whileLoop, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + else + { + //Fallback to quadratic bezier at spline end: + TryDrawQuadraticSegment_ofSplineCase_start_control1_end(is2D, i_startOfCurrSegment, i_startOfCurrSegment + 2, bezierPointCollection, GetPos, i_whileLoop, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + if (lengthOfCollection > 3) + { + text = "[ points collection length is 2 too long for the '3 points per segment (+1 final)' scheme
-> last segment falls back from cubic to quadratic bezier]
" + text; + } + } + + if (lengthOfCollection == 3) + { + text = "[ points collection length is 3 but the first segment needs 4
-> the single segment falls back from cubic to quadratic bezier]
" + text; + } + } + else + { + if ((i_startOfCurrSegment + 1) < lengthOfCollection) + { + //one splineDefiningCollectionPoint more than '3 points per segment (+1 final)' scheme: + //->two to little for another segment + if (closeGapFromEndToStart) + { + TryDrawQuadraticSegment_ofSplineCase_start_control1_end(is2D, i_startOfCurrSegment, 0, bezierPointCollection, GetPos, i_whileLoop, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + else + { + text = "[ points collection length is 1 too long for the '3 points per segment (+1 final)' scheme
-> last point discarded]
" + text; + } + } + else + { + if (i_startOfCurrSegment < lengthOfCollection) + { + //bezierPointCollection.length perfectly fits the '3 points per segment (+1 final)' scheme + //-> no surplus points available + if (closeGapFromEndToStart) + { + TryDrawCubicSegment_asGapCloserBetweenSplineEndAndStart(is2D, i_startOfCurrSegment, bezierPointCollection, GetPos, i_whileLoop, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + } + } + } + } + return textPosition; + } + + static void TryDrawCubicSegment_ofSplineCase_start_control1_control2_endIsNextStart(bool is2D, int i_ofSegmentStartPos_insideBezierPointsCollection, int i_ofSegmentEndPos_insideBezierPointsCollection, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, int i_whileLoop, ref bool textPosition_hasAlreadyBeenAssigned, ref Vector3 textPosition, ref bool splineHasAlreadyCommunicatedANullItem, Color color, float width, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 fallbackPositionOfSegment = Vector3.zero; + bool fallbackPositionOfSegment_hasAlreadyBeenAssigned = false; + bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid = false; + + Vector3 startPosition = TryGetPosFromBezierPointCollection(out bool startPosItemIsNull, bezierPointCollection, GetPos, i_ofSegmentStartPos_insideBezierPointsCollection, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(startPosItemIsNull, startPosition, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + + Vector3 controlPosOfStartDirection = TryGetPosFromBezierPointCollection(bezierPointCollection, GetPos, i_ofSegmentStartPos_insideBezierPointsCollection + 1, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + Vector3 controlPosOfEndDirection = TryGetPosFromBezierPointCollection(bezierPointCollection, GetPos, i_ofSegmentStartPos_insideBezierPointsCollection + 2, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + + Vector3 endPosition = TryGetPosFromBezierPointCollection(out bool endPosItemIsNull, bezierPointCollection, GetPos, i_ofSegmentEndPos_insideBezierPointsCollection, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(endPosItemIsNull, endPosition, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + + TryDrawCubicBezierSegment(is2D, startPosition, endPosition, controlPosOfStartDirection, controlPosOfEndDirection, oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid, ref splineHasAlreadyCommunicatedANullItem, i_whileLoop, fallbackPositionOfSegment_hasAlreadyBeenAssigned, fallbackPositionOfSegment, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + static void TryDrawQuadraticSegment_ofSplineCase_start_control1_end(bool is2D, int i_ofSegmentStartPos_insideBezierPointsCollection, int i_ofSegmentEndPos_insideBezierPointsCollection, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, int i_whileLoop, ref bool textPosition_hasAlreadyBeenAssigned, ref Vector3 textPosition, ref bool splineHasAlreadyCommunicatedANullItem, Color color, float width, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 fallbackPositionOfSegment = Vector3.zero; + bool fallbackPositionOfSegment_hasAlreadyBeenAssigned = false; + bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid = false; + + Vector3 startPosition = TryGetPosFromBezierPointCollection(out bool startPosItemIsNullOrInvalid, bezierPointCollection, GetPos, i_ofSegmentStartPos_insideBezierPointsCollection, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(startPosItemIsNullOrInvalid, startPosition, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + + Vector3 controlPosInBetween = TryGetPosFromBezierPointCollection(bezierPointCollection, GetPos, i_ofSegmentStartPos_insideBezierPointsCollection + 1, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + + Vector3 endPosition = TryGetPosFromBezierPointCollection(out bool endPosItemIsNullOrInvalid, bezierPointCollection, GetPos, i_ofSegmentEndPos_insideBezierPointsCollection, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(endPosItemIsNullOrInvalid, endPosition, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + + TryDrawQuadraticBezierSegment(is2D, startPosition, endPosition, controlPosInBetween, oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid, ref splineHasAlreadyCommunicatedANullItem, i_whileLoop, fallbackPositionOfSegment_hasAlreadyBeenAssigned, fallbackPositionOfSegment, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + static void TryDrawCubicSegment_asGapCloserBetweenSplineEndAndStart(bool is2D, int i_lastSlotOfBezierPointsCollection, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, int i_whileLoop, ref bool textPosition_hasAlreadyBeenAssigned, ref Vector3 textPosition, ref bool splineHasAlreadyCommunicatedANullItem, Color color, float width, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 fallbackPositionOfSegment = Vector3.zero; + bool fallbackPositionOfSegment_hasAlreadyBeenAssigned = false; + bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid = false; + + Vector3 gapClosingSegmentsStartPosition_isSplineEndPos = TryGetPosFromBezierPointCollection(out bool segmentsStartPosItemIsNull, bezierPointCollection, GetPos, i_lastSlotOfBezierPointsCollection, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(segmentsStartPosItemIsNull, gapClosingSegmentsStartPosition_isSplineEndPos, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + + Vector3 backwardControlPosOfSplinesEndPos = TryGetPosFromBezierPointCollection(out bool backwardControlPosOfSplinesEndPos_isNull, bezierPointCollection, GetPos, i_lastSlotOfBezierPointsCollection - 1, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + Vector3 controlPosOfSegmentStartDirection = Vector3.zero; + if (backwardControlPosOfSplinesEndPos_isNull == false) + { + Vector3 splinesEndPos_toHisBackwardControlPos = backwardControlPosOfSplinesEndPos - gapClosingSegmentsStartPosition_isSplineEndPos; + controlPosOfSegmentStartDirection = gapClosingSegmentsStartPosition_isSplineEndPos - splinesEndPos_toHisBackwardControlPos; + } + + Vector3 gapClosingSegmentsEndPosition_isSplineStartPos = TryGetPosFromBezierPointCollection(out bool segmentsEndPosItemIsNull, bezierPointCollection, GetPos, 0, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(segmentsEndPosItemIsNull, gapClosingSegmentsEndPosition_isSplineStartPos, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + + Vector3 forwardControlPosOfSplinesStartPos = TryGetPosFromBezierPointCollection(out bool forwardControlPosOfSplinesStartPos_isNull, bezierPointCollection, GetPos, 1, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + Vector3 controlPosOfSegmentEndDirection = Vector3.zero; + if (forwardControlPosOfSplinesStartPos_isNull == false) + { + Vector3 splinesStartPos_toHisForwardControlPos = forwardControlPosOfSplinesStartPos - gapClosingSegmentsEndPosition_isSplineStartPos; + controlPosOfSegmentEndDirection = gapClosingSegmentsEndPosition_isSplineStartPos - splinesStartPos_toHisForwardControlPos; + } + + TryDrawCubicBezierSegment(is2D, gapClosingSegmentsStartPosition_isSplineEndPos, gapClosingSegmentsEndPosition_isSplineStartPos, controlPosOfSegmentStartDirection, controlPosOfSegmentEndDirection, oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid, ref splineHasAlreadyCommunicatedANullItem, i_whileLoop, fallbackPositionOfSegment_hasAlreadyBeenAssigned, fallbackPositionOfSegment, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + static Vector3 DrawSpline_case_start_control1_endIsNextStart(bool is2D, out bool textPosition_hasAlreadyBeenAssigned, ref string text, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, int lengthOfCollection, Color color, DrawBasics.BezierPosInterpretation interpretationOfPointsCollection, float width, bool closeGapFromEndToStart, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + textPosition_hasAlreadyBeenAssigned = false; + Vector3 textPosition = Vector3.zero; + + if (lengthOfCollection < 3) + { + Debug.LogError("Bezier spline with BezierPosInterpretation of '" + interpretationOfPointsCollection + "' needs at least 3 control points, but the specified collection has only " + lengthOfCollection + " -> drawing skipped."); + } + else + { + bool splineHasAlreadyCommunicatedANullItem = false; //preventing log spam and many drawn lines (for multiple fallback texts) + int i_startOfCurrSegment = 0; + int i_endOfCurrSegment = i_startOfCurrSegment + 2; + int maxNumberOfWhileLoops = 10000; //prevent freeze/endless loops + int i_whileLoop = 0; + while (i_endOfCurrSegment < lengthOfCollection) + { + TryDrawQuadraticSegment_ofSplineCase_start_control1_end(is2D, i_startOfCurrSegment, i_endOfCurrSegment, bezierPointCollection, GetPos, i_whileLoop, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + + i_startOfCurrSegment = i_endOfCurrSegment; + i_endOfCurrSegment = i_startOfCurrSegment + 2; + + i_whileLoop++; + if (i_whileLoop > maxNumberOfWhileLoops) + { + Debug.LogError("Too many Bezier Segments (more than " + maxNumberOfWhileLoops + "). Drawing aborted."); + break; + } + } + + if ((i_startOfCurrSegment + 1) < lengthOfCollection) + { + //one splineDefiningCollectionPoint more than '2 points per segment (+1 final)' scheme: + //->one to little for another segment + if (closeGapFromEndToStart) + { + TryDrawQuadraticSegment_ofSplineCase_start_control1_end(is2D, i_startOfCurrSegment, 0, bezierPointCollection, GetPos, i_whileLoop, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + else + { + text = "[ points collection length is 1 too long for the '2 points per segment (+1 final)' scheme
-> last point discarded]
" + text; + } + } + else + { + if (i_startOfCurrSegment < lengthOfCollection) + { + //bezierPointCollection.length perfectly fits the '3 points per segment (+1 final)' scheme + //-> no surplus points available + if (closeGapFromEndToStart) + { + TryDrawQuadraticSegment_asGapCloserBetweenSplineEndAndStart(is2D, i_startOfCurrSegment, bezierPointCollection, GetPos, i_whileLoop, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + } + } + } + return textPosition; + } + + static void TryDrawQuadraticSegment_asGapCloserBetweenSplineEndAndStart(bool is2D, int i_lastSlotOfBezierPointsCollection, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, int i_whileLoop, ref bool textPosition_hasAlreadyBeenAssigned, ref Vector3 textPosition, ref bool splineHasAlreadyCommunicatedANullItem, Color color, float width, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 fallbackPositionOfSegment = Vector3.zero; + bool fallbackPositionOfSegment_hasAlreadyBeenAssigned = false; + bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid = false; + + Vector3 gapClosingSegmentsStartPosition_isSplineEndPos = TryGetPosFromBezierPointCollection(out bool segmentsStartPosItemIsNull, bezierPointCollection, GetPos, i_lastSlotOfBezierPointsCollection, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(segmentsStartPosItemIsNull, gapClosingSegmentsStartPosition_isSplineEndPos, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + + Vector3 backwardControlPosOfSplinesEndPos = TryGetPosFromBezierPointCollection(out bool backwardControlPosOfSplinesEndPos_isNull, bezierPointCollection, GetPos, i_lastSlotOfBezierPointsCollection - 1, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + Vector3 controlPosOfSegmentStartDirection = Vector3.zero; + if (backwardControlPosOfSplinesEndPos_isNull == false) + { + Vector3 splinesEndPos_toHisBackwardControlPos = backwardControlPosOfSplinesEndPos - gapClosingSegmentsStartPosition_isSplineEndPos; + controlPosOfSegmentStartDirection = gapClosingSegmentsStartPosition_isSplineEndPos - splinesEndPos_toHisBackwardControlPos; + } + + Vector3 gapClosingSegmentsEndPosition_isSplineStartPos = TryGetPosFromBezierPointCollection(out bool segmentsEndPosItemIsNull, bezierPointCollection, GetPos, 0, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(segmentsEndPosItemIsNull, gapClosingSegmentsEndPosition_isSplineStartPos, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + + Vector3 forwardControlPosOfSplinesStartPos = TryGetPosFromBezierPointCollection(bezierPointCollection, GetPos, 1, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + + TryDrawQuadraticBezierSegment(is2D, gapClosingSegmentsStartPosition_isSplineEndPos, gapClosingSegmentsEndPosition_isSplineStartPos, controlPosOfSegmentStartDirection, oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid, ref splineHasAlreadyCommunicatedANullItem, i_whileLoop, fallbackPositionOfSegment_hasAlreadyBeenAssigned, fallbackPositionOfSegment, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + static Vector3 DrawSpline_case_onlySegmentStartPoints_backwardForwardIsAligned(bool is2D, out bool textPosition_hasAlreadyBeenAssigned, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, FlexibleGetDirectionControlPosOfTransform GetForwardControlPos, FlexibleGetDirectionControlPosOfTransform GetBackwardControlPos, int lengthOfCollection, Color color, DrawBasics.BezierPosInterpretation interpretationOfPointsCollection, float width, bool closeGapFromEndToStart, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + textPosition_hasAlreadyBeenAssigned = false; + Vector3 textPosition = Vector3.zero; + + if (lengthOfCollection < 2) + { + Debug.LogError("Bezier spline with BezierPosInterpretation of '" + interpretationOfPointsCollection + "' needs at least 2 control points, but the specified collection has only " + lengthOfCollection + " -> drawing skipped."); + } + else + { + bool splineHasAlreadyCommunicatedANullItem = false; //preventing log spam and many drawn lines (for multiple fallback texts) + for (int i_segmentEndPos = 1; i_segmentEndPos < lengthOfCollection; i_segmentEndPos++) + { + int i_segmentStartPos = i_segmentEndPos - 1; + TryDrawSegment_ofSplineCase_onlySegmentStartPoints_backwardForwardIsAligned(is2D, i_segmentStartPos, i_segmentEndPos, bezierPointCollection, GetPos, GetForwardControlPos, GetBackwardControlPos, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + if (closeGapFromEndToStart) + { + TryDrawSegment_ofSplineCase_onlySegmentStartPoints_backwardForwardIsAligned(is2D, lengthOfCollection - 1, 0, bezierPointCollection, GetPos, GetForwardControlPos, GetBackwardControlPos, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + } + return textPosition; + } + + static void TryDrawSegment_ofSplineCase_onlySegmentStartPoints_backwardForwardIsAligned(bool is2D, int i_segmentStartPos, int i_segmentEndPos, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, FlexibleGetDirectionControlPosOfTransform GetForwardControlPos, FlexibleGetDirectionControlPosOfTransform GetBackwardControlPos, ref bool textPosition_hasAlreadyBeenAssigned, ref Vector3 textPosition, ref bool splineHasAlreadyCommunicatedANullItem, Color color, float width, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 fallbackPositionOfSegment = Vector3.zero; + Vector3 controlPosOfEndDirection = Vector3.zero; + Vector3 controlPosOfStartDirection = Vector3.zero; + bool fallbackPositionOfSegment_hasAlreadyBeenAssigned = false; + bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid = false; + + Vector3 startPosition = TryGetPosFromBezierPointCollection(out bool startPosItemIsNullOrInvalid, bezierPointCollection, GetPos, i_segmentStartPos, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(startPosItemIsNullOrInvalid, startPosition, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + if (startPosItemIsNullOrInvalid == false) { controlPosOfStartDirection = GetForwardControlPos(bezierPointCollection, i_segmentStartPos); } + + Vector3 endPosition = TryGetPosFromBezierPointCollection(out bool endPosItemIsNullOrInvalid, bezierPointCollection, GetPos, i_segmentEndPos, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(endPosItemIsNullOrInvalid, endPosition, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + if (endPosItemIsNullOrInvalid == false) { controlPosOfEndDirection = GetBackwardControlPos(bezierPointCollection, i_segmentEndPos); } + + TryDrawCubicBezierSegment(is2D, startPosition, endPosition, controlPosOfStartDirection, controlPosOfEndDirection, oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid, ref splineHasAlreadyCommunicatedANullItem, i_segmentStartPos, fallbackPositionOfSegment_hasAlreadyBeenAssigned, fallbackPositionOfSegment, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + static Vector3 DrawSpline_case_onlySegmentStartPoints_backwardForwardIsMirrored(bool is2D, out bool textPosition_hasAlreadyBeenAssigned, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, FlexibleGetDirectionControlPosOfTransform GetForwardControlPos, int lengthOfCollection, Color color, DrawBasics.BezierPosInterpretation interpretationOfPointsCollection, float width, bool closeGapFromEndToStart, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + textPosition_hasAlreadyBeenAssigned = false; + Vector3 textPosition = Vector3.zero; + + if (lengthOfCollection < 2) + { + Debug.LogError("Bezier spline with BezierPosInterpretation of '" + interpretationOfPointsCollection + "' needs at least 2 control points, but the specified collection has only " + lengthOfCollection + " -> drawing skipped."); + } + else + { + bool splineHasAlreadyCommunicatedANullItem = false; //preventing log spam and many drawn lines (for multiple fallback texts) + for (int i_segmentEndPos = 1; i_segmentEndPos < lengthOfCollection; i_segmentEndPos++) + { + int i_segmentStartPos = i_segmentEndPos - 1; + TryDrawSegment_ofSplineCase_onlySegmentStartPoints_backwardForwardIsMirrored(is2D, i_segmentStartPos, i_segmentEndPos, bezierPointCollection, GetPos, GetForwardControlPos, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + if (closeGapFromEndToStart) + { + TryDrawSegment_ofSplineCase_onlySegmentStartPoints_backwardForwardIsMirrored(is2D, lengthOfCollection - 1, 0, bezierPointCollection, GetPos, GetForwardControlPos, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + } + return textPosition; + } + + static void TryDrawSegment_ofSplineCase_onlySegmentStartPoints_backwardForwardIsMirrored(bool is2D, int i_segmentStartPos, int i_segmentEndPos, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, FlexibleGetDirectionControlPosOfTransform GetForwardControlPos, ref bool textPosition_hasAlreadyBeenAssigned, ref Vector3 textPosition, ref bool splineHasAlreadyCommunicatedANullItem, Color color, float width, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 fallbackPositionOfSegment = Vector3.zero; + Vector3 controlPosOfEndDirection = Vector3.zero; + Vector3 controlPosOfStartDirection = Vector3.zero; + bool fallbackPositionOfSegment_hasAlreadyBeenAssigned = false; + bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid = false; + + Vector3 startPosition = TryGetPosFromBezierPointCollection(out bool startPosItemIsNullOrInvalid, bezierPointCollection, GetPos, i_segmentStartPos, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(startPosItemIsNullOrInvalid, startPosition, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + if (startPosItemIsNullOrInvalid == false) { controlPosOfStartDirection = GetForwardControlPos(bezierPointCollection, i_segmentStartPos); } + + Vector3 endPosition = TryGetPosFromBezierPointCollection(out bool endPosItemIsNullOrInvalid, bezierPointCollection, GetPos, i_segmentEndPos, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(endPosItemIsNullOrInvalid, endPosition, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + if (endPosItemIsNullOrInvalid == false) + { + Vector3 controlPosOfEndDirection_forward = GetForwardControlPos(bezierPointCollection, i_segmentEndPos); + Vector3 endPos_to_endPosForwardControlPos = controlPosOfEndDirection_forward - endPosition; + controlPosOfEndDirection = endPosition - endPos_to_endPosForwardControlPos; + } + + TryDrawCubicBezierSegment(is2D, startPosition, endPosition, controlPosOfStartDirection, controlPosOfEndDirection, oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid, ref splineHasAlreadyCommunicatedANullItem, i_segmentStartPos, fallbackPositionOfSegment_hasAlreadyBeenAssigned, fallbackPositionOfSegment, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + static Vector3 DrawSpline_case_onlySegmentStartPoints_backwardForwardIsKinked(bool is2D, out bool textPosition_hasAlreadyBeenAssigned, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, FlexibleGetDirectionControlPosOfTransform GetForwardControlPos, int lengthOfCollection, Color color, DrawBasics.BezierPosInterpretation interpretationOfPointsCollection, float width, bool closeGapFromEndToStart, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + textPosition_hasAlreadyBeenAssigned = false; + Vector3 textPosition = Vector3.zero; + + if (lengthOfCollection < 2) + { + Debug.LogError("Bezier spline with BezierPosInterpretation of '" + interpretationOfPointsCollection + "' needs at least 2 control points, but the specified collection has only " + lengthOfCollection + " -> drawing skipped."); + } + else + { + bool splineHasAlreadyCommunicatedANullItem = false; //preventing log spam and many drawn lines (for multiple fallback texts) + for (int i_segmentEndPos = 1; i_segmentEndPos < lengthOfCollection; i_segmentEndPos++) + { + int i_segmentStartPos = i_segmentEndPos - 1; + TryDrawSegment_ofSplineCase_onlySegmentStartPoints_backwardForwardIsKinked(is2D, i_segmentStartPos, i_segmentEndPos, bezierPointCollection, GetPos, GetForwardControlPos, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + if (closeGapFromEndToStart) + { + TryDrawSegment_ofSplineCase_onlySegmentStartPoints_backwardForwardIsKinked(is2D, lengthOfCollection - 1, 0, bezierPointCollection, GetPos, GetForwardControlPos, ref textPosition_hasAlreadyBeenAssigned, ref textPosition, ref splineHasAlreadyCommunicatedANullItem, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + } + return textPosition; + } + + static void TryDrawSegment_ofSplineCase_onlySegmentStartPoints_backwardForwardIsKinked(bool is2D, int i_segmentStartPos, int i_segmentEndPos, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, FlexibleGetDirectionControlPosOfTransform GetForwardControlPos, ref bool textPosition_hasAlreadyBeenAssigned, ref Vector3 textPosition, ref bool splineHasAlreadyCommunicatedANullItem, Color color, float width, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 fallbackPositionOfSegment = Vector3.zero; + Vector3 controlPosInBetween = Vector3.zero; + bool fallbackPositionOfSegment_hasAlreadyBeenAssigned = false; + bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid = false; + + Vector3 startPosition = TryGetPosFromBezierPointCollection(out bool startPosItemIsNullOrInvalid, bezierPointCollection, GetPos, i_segmentStartPos, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(startPosItemIsNullOrInvalid, startPosition, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + if (startPosItemIsNullOrInvalid == false) { controlPosInBetween = GetForwardControlPos(bezierPointCollection, i_segmentStartPos); } + + Vector3 endPosition = TryGetPosFromBezierPointCollection(out bool endPosItemIsNullOrInvalid, bezierPointCollection, GetPos, i_segmentEndPos, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + TryAssignFallbackAndTextPositions(endPosItemIsNullOrInvalid, endPosition, ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref textPosition, ref textPosition_hasAlreadyBeenAssigned); + + TryDrawQuadraticBezierSegment(is2D, startPosition, endPosition, controlPosInBetween, oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid, ref splineHasAlreadyCommunicatedANullItem, i_segmentStartPos, fallbackPositionOfSegment_hasAlreadyBeenAssigned, fallbackPositionOfSegment, color, width, straightSubDivisionsPerSegment, textSize, durationInSec, hiddenByNearerObjects); + } + + static Vector3 TryGetPosFromBezierPointCollection(BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, int i_insideBezierPointCollection_whereToTryObtain, ref bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid) + { + return TryGetPosFromBezierPointCollection(out bool unused, bezierPointCollection, GetPos, i_insideBezierPointCollection_whereToTryObtain, ref oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid); + } + + static Vector3 TryGetPosFromBezierPointCollection(out bool collectionItemIsNullOrInvalid, BezierPointCollection bezierPointCollection, FlexibleGetPosAtIndex GetPos, int i_insideBezierPointCollection_whereToTryObtain, ref bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid) + { + Vector3 obtainedPos = GetPos(bezierPointCollection, i_insideBezierPointCollection_whereToTryObtain, out collectionItemIsNullOrInvalid); + if (collectionItemIsNullOrInvalid) { oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid = true; } + return obtainedPos; + } + + static void TryAssignFallbackAndTextPositions(bool collectionItemIsNullOrInvalid, Vector3 position, ref Vector3 fallbackPositionOfSegment, ref bool fallbackPositionOfSegment_hasAlreadyBeenAssigned, ref Vector3 textPosition, ref bool textPosition_hasAlreadyBeenAssigned) + { + if (collectionItemIsNullOrInvalid == false) + { + AssignFallbackPositionOfSegment(ref fallbackPositionOfSegment, ref fallbackPositionOfSegment_hasAlreadyBeenAssigned, position); + AssignTextPosition(ref textPosition, ref textPosition_hasAlreadyBeenAssigned, position); + } + } + + static void AssignFallbackPositionOfSegment(ref Vector3 fallbackPositionOfSegment, ref bool fallbackPositionOfSegment_hasAlreadyBeenAssigned, Vector3 fallbackPositionOfSegmentCandidate) + { + if (fallbackPositionOfSegment_hasAlreadyBeenAssigned == false) + { + fallbackPositionOfSegment = fallbackPositionOfSegmentCandidate; + fallbackPositionOfSegment_hasAlreadyBeenAssigned = true; + } + } + + static void AssignTextPosition(ref Vector3 textPosition, ref bool textPosition_hasAlreadyBeenAssigned, Vector3 textPositionCandidate) + { + if (textPosition_hasAlreadyBeenAssigned == false) + { + textPosition = textPositionCandidate; + textPosition_hasAlreadyBeenAssigned = true; + } + } + + static void TryDrawCubicBezierSegment(bool is2D, Vector3 startPosition, Vector3 endPosition, Vector3 controlPosOfStartDirection, Vector3 controlPosOfEndDirection, bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid, ref bool splineHasAlreadyCommunicatedANullItem, int i_segment_usedForErrorText, bool fallbackPositionOfSegment_hasAlreadyBeenAssigned, Vector3 fallbackPositionOfSegment, Color color, float width, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + if (oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid) + { + CommunicateMissingArrayItem(ref splineHasAlreadyCommunicatedANullItem, i_segment_usedForErrorText, fallbackPositionOfSegment_hasAlreadyBeenAssigned, fallbackPositionOfSegment, color, textSize, durationInSec, hiddenByNearerObjects); + } + else + { + BezierSegmentCubic(is2D, startPosition, endPosition, controlPosOfStartDirection, controlPosOfEndDirection, color, null, width, straightSubDivisionsPerSegment, 0.1f, false, durationInSec, hiddenByNearerObjects); + } + } + + static void TryDrawQuadraticBezierSegment(bool is2D, Vector3 startPosition, Vector3 endPosition, Vector3 controlPosInBetween, bool oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid, ref bool splineHasAlreadyCommunicatedANullItem, int i_segment_usedForErrorText, bool fallbackPositionOfSegment_hasAlreadyBeenAssigned, Vector3 fallbackPositionOfSegment, Color color, float width, int straightSubDivisionsPerSegment, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + if (oneOfTheSegmentPointsIsUndefined_becauseCollectionItemIsNullOrInvalid) + { + CommunicateMissingArrayItem(ref splineHasAlreadyCommunicatedANullItem, i_segment_usedForErrorText, fallbackPositionOfSegment_hasAlreadyBeenAssigned, fallbackPositionOfSegment, color, textSize, durationInSec, hiddenByNearerObjects); + } + else + { + BezierSegmentQuadratic(is2D, startPosition, endPosition, controlPosInBetween, color, null, width, straightSubDivisionsPerSegment, 0.1f, false, durationInSec, hiddenByNearerObjects); + } + } + + static void CommunicateMissingArrayItem(ref bool splineHasAlreadyCommunicatedANullItem, int i_segment_usedForErrorText, bool hasfallbackPositionOfSegment, Vector3 fallbackPositionOfSegment, Color color, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + if (splineHasAlreadyCommunicatedANullItem == false) + { + if (hasfallbackPositionOfSegment) + { + UtilitiesDXXL_Text.WriteFramed("[ An item in points collection is null/invalid
-> skip drawing of bezier segment (i=" + i_segment_usedForErrorText + ")]", fallbackPositionOfSegment, color, textSize, default(Vector3), default(Vector3), DrawText.TextAnchorDXXL.UpperRight, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.02f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + else + { + Debug.LogError("An item in points collection is null/invalid -> skip drawing of bezier spline segment (i=" + i_segment_usedForErrorText + ")"); + } + } + splineHasAlreadyCommunicatedANullItem = true; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Bezier.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Bezier.cs.meta new file mode 100644 index 0000000..330f3f3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Bezier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88d8b073378c41a44bca57e7bc7f7146 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_CharsAndIcons.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_CharsAndIcons.cs new file mode 100644 index 0000000..f649983 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_CharsAndIcons.cs @@ -0,0 +1,659 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_CharsAndIcons + { + ///Symbol definition format: + //a jagged array of Vector2 arrays, + //each Vector2 array describes a stringLine of points, + //multiple stringLine of points describe a symbol. + //(actually Vector3, but z-component is ignored) + + //saving GC.Alloc and ctor's: + static Vector3 deletedMarkupStroke_lineStart = new Vector2(0.0f, 0.375f); + static Vector3 deletedMarkupStroke_lineEnd = new Vector2(1.0f, 0.375f); + static Vector3 underlinedMarkupStroke_lineStart = new Vector2(0.0f, -0.25f); + static Vector3 underlinedMarkupStroke_lineEnd = new Vector2(1.0f, -0.25f); + + public static string GetIconAsMarkupString(DrawBasics.IconType requestedIcon) + { + switch (requestedIcon) + { + case DrawBasics.IconType.profileFoto: + return ""; + + case DrawBasics.IconType.imageLandscape: + return ""; + + case DrawBasics.IconType.homeHouse: + return ""; + + case DrawBasics.IconType.dataDisc: + return ""; + + case DrawBasics.IconType.saveData: + return ""; + + case DrawBasics.IconType.loadData: + return ""; + + case DrawBasics.IconType.speechBubble: + return ""; + + case DrawBasics.IconType.speechBubbleEmpty: + return ""; + + case DrawBasics.IconType.thumbUp: + return ""; + + case DrawBasics.IconType.thumbDown: + return ""; + + case DrawBasics.IconType.lightBulbOn: + return ""; + + case DrawBasics.IconType.lightBulbOff: + return ""; + + case DrawBasics.IconType.videoCamera: + return ""; + + case DrawBasics.IconType.camera: + return ""; + + case DrawBasics.IconType.music: + return ""; + + case DrawBasics.IconType.audioSpeaker: + return ""; + + case DrawBasics.IconType.microphone: + return ""; + + case DrawBasics.IconType.wlan_wifi: + return ""; + + case DrawBasics.IconType.share: + return ""; + + case DrawBasics.IconType.timeClock: + return ""; + + case DrawBasics.IconType.telephone: + return ""; + + case DrawBasics.IconType.doorOpen: + return ""; + + case DrawBasics.IconType.doorEnter: + return ""; + + case DrawBasics.IconType.doorLeave: + return ""; + + case DrawBasics.IconType.locationPin: + return ""; + + case DrawBasics.IconType.folder: + return ""; + + case DrawBasics.IconType.saveToFolder: + return ""; + + case DrawBasics.IconType.loadFromFolder: + return ""; + + case DrawBasics.IconType.optionsSettingsGear: + return ""; + + case DrawBasics.IconType.adjustOptionsSettings: + return ""; + + case DrawBasics.IconType.pen: + return ""; + + case DrawBasics.IconType.questionMark: + return ""; + + case DrawBasics.IconType.exclamationMark: + return ""; + + case DrawBasics.IconType.shoppingCart: + return ""; + + case DrawBasics.IconType.checkmarkChecked: + return ""; + + case DrawBasics.IconType.checkmarkUnchecked: + return ""; + + case DrawBasics.IconType.battery: + return ""; + + case DrawBasics.IconType.cloud: + return ""; + + case DrawBasics.IconType.magnifier: + return ""; + + case DrawBasics.IconType.magnifierPlus: + return ""; + + case DrawBasics.IconType.magnifierMinus: + return ""; + + case DrawBasics.IconType.timeHourglassCursor: + return ""; + + case DrawBasics.IconType.cursorHand: + return ""; + + case DrawBasics.IconType.cursorPointer: + return ""; + + case DrawBasics.IconType.trashcan: + return ""; + + case DrawBasics.IconType.switchOnOff: + return ""; + + case DrawBasics.IconType.playButton: + return ""; + + case DrawBasics.IconType.pauseButton: + return ""; + + case DrawBasics.IconType.stopButton: + return ""; + + case DrawBasics.IconType.playPauseButton: + return ""; + + case DrawBasics.IconType.heart: + return ""; + + case DrawBasics.IconType.coin: + return ""; + + case DrawBasics.IconType.coins: + return ""; + + case DrawBasics.IconType.moneyBills: + return ""; + + case DrawBasics.IconType.moneyBag: + return ""; + + case DrawBasics.IconType.chestTreasureBox_closed: + return ""; + + case DrawBasics.IconType.lootbox: + return ""; + + case DrawBasics.IconType.crown: + return ""; + + case DrawBasics.IconType.trophy: + return ""; + + case DrawBasics.IconType.awardMedal: + return ""; + + case DrawBasics.IconType.sword: + return ""; + + case DrawBasics.IconType.shield: + return ""; + + case DrawBasics.IconType.gun: + return ""; + + case DrawBasics.IconType.bullet: + return ""; + + case DrawBasics.IconType.rocket: + return ""; + + case DrawBasics.IconType.crosshair: + return ""; + + case DrawBasics.IconType.arrow: + return ""; + + case DrawBasics.IconType.arrowBow: + return ""; + + case DrawBasics.IconType.bomb: + return ""; + + case DrawBasics.IconType.shovel: + return ""; + + case DrawBasics.IconType.hammer: + return ""; + + case DrawBasics.IconType.axe: + return ""; + + case DrawBasics.IconType.magnet: + return ""; + + case DrawBasics.IconType.compass: + return ""; + + case DrawBasics.IconType.fuelStation: + return ""; + + case DrawBasics.IconType.fuelCan: + return ""; + + case DrawBasics.IconType.lockLocked: + return ""; + + case DrawBasics.IconType.lockUnlocked: + return ""; + + case DrawBasics.IconType.key: + return ""; + + case DrawBasics.IconType.gemDiamond: + return ""; + + case DrawBasics.IconType.gold: + return ""; + + case DrawBasics.IconType.potion: + return ""; + + case DrawBasics.IconType.presentGift: + return ""; + + case DrawBasics.IconType.death: + return ""; + + case DrawBasics.IconType.map: + return ""; + + case DrawBasics.IconType.mushroom: + return ""; + + case DrawBasics.IconType.star: + return ""; + + case DrawBasics.IconType.pill: + return ""; + + case DrawBasics.IconType.health: + return ""; + + case DrawBasics.IconType.foodPlate: + return ""; + + case DrawBasics.IconType.foodMeat: + return ""; + + case DrawBasics.IconType.flag: + return ""; + + case DrawBasics.IconType.flagChequered: + return ""; + + case DrawBasics.IconType.ball: + return ""; + + case DrawBasics.IconType.dice: + return ""; + + case DrawBasics.IconType.joystick: + return ""; + + case DrawBasics.IconType.gamepad: + return ""; + + case DrawBasics.IconType.jigsawPuzzle: + return ""; + + case DrawBasics.IconType.fish: + return ""; + + case DrawBasics.IconType.car: + return ""; + + case DrawBasics.IconType.tree: + return ""; + + case DrawBasics.IconType.palm: + return ""; + + case DrawBasics.IconType.leaf: + return ""; + + case DrawBasics.IconType.nukeNuclearWarning: + return ""; + + case DrawBasics.IconType.biohazardWarning: + return ""; + + case DrawBasics.IconType.fireWarning: + return ""; + + case DrawBasics.IconType.warning: + return ""; + + case DrawBasics.IconType.emergencyExit: + return ""; + + case DrawBasics.IconType.sun: + return ""; + + case DrawBasics.IconType.rain: + return ""; + + case DrawBasics.IconType.wind: + return ""; + + case DrawBasics.IconType.snow: + return ""; + + case DrawBasics.IconType.lightning: + return ""; + + case DrawBasics.IconType.fire: + return ""; + + case DrawBasics.IconType.unitSquare: + return ""; + + case DrawBasics.IconType.unitSquareIncl1Right: + return ""; + + case DrawBasics.IconType.unitSquareIncl2Right: + return ""; + + case DrawBasics.IconType.unitSquareIncl3Right: + return ""; + + case DrawBasics.IconType.unitSquareIncl4Right: + return ""; + + case DrawBasics.IconType.unitSquareIncl5Right: + return ""; + + case DrawBasics.IconType.unitSquareIncl6Right: + return ""; + + case DrawBasics.IconType.unitSquareCrossed: + return ""; + + case DrawBasics.IconType.unitCircle: + return ""; + + case DrawBasics.IconType.animal: + return ""; + + case DrawBasics.IconType.bird: + return ""; + + case DrawBasics.IconType.humanMale: + return ""; + + case DrawBasics.IconType.humanFemale: + return ""; + + case DrawBasics.IconType.bombExplosion: + return ""; + + case DrawBasics.IconType.tower: + return ""; + + case DrawBasics.IconType.circleDotFilled: + return ""; + + case DrawBasics.IconType.circleDotUnfilled: + return ""; + + case DrawBasics.IconType.logMessage: + return ""; + + case DrawBasics.IconType.logMessageError: + return ""; + + case DrawBasics.IconType.logMessageException: + return ""; + + case DrawBasics.IconType.logMessageAssertion: + return ""; + + case DrawBasics.IconType.up_oneStroke: + return ""; + + case DrawBasics.IconType.up_twoStroke: + return ""; + + case DrawBasics.IconType.up_threeStroke: + return ""; + + case DrawBasics.IconType.down_oneStroke: + return ""; + + case DrawBasics.IconType.down_twoStroke: + return ""; + + case DrawBasics.IconType.down_threeStroke: + return ""; + + case DrawBasics.IconType.left_oneStroke: + return ""; + + case DrawBasics.IconType.left_twoStroke: + return ""; + + case DrawBasics.IconType.left_threeStroke: + return ""; + + case DrawBasics.IconType.right_oneStroke: + return ""; + + case DrawBasics.IconType.right_twoStroke: + return ""; + + case DrawBasics.IconType.right_threeStroke: + return ""; + + case DrawBasics.IconType.fist: + return ""; + + case DrawBasics.IconType.boxingGlove: + return ""; + + case DrawBasics.IconType.stars5Rate: + return ""; + + case DrawBasics.IconType.stars3: + return ""; + + case DrawBasics.IconType.shootingStar: + return ""; + + case DrawBasics.IconType.moonHalf: + return ""; + + case DrawBasics.IconType.moonFullPlanet: + return ""; + + case DrawBasics.IconType.leftHandRule: + return ""; + + case DrawBasics.IconType.rightHandRule: + return ""; + + case DrawBasics.IconType.megaphone: + return ""; + + case DrawBasics.IconType.arrowLeft: + return ""; + + case DrawBasics.IconType.arrowRight: + return ""; + + case DrawBasics.IconType.arrowUp: + return ""; + + case DrawBasics.IconType.arrowDown: + return ""; + + case DrawBasics.IconType.healthBox: + return ""; + + case DrawBasics.IconType.iceIcicle: + return ""; + + case DrawBasics.IconType.pickAxe: + return ""; + + case DrawBasics.IconType.audioSpeakerMute: + return ""; + + case DrawBasics.IconType.chestTreasureBox_open: + return ""; + + case DrawBasics.IconType.doorClosed: + return ""; + + default: + Debug.LogError("Icon '" + requestedIcon + "' not implemented."); + return ""; + } + + } + + + public static void RefillCurrPrintedCharDef(InternalDXXL_CharConfig charToFillIn, out bool charIsMissing) + { + Vector3[][] charDefinition; + if (charToFillIn.isIcon) + { + charDefinition = DrawXXL_LinesManager.instance.GetPointsArray(charToFillIn.iconString, out charIsMissing); + } + else + { + charDefinition = DrawXXL_LinesManager.instance.GetPointsArray(charToFillIn.character, out charIsMissing); + } + + int addionalMarkupStrokes = 0; + if (charToFillIn.deleted) + { + addionalMarkupStrokes++; + } + if (charToFillIn.underlined) + { + addionalMarkupStrokes++; + } + + DrawXXL_LinesManager.instance.numberOfStrokes_forCurrUsedChar = charDefinition.Length + addionalMarkupStrokes; + for (int i_stroke = 0; i_stroke < charDefinition.Length; i_stroke++) + { + DrawXXL_LinesManager.instance.numberOfPointsForEachStroke_forCurrUsedChar[i_stroke] = charDefinition[i_stroke].Length; + for (int i_point = 0; i_point < charDefinition[i_stroke].Length; i_point++) + { + DrawXXL_LinesManager.instance.currPrinted_charDef[i_stroke][i_point] = charDefinition[i_stroke][i_point]; + } + } + + int curr_stroke = charDefinition.Length; + if (charToFillIn.deleted) + { + DrawXXL_LinesManager.instance.numberOfPointsForEachStroke_forCurrUsedChar[curr_stroke] = 2; + DrawXXL_LinesManager.instance.currPrinted_charDef[curr_stroke][0] = deletedMarkupStroke_lineStart; + DrawXXL_LinesManager.instance.currPrinted_charDef[curr_stroke][1] = deletedMarkupStroke_lineEnd; + curr_stroke++; + } + if (charToFillIn.underlined) + { + DrawXXL_LinesManager.instance.numberOfPointsForEachStroke_forCurrUsedChar[curr_stroke] = 2; + DrawXXL_LinesManager.instance.currPrinted_charDef[curr_stroke][0] = underlinedMarkupStroke_lineStart; + DrawXXL_LinesManager.instance.currPrinted_charDef[curr_stroke][1] = underlinedMarkupStroke_lineEnd; + curr_stroke++; + } + } + + + static Vector3 offset_toShiftIconsCenterToZero = new Vector3(-0.5f, -0.5f, 0.0f); + public static void RefillCurrPrintedCharDefWithZeroCenteredIcon(DrawBasics.IconType iconToFillIn) + { + Vector3[][] charDefinition = DrawXXL_LinesManager.instance.GetPointsArray(iconToFillIn); + DrawXXL_LinesManager.instance.numberOfStrokes_forCurrUsedChar = charDefinition.Length; + for (int i_stroke = 0; i_stroke < charDefinition.Length; i_stroke++) + { + DrawXXL_LinesManager.instance.numberOfPointsForEachStroke_forCurrUsedChar[i_stroke] = charDefinition[i_stroke].Length; + for (int i_point = 0; i_point < charDefinition[i_stroke].Length; i_point++) + { + DrawXXL_LinesManager.instance.currPrinted_charDef[i_stroke][i_point] = charDefinition[i_stroke][i_point] + offset_toShiftIconsCenterToZero; + } + } + } + + + public static void DrawAllIconsWithTheirNames(Vector3 position, Color iconsColor, Color textColor, bool displayNameTexts, float sizeOfIconWall) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + iconsColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(iconsColor, Color.white); + textColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(textColor, Color.black); + sizeOfIconWall = Mathf.Max(sizeOfIconWall, 1.0f); + Vector3 positionOfNextThemeBlock = position; + + positionOfNextThemeBlock = DrawIconThemeBlock(positionOfNextThemeBlock, "System / Operate", 0, 37, iconsColor, textColor, sizeOfIconWall, displayNameTexts, (-1)); + positionOfNextThemeBlock = DrawIconThemeBlock(positionOfNextThemeBlock, "Human", 38, 45, iconsColor, textColor, sizeOfIconWall, displayNameTexts, (-1)); + positionOfNextThemeBlock = DrawIconThemeBlock(positionOfNextThemeBlock, "Nature / Weather", 46, 63, iconsColor, textColor, sizeOfIconWall, displayNameTexts, (-1)); + positionOfNextThemeBlock = DrawIconThemeBlock(positionOfNextThemeBlock, "Games", 64, 113, iconsColor, textColor, sizeOfIconWall, displayNameTexts, (-1)); + positionOfNextThemeBlock = DrawIconThemeBlock(positionOfNextThemeBlock, "Tools / Weapons", 114, 124, iconsColor, textColor, sizeOfIconWall, displayNameTexts, (-1)); + positionOfNextThemeBlock = DrawIconThemeBlock(positionOfNextThemeBlock, "Signs / Warning", 125, 133, iconsColor, textColor, sizeOfIconWall, displayNameTexts, (-1)); + positionOfNextThemeBlock = DrawIconThemeBlock(positionOfNextThemeBlock, "Basics", 134, 164, iconsColor, textColor, sizeOfIconWall, displayNameTexts, 158); + positionOfNextThemeBlock = DrawIconThemeBlock(positionOfNextThemeBlock, "Miscellaneous", 165, 166, iconsColor, textColor, sizeOfIconWall, displayNameTexts, (-1)); + } + + static Vector3 DrawIconThemeBlock(Vector3 startPos, string headline, int i_startIcon, int i_endIcon, Color iconsColor, Color textColor, float sizeOfWholeIconWall, bool displayNameTexts, int newLineForEveryIconAfterThisIconI) + { + Vector3 currPosOfLineStart = startPos; + float iconSize = 0.1f * sizeOfWholeIconWall; + float lineHeight = 1.8f * iconSize; + UtilitiesDXXL_Text.Write(headline + ":", currPosOfLineStart + Vector3.left * 0.5f * iconSize, iconsColor, 0.65f * iconSize, Vector3.right, Vector3.up, DrawText.TextAnchorDXXL.MiddleLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, false, false, false, true); + currPosOfLineStart = currPosOfLineStart + Vector3.down * lineHeight; + int i_line = 0; + int i_ofIconInsideLine = 0; + int iconsPerLine = 10; + bool hasAlreadyDrawnAnIconInCurrLine = false; + Quaternion rotation = Quaternion.LookRotation(Vector3.forward, Vector3.up); + for (int i_icon = i_startIcon; i_icon <= i_endIcon; i_icon++) + { + Vector3 currIconPosition = currPosOfLineStart + Vector3.right * 1.8f * iconSize * i_ofIconInsideLine; + string text = ((DrawBasics.IconType)i_icon).ToString(); + UtilitiesDXXL_DrawBasics.Icon(currIconPosition, (DrawBasics.IconType)i_icon, iconsColor, iconSize, displayNameTexts ? DrawText.MarkupColor(text, textColor) : null, rotation, 0, false, 0.0f, false, 0.1f, 0.004f, true); + hasAlreadyDrawnAnIconInCurrLine = true; + i_ofIconInsideLine++; + + if (i_icon == newLineForEveryIconAfterThisIconI) + { + iconsPerLine = 1; + } + if (i_ofIconInsideLine >= iconsPerLine) + { + i_ofIconInsideLine = 0; + i_line++; + currPosOfLineStart = currPosOfLineStart + Vector3.down * lineHeight; + hasAlreadyDrawnAnIconInCurrLine = false; + } + } + + Vector3 positionOfNextThemeBlock = currPosOfLineStart + 0.65f * Vector3.down * lineHeight; + if (hasAlreadyDrawnAnIconInCurrLine) + { + positionOfNextThemeBlock = positionOfNextThemeBlock + Vector3.down * lineHeight; + } + return positionOfNextThemeBlock; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_CharsAndIcons.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_CharsAndIcons.cs.meta new file mode 100644 index 0000000..1cf3f76 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_CharsAndIcons.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee252834740c4ef4ab706dedee2aaaa0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Colors.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Colors.cs new file mode 100644 index 0000000..6544781 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Colors.cs @@ -0,0 +1,802 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_Colors + { + public static Color violet = new Color(0.9372549f, 0.4196078f, 0.6156863f, 1f); + public static Color darkBlue = new Color(0.1372549f, 0.1058824f, 0.7176471f, 1f); + public static Color red_xAxis = new Color(0.9607843f, 0.282353f, 0.1607843f, 0.9333333f); + public static Color green_yAxis = new Color(0.6784314f, 0.9568627f, 0.3058824f, 0.9333333f); + public static Color blue_zAxis = new Color(0.2470588f, 0.5176471f, 0.9882353f, 1f); + public static Color red_xAxisAlpha1 = new Color(0.9607843f, 0.282353f, 0.1607843f, 1f); + public static Color green_yAxisAlpha1 = new Color(0.6784314f, 0.9568627f, 0.3058824f, 1f); + public static Color blue_zAxisAlpha1 = new Color(0.2470588f, 0.5176471f, 0.9882353f, 1f); + public static Color green_lineThresholdNearDistance = new Color(0.1215686f, 0.8745098f, 0.2078431f, 1f); + public static Color orange_lineThresholdMiddleDistance = new Color(0.9960784f, 0.7490196f, 0f, 1f); + public static Color red_lineThresholdFarDistance = new Color(0.9647059f, 0f, 0.1607843f, 1f); + public static Color grey_logMessage = new Color(0.6784314f, 0.6784314f, 0.6784314f, 1f); + public static Color yellow_logWarning = new Color(0.8862745f, 0.6666667f, 0f, 1f); + public static Color red_logError = new Color(0.8078431f, 0.05490196f, 0.05490196f, 1f); + public static Color purple_raycastHitTextDefault = new Color(0.2941177f, 0f, 0.3882353f, 1f); + public static Color green_boolTrue = new Color(0.5137255f, 0.8862745f, 0.2901961f, 1f); + public static Color red_boolFalse = new Color(0.9294118f, 0.2784314f, 0.1921569f, 1f); + + public enum ColorComponent { r, g, b, a }; + + public static Color Get_color_butWithAdjustedAlpha(Color baseColor_forWhichToAdjustTheAlpha, float alphaFactor) + { + Color color_toReturn = new Color(); + + color_toReturn.r = baseColor_forWhichToAdjustTheAlpha.r; + color_toReturn.g = baseColor_forWhichToAdjustTheAlpha.g; + color_toReturn.b = baseColor_forWhichToAdjustTheAlpha.b; + color_toReturn.a = baseColor_forWhichToAdjustTheAlpha.a * alphaFactor; + + return color_toReturn; + } + + public static Color Get_color_butWithFixedAlpha(Color baseColor_forWhichToSetTheAlpha, float fixedAlpha) + { + Color color_toReturn = new Color(); + + color_toReturn.r = baseColor_forWhichToSetTheAlpha.r; + color_toReturn.g = baseColor_forWhichToSetTheAlpha.g; + color_toReturn.b = baseColor_forWhichToSetTheAlpha.b; + color_toReturn.a = fixedAlpha; + + return color_toReturn; + } + + public static Color Get_color_darkenedFromGivenColor(Color baseColor_toAdjust, float darkeningIntensity) + { + Color color_toReturn = new Color(); + + color_toReturn.r = baseColor_toAdjust.r / darkeningIntensity; + color_toReturn.g = baseColor_toAdjust.g / darkeningIntensity; + color_toReturn.b = baseColor_toAdjust.b / darkeningIntensity; + color_toReturn.a = baseColor_toAdjust.a; + + return color_toReturn; + } + + public static Color Get_randomColorSeeded(int seed) + { + return Get_randomColorSeeded(seed, 1.0f, 0.0f); + } + + public static Color Get_randomColorSeeded(int seed, float alphaToUse_0to1, float forceLuminance) + { + Color color_toReturn = new Color(); + + float r_x = 1235.235f + 2.014f * (float)seed; + float r_y = 2395.0911f + 3.599f * (float)seed; + color_toReturn.r = Mathf.PerlinNoise(UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_m1_to_p1(r_x) * 100.0f, UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_m1_to_p1(r_y) * 100.0f); + float g_x = 213.732f + 3.521f * (float)seed; + float g_y = -35.9806f + 2.511f * (float)seed; + color_toReturn.g = Mathf.PerlinNoise(UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_m1_to_p1(g_x) * 100.0f, UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_m1_to_p1(g_y) * 100.0f); + float b_x = 355.5312f - 2.761f * (float)seed; + float b_y = -299.1816f + 1.811f * (float)seed; + color_toReturn.b = Mathf.PerlinNoise(UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_m1_to_p1(b_x) * 100.0f, UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_m1_to_p1(b_y) * 100.0f); + + ColorComponent biggestComponent = GetBiggestComponentRGB(color_toReturn); + ColorComponent smallestComponent = GetSmallestComponentRGB(color_toReturn); + + color_toReturn = color_toReturn * color_toReturn * 1.0f; + switch (biggestComponent) + { + case ColorComponent.r: + color_toReturn.r = 0.5f * (color_toReturn.r + 1.0f); + break; + + case ColorComponent.g: + color_toReturn.g = 0.5f * (color_toReturn.g + 1.0f); + break; + + case ColorComponent.b: + color_toReturn.b = 0.5f * (color_toReturn.b + 1.0f); + break; + + default: + break; + } + + switch (smallestComponent) + { + case ColorComponent.r: + color_toReturn.r = 1.0f; + break; + + case ColorComponent.g: + color_toReturn.g = 1.0f; + break; + + case ColorComponent.b: + color_toReturn.b = 1.0f; + break; + + default: + break; + } + + if (UtilitiesDXXL_Math.CheckIf_givenNumberIs_evenNotOdd(seed)) + { + color_toReturn = Invert_andAlphaTo1(color_toReturn); + color_toReturn = color_toReturn * 2.4f; + } + + color_toReturn = SeededColorGenerator.ForceApproxLuminance(color_toReturn, forceLuminance); + color_toReturn.a = alphaToUse_0to1; + return color_toReturn; + } + + static ColorComponent GetBiggestComponentRGB(Color color) + { + float componentValue; + return GetBiggestComponentRGB(color, out componentValue); + } + + static ColorComponent GetBiggestComponentRGB(Color color, out float biggestValue) + { + ColorComponent biggestComponent = ColorComponent.r; + biggestValue = color.r; + + if (color.g > biggestValue) + { + biggestComponent = ColorComponent.g; + biggestValue = color.g; + } + + if (color.b > biggestValue) + { + biggestComponent = ColorComponent.b; + biggestValue = color.b; + } + + return biggestComponent; + } + + static ColorComponent GetSmallestComponentRGB(Color color) + { + float componentValue; + return GetSmallestComponentRGB(color, out componentValue); + } + + static ColorComponent GetSmallestComponentRGB(Color color, out float smallestValue) + { + ColorComponent smallestComponent = ColorComponent.r; + smallestValue = color.r; + + if (color.g < smallestValue) + { + smallestComponent = ColorComponent.g; + smallestValue = color.g; + } + + if (color.b < smallestValue) + { + smallestComponent = ColorComponent.b; + smallestValue = color.b; + } + + return smallestComponent; + } + + public static Color OverwriteColorNearGreyWithBlack(Color colorToOverwrite) + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(0.5f, colorToOverwrite.r, 0.12f) && UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(0.5f, colorToOverwrite.g, 0.12f) && UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(0.5f, colorToOverwrite.b, 0.12f)) + { + return Color.black; + } + else + { + return colorToOverwrite; + } + } + + public static Color Invert_andAlphaTo1(Color color) + { + return new Color(1.0f - color.r, 1.0f - color.g, 1.0f - color.b); + } + + public static Color OverwriteDefaultColor(Color colorToOverwriteIfDefault) + { + return OverwriteDefaultColor(colorToOverwriteIfDefault, DrawBasics.defaultColor); + } + + public static Color OverwriteDefaultColor(Color colorToOverwriteIfDefault, Color overwritingColor) + { + if (UtilitiesDXXL_Math.FloatIsInvalid(colorToOverwriteIfDefault.r) || UtilitiesDXXL_Math.FloatIsInvalid(colorToOverwriteIfDefault.g) || UtilitiesDXXL_Math.FloatIsInvalid(colorToOverwriteIfDefault.b) || UtilitiesDXXL_Math.FloatIsInvalid(colorToOverwriteIfDefault.a)) + { + Debug.LogError("color contains invalid float components: ( r is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(colorToOverwriteIfDefault.r) + ", g is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(colorToOverwriteIfDefault.g) + ", b is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(colorToOverwriteIfDefault.b) + ", a is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(colorToOverwriteIfDefault.a) + ") -> fallback to white color."); + return overwritingColor; + } + + if (IsDefaultColor(colorToOverwriteIfDefault)) + { + return overwritingColor; + } + else + { + return colorToOverwriteIfDefault; + } + } + + public static bool IsDefaultColor(Color color) + { + return (UtilitiesDXXL_Math.ApproximatelyZero(color.r) && UtilitiesDXXL_Math.ApproximatelyZero(color.g) && UtilitiesDXXL_Math.ApproximatelyZero(color.b) && UtilitiesDXXL_Math.ApproximatelyZero(color.a)); + } + + public static bool IsApproxSameColor(Color color1, Color color2, bool ignoreAlpha = true) + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(color1.r, color2.r, 0.005f)) + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(color1.g, color2.g, 0.005f)) + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(color1.b, color2.b, 0.005f)) + { + if (ignoreAlpha) + { + return true; + } + else + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(color1.a, color2.a, 0.005f)) + { + return true; + } + } + } + } + } + return false; + } + + public static Color GetSimilarColorWithOtherBrightnessValue(Color initialColor) + { + return ((initialColor.grayscale < 0.175f) ? Color.Lerp(initialColor, Color.white, 0.7f) : Color.Lerp(initialColor, Color.black, 0.7f)); + } + + public static Color GetSimilarColorWithOtherBrightnessValue(Color initialColor, float changeIntensity) + { + return ((initialColor.grayscale < 0.175f) ? Color.Lerp(initialColor, Color.white, changeIntensity) : Color.Lerp(initialColor, Color.black, changeIntensity)); + } + + public static Color GetSimilarColorWithSlightlyOtherBrightnessValue(Color initialColor) + { + float luminanceOfInitialColor = SeededColorGenerator.GetLuminance(initialColor); + return ((luminanceOfInitialColor < 0.5f) ? Color.Lerp(initialColor, Color.white, 0.2f) : Color.Lerp(initialColor, Color.black, 0.2f)); + } + + public static Color GetSimilarColorWithAdjustableOtherBrightnessValue(Color initialColor, float changeIntensity) + { + float luminanceOfInitialColor = SeededColorGenerator.GetLuminance(initialColor); + return ((luminanceOfInitialColor < 0.5f) ? Color.Lerp(initialColor, Color.white, changeIntensity) : Color.Lerp(initialColor, Color.black, changeIntensity)); + } + + static Keyframe redCurveOfRainbow_atLuminanceNotForced_keyframe0 = new Keyframe(0f, 1f, 0f, 0f, 0f, 0.0267929f); + static Keyframe redCurveOfRainbow_atLuminanceNotForced_keyframe1 = new Keyframe(0.1666667f, 1f, 0f, -2.628986f, 0.03435588f, 0.3283422f); + static Keyframe redCurveOfRainbow_atLuminanceNotForced_keyframe2 = new Keyframe(0.3333333f, 0f, -19.39972f, 0f, 0.1582886f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminanceNotForced_keyframe3 = new Keyframe(0.6666667f, 0f, 0f, 45.27549f, 0.0103105f, 0.06844892f); + static Keyframe redCurveOfRainbow_atLuminanceNotForced_keyframe4 = new Keyframe(0.8333333f, 1f, 2.024274f, 0f, 0.4823529f, 0.01595771f); + static Keyframe redCurveOfRainbow_atLuminanceNotForced_keyframe5 = new Keyframe(1f, 1f, 0f, 0f, 0.02324617f, 0f); + static AnimationCurve redCurveOfRainbow_atLuminanceNotForced = new AnimationCurve(redCurveOfRainbow_atLuminanceNotForced_keyframe0, redCurveOfRainbow_atLuminanceNotForced_keyframe1, redCurveOfRainbow_atLuminanceNotForced_keyframe2, redCurveOfRainbow_atLuminanceNotForced_keyframe3, redCurveOfRainbow_atLuminanceNotForced_keyframe4, redCurveOfRainbow_atLuminanceNotForced_keyframe5); + + static Keyframe greenCurveOfRainbow_atLuminanceNotForced_keyframe0 = new Keyframe(0f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminanceNotForced_keyframe1 = new Keyframe(0.333333f, 0f, 0f, 17.67738f, 0.003058169f, 0.1337735f); + static Keyframe greenCurveOfRainbow_atLuminanceNotForced_keyframe2 = new Keyframe(0.4080812f, 0.5186183f, 5.17586f, 5.17586f, 0.4374433f, 0.4164693f); + static Keyframe greenCurveOfRainbow_atLuminanceNotForced_keyframe3 = new Keyframe(0.5f, 1f, 2.790231f, 0f, 0.2850692f, 0.007641078f); + static Keyframe greenCurveOfRainbow_atLuminanceNotForced_keyframe4 = new Keyframe(0.8333333f, 1f, 0f, -1.997148f, 0.006811738f, 0.3967916f); + static Keyframe greenCurveOfRainbow_atLuminanceNotForced_keyframe5 = new Keyframe(1f, 0f, -14.63444f, -5.54757f, 0.1411764f, 0f); + static AnimationCurve greenCurveOfRainbow_atLuminanceNotForced = new AnimationCurve(greenCurveOfRainbow_atLuminanceNotForced_keyframe0, greenCurveOfRainbow_atLuminanceNotForced_keyframe1, greenCurveOfRainbow_atLuminanceNotForced_keyframe2, greenCurveOfRainbow_atLuminanceNotForced_keyframe3, greenCurveOfRainbow_atLuminanceNotForced_keyframe4, greenCurveOfRainbow_atLuminanceNotForced_keyframe5); + + static Keyframe blueCurveOfRainbow_atLuminanceNotForced_keyframe0 = new Keyframe(0f, -0.002349854f, 5.103677f, 9.843518f, 0f, 0.4812853f); + static Keyframe blueCurveOfRainbow_atLuminanceNotForced_keyframe1 = new Keyframe(0.166666f, 1f, 3.602612f, 0f, 0.3582862f, 0.005642463f); + static Keyframe blueCurveOfRainbow_atLuminanceNotForced_keyframe2 = new Keyframe(0.5f, 1f, 0f, -3.017625f, 0.01999663f, 0.3048127f); + static Keyframe blueCurveOfRainbow_atLuminanceNotForced_keyframe3 = new Keyframe(0.6666666f, 0f, -22.01747f, 0f, 0.1368982f, 0.01547652f); + static Keyframe blueCurveOfRainbow_atLuminanceNotForced_keyframe4 = new Keyframe(1f, 0f, 0f, 0f, 0f, 0f); + static AnimationCurve blueCurveOfRainbow_atLuminanceNotForced = new AnimationCurve(blueCurveOfRainbow_atLuminanceNotForced_keyframe0, blueCurveOfRainbow_atLuminanceNotForced_keyframe1, blueCurveOfRainbow_atLuminanceNotForced_keyframe2, blueCurveOfRainbow_atLuminanceNotForced_keyframe3, blueCurveOfRainbow_atLuminanceNotForced_keyframe4); + + static Keyframe luminanceTargetCurveOfRainbow_atLuminanceNotForced_keyframe0 = new Keyframe(0f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminanceNotForced_keyframe1 = new Keyframe(1f, 1f, 0f, 0f, 0f, 0f); + static AnimationCurve luminanceTargetCurveOfRainbow_atLuminanceNotForced = new AnimationCurve(luminanceTargetCurveOfRainbow_atLuminanceNotForced_keyframe0, luminanceTargetCurveOfRainbow_atLuminanceNotForced_keyframe1); + + static Keyframe redCurveOfRainbow_atLuminance0825_keyframe0 = new Keyframe(0f, 1f, 0f, 0f, 0f, 0.0267929f); + static Keyframe redCurveOfRainbow_atLuminance0825_keyframe1 = new Keyframe(0.1666667f, 1f, 0f, -34.14504f, 0.03435588f, 0.0845046f); + static Keyframe redCurveOfRainbow_atLuminance0825_keyframe2 = new Keyframe(0.2320574f, 0.4720321f, -5.176624f, -5.176624f, 0.4951762f, 0.423487f); + static Keyframe redCurveOfRainbow_atLuminance0825_keyframe3 = new Keyframe(0.33333f, 0.05f, -2.198078f, 0f, 0.1232304f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance0825_keyframe4 = new Keyframe(0.41f, 0f, -0.2348027f, 0f, 0.7860962f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance0825_keyframe5 = new Keyframe(0.6666667f, 0f, 0f, 8.216114f, 0.0103105f, 0.2128025f); + static Keyframe redCurveOfRainbow_atLuminance0825_keyframe6 = new Keyframe(0.7662566f, 0.5346156f, 2.536475f, 2.750102f, 0.4451402f, 0.6306142f); + static Keyframe redCurveOfRainbow_atLuminance0825_keyframe7 = new Keyframe(0.8333333f, 1f, 14.31863f, 0f, 0.2072095f, 0.01595771f); + static Keyframe redCurveOfRainbow_atLuminance0825_keyframe8 = new Keyframe(1f, 1f, 0f, 0f, 0.02324617f, 0f); + static AnimationCurve redCurveOfRainbow_atLuminance0825 = new AnimationCurve(redCurveOfRainbow_atLuminance0825_keyframe0, redCurveOfRainbow_atLuminance0825_keyframe1, redCurveOfRainbow_atLuminance0825_keyframe2, redCurveOfRainbow_atLuminance0825_keyframe3, redCurveOfRainbow_atLuminance0825_keyframe4, redCurveOfRainbow_atLuminance0825_keyframe5, redCurveOfRainbow_atLuminance0825_keyframe6, redCurveOfRainbow_atLuminance0825_keyframe7, redCurveOfRainbow_atLuminance0825_keyframe8); + + static Keyframe greenCurveOfRainbow_atLuminance0825_keyframe0 = new Keyframe(0f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance0825_keyframe1 = new Keyframe(0.257754f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance0825_keyframe2 = new Keyframe(0.333333f, 0.05f, 0f, 2.176718f, 0.003058169f, 0.4737473f); + static Keyframe greenCurveOfRainbow_atLuminance0825_keyframe3 = new Keyframe(0.4266467f, 0.4177842f, 4.696632f, 4.900658f, 0.4689451f, 0.4386555f); + static Keyframe greenCurveOfRainbow_atLuminance0825_keyframe4 = new Keyframe(0.5f, 1f, 10.00402f, 0f, 0.2608117f, 0.007641078f); + static Keyframe greenCurveOfRainbow_atLuminance0825_keyframe5 = new Keyframe(0.8333333f, 1f, 0f, -24.77313f, 0.006811738f, 0.1773775f); + static Keyframe greenCurveOfRainbow_atLuminance0825_keyframe6 = new Keyframe(0.8805654f, 0.531985f, -9.559245f, -7.222806f, 0.2444473f, 0.294646f); + static Keyframe greenCurveOfRainbow_atLuminance0825_keyframe7 = new Keyframe(1f, 0f, -4.811322f, -5.54757f, 0.2375333f, 0f); + static AnimationCurve greenCurveOfRainbow_atLuminance0825 = new AnimationCurve(greenCurveOfRainbow_atLuminance0825_keyframe0, greenCurveOfRainbow_atLuminance0825_keyframe1, greenCurveOfRainbow_atLuminance0825_keyframe2, greenCurveOfRainbow_atLuminance0825_keyframe3, greenCurveOfRainbow_atLuminance0825_keyframe4, greenCurveOfRainbow_atLuminance0825_keyframe5, greenCurveOfRainbow_atLuminance0825_keyframe6, greenCurveOfRainbow_atLuminance0825_keyframe7); + + static Keyframe blueCurveOfRainbow_atLuminance0825_keyframe0 = new Keyframe(0f, 0f, 5.103677f, 2.205189f, 0f, 0.4330214f); + static Keyframe blueCurveOfRainbow_atLuminance0825_keyframe1 = new Keyframe(0.1062056f, 0.3805489f, 4.460747f, 4.460747f, 0.410798f, 0.3914252f); + static Keyframe blueCurveOfRainbow_atLuminance0825_keyframe2 = new Keyframe(0.166666f, 1f, 17.27078f, 0f, 0.2181011f, 0.005642463f); + static Keyframe blueCurveOfRainbow_atLuminance0825_keyframe3 = new Keyframe(0.5f, 1f, 0f, -16.78093f, 0.01999663f, 0.2947439f); + static Keyframe blueCurveOfRainbow_atLuminance0825_keyframe4 = new Keyframe(0.5647435f, 0.4470914f, -4.936384f, -3.610273f, 0.3874579f, 0.2659675f); + static Keyframe blueCurveOfRainbow_atLuminance0825_keyframe5 = new Keyframe(0.6666666f, 0f, -9.622663f, 0f, 0.3078054f, 0.01547652f); + static Keyframe blueCurveOfRainbow_atLuminance0825_keyframe6 = new Keyframe(1f, 0f, 0f, 0f, 0f, 0f); + static AnimationCurve blueCurveOfRainbow_atLuminance0825 = new AnimationCurve(blueCurveOfRainbow_atLuminance0825_keyframe0, blueCurveOfRainbow_atLuminance0825_keyframe1, blueCurveOfRainbow_atLuminance0825_keyframe2, blueCurveOfRainbow_atLuminance0825_keyframe3, blueCurveOfRainbow_atLuminance0825_keyframe4, blueCurveOfRainbow_atLuminance0825_keyframe5, blueCurveOfRainbow_atLuminance0825_keyframe6); + + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0825_keyframe0 = new Keyframe(0f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0825_keyframe1 = new Keyframe(1f, 1f, 0f, 0f, 0f, 0f); + static AnimationCurve luminanceTargetCurveOfRainbow_atLuminance0825 = new AnimationCurve(luminanceTargetCurveOfRainbow_atLuminance0825_keyframe0, luminanceTargetCurveOfRainbow_atLuminance0825_keyframe1); + + static Keyframe redCurveOfRainbow_atLuminance0675_keyframe0 = new Keyframe(0f, 1f, 0f, 0f, 0f, 0.0267929f); + static Keyframe redCurveOfRainbow_atLuminance0675_keyframe1 = new Keyframe(0.1666667f, 1f, 0f, -27.8928f, 0.03435588f, 0.04299471f); + static Keyframe redCurveOfRainbow_atLuminance0675_keyframe2 = new Keyframe(0.2331255f, 0.519197f, -5.176624f, -5.176624f, 0.4951762f, 0.423487f); + static Keyframe redCurveOfRainbow_atLuminance0675_keyframe3 = new Keyframe(0.3333333f, 0.1f, -2.198078f, 0f, 0.1232304f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance0675_keyframe4 = new Keyframe(0.41f, 0f, -0.2348027f, 0f, 0.7860962f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance0675_keyframe5 = new Keyframe(0.6666667f, 0f, 0f, 8.878784f, 0.0103105f, 0.1732416f); + static Keyframe redCurveOfRainbow_atLuminance0675_keyframe6 = new Keyframe(0.7705347f, 0.5629174f, 3.463916f, 4.153102f, 0.5805737f, 0.599038f); + static Keyframe redCurveOfRainbow_atLuminance0675_keyframe7 = new Keyframe(0.8333333f, 1f, 8.022022f, 0f, 0.2558905f, 0.01595771f); + static Keyframe redCurveOfRainbow_atLuminance0675_keyframe8 = new Keyframe(1f, 1f, 0f, 0f, 0.02324617f, 0f); + static AnimationCurve redCurveOfRainbow_atLuminance0675 = new AnimationCurve(redCurveOfRainbow_atLuminance0675_keyframe0, redCurveOfRainbow_atLuminance0675_keyframe1, redCurveOfRainbow_atLuminance0675_keyframe2, redCurveOfRainbow_atLuminance0675_keyframe3, redCurveOfRainbow_atLuminance0675_keyframe4, redCurveOfRainbow_atLuminance0675_keyframe5, redCurveOfRainbow_atLuminance0675_keyframe6, redCurveOfRainbow_atLuminance0675_keyframe7, redCurveOfRainbow_atLuminance0675_keyframe8); + + static Keyframe greenCurveOfRainbow_atLuminance0675_keyframe0 = new Keyframe(0f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance0675_keyframe1 = new Keyframe(0.257754f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance0675_keyframe2 = new Keyframe(0.333333f, 0.1023499f, 0f, 4.399855f, 0.003058169f, 0.1528241f); + static Keyframe greenCurveOfRainbow_atLuminance0675_keyframe3 = new Keyframe(0.4266467f, 0.4177842f, 4.516745f, 4.023407f, 0.5491757f, 0.4652202f); + static Keyframe greenCurveOfRainbow_atLuminance0675_keyframe4 = new Keyframe(0.5f, 1f, 10.00402f, 0f, 0.2608117f, 0.007641078f); + static Keyframe greenCurveOfRainbow_atLuminance0675_keyframe5 = new Keyframe(0.8333333f, 1f, 0f, -14.14011f, 0.006811738f, 0.259255f); + static Keyframe greenCurveOfRainbow_atLuminance0675_keyframe6 = new Keyframe(0.9009427f, 0.4423702f, -4.054608f, -5.455518f, 0.3919348f, 0.3876472f); + static Keyframe greenCurveOfRainbow_atLuminance0675_keyframe7 = new Keyframe(1f, 0f, -7.105606f, -5.54757f, 0.1943456f, 0f); + static AnimationCurve greenCurveOfRainbow_atLuminance0675 = new AnimationCurve(greenCurveOfRainbow_atLuminance0675_keyframe0, greenCurveOfRainbow_atLuminance0675_keyframe1, greenCurveOfRainbow_atLuminance0675_keyframe2, greenCurveOfRainbow_atLuminance0675_keyframe3, greenCurveOfRainbow_atLuminance0675_keyframe4, greenCurveOfRainbow_atLuminance0675_keyframe5, greenCurveOfRainbow_atLuminance0675_keyframe6, greenCurveOfRainbow_atLuminance0675_keyframe7); + + static Keyframe blueCurveOfRainbow_atLuminance0675_keyframe0 = new Keyframe(0f, 0f, 5.103677f, 79.3868f, 0f, 0.01229945f); + static Keyframe blueCurveOfRainbow_atLuminance0675_keyframe1 = new Keyframe(0.08695666f, 0.371119f, 4.460747f, 4.460747f, 0.410798f, 0.3914252f); + static Keyframe blueCurveOfRainbow_atLuminance0675_keyframe2 = new Keyframe(0.166666f, 1f, 17.27078f, 0f, 0.2181011f, 0.005642463f); + static Keyframe blueCurveOfRainbow_atLuminance0675_keyframe3 = new Keyframe(0.5f, 1f, 0f, -16.78093f, 0.01999663f, 0.2947439f); + static Keyframe blueCurveOfRainbow_atLuminance0675_keyframe4 = new Keyframe(0.5647435f, 0.4470914f, -4.936384f, -3.610273f, 0.3874579f, 0.2659675f); + static Keyframe blueCurveOfRainbow_atLuminance0675_keyframe5 = new Keyframe(0.6666666f, 0f, -9.622663f, 0f, 0.3078054f, 0.01547652f); + static Keyframe blueCurveOfRainbow_atLuminance0675_keyframe6 = new Keyframe(1f, 0f, 0f, 0f, 0f, 0f); + static AnimationCurve blueCurveOfRainbow_atLuminance0675 = new AnimationCurve(blueCurveOfRainbow_atLuminance0675_keyframe0, blueCurveOfRainbow_atLuminance0675_keyframe1, blueCurveOfRainbow_atLuminance0675_keyframe2, blueCurveOfRainbow_atLuminance0675_keyframe3, blueCurveOfRainbow_atLuminance0675_keyframe4, blueCurveOfRainbow_atLuminance0675_keyframe5, blueCurveOfRainbow_atLuminance0675_keyframe6); + + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0675_keyframe0 = new Keyframe(0f, 1.1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0675_keyframe1 = new Keyframe(0.1666666f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0675_keyframe2 = new Keyframe(0.3333333f, 1.1f, 0.002788117f, 0f, 0.8747915f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0675_keyframe3 = new Keyframe(0.5f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0675_keyframe4 = new Keyframe(0.8333333f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0675_keyframe5 = new Keyframe(1f, 1.1f, 0f, 0f, 0f, 0f); + static AnimationCurve luminanceTargetCurveOfRainbow_atLuminance0675 = new AnimationCurve(luminanceTargetCurveOfRainbow_atLuminance0675_keyframe0, luminanceTargetCurveOfRainbow_atLuminance0675_keyframe1, luminanceTargetCurveOfRainbow_atLuminance0675_keyframe2, luminanceTargetCurveOfRainbow_atLuminance0675_keyframe3, luminanceTargetCurveOfRainbow_atLuminance0675_keyframe4, luminanceTargetCurveOfRainbow_atLuminance0675_keyframe5); + + static Keyframe redCurveOfRainbow_atLuminance05_keyframe0 = new Keyframe(0f, 1f, 0f, 0f, 0f, 0.0267929f); + static Keyframe redCurveOfRainbow_atLuminance05_keyframe1 = new Keyframe(0.1666667f, 1f, 0f, -27.8928f, 0.03435588f, 0.04299471f); + static Keyframe redCurveOfRainbow_atLuminance05_keyframe2 = new Keyframe(0.2331255f, 0.519197f, -5.176624f, -5.176624f, 0.4951762f, 0.423487f); + static Keyframe redCurveOfRainbow_atLuminance05_keyframe3 = new Keyframe(0.3333333f, 0.1f, -2.198078f, 0f, 0.1232304f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance05_keyframe4 = new Keyframe(0.41f, 0f, -0.2348027f, 0f, 0.7860962f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance05_keyframe5 = new Keyframe(0.6666667f, 0f, 0f, 28.39604f, 0.0103105f, 0.1390375f); + static Keyframe redCurveOfRainbow_atLuminance05_keyframe6 = new Keyframe(0.8333333f, 1f, 26.88915f, 0f, 0.03315497f, 0.01595771f); + static Keyframe redCurveOfRainbow_atLuminance05_keyframe7 = new Keyframe(1f, 1f, 0f, 0f, 0.02324617f, 0f); + static AnimationCurve redCurveOfRainbow_atLuminance05 = new AnimationCurve(redCurveOfRainbow_atLuminance05_keyframe0, redCurveOfRainbow_atLuminance05_keyframe1, redCurveOfRainbow_atLuminance05_keyframe2, redCurveOfRainbow_atLuminance05_keyframe3, redCurveOfRainbow_atLuminance05_keyframe4, redCurveOfRainbow_atLuminance05_keyframe5, redCurveOfRainbow_atLuminance05_keyframe6, redCurveOfRainbow_atLuminance05_keyframe7); + + static Keyframe greenCurveOfRainbow_atLuminance05_keyframe0 = new Keyframe(0f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance05_keyframe1 = new Keyframe(0.257754f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance05_keyframe2 = new Keyframe(0.333333f, 0.1023499f, 0f, 4.399855f, 0.003058169f, 0.1528241f); + static Keyframe greenCurveOfRainbow_atLuminance05_keyframe3 = new Keyframe(0.4266467f, 0.4177842f, 4.516745f, 4.023407f, 0.5491757f, 0.4652202f); + static Keyframe greenCurveOfRainbow_atLuminance05_keyframe4 = new Keyframe(0.5f, 1f, 10.00402f, 0f, 0.2608117f, 0.007641078f); + static Keyframe greenCurveOfRainbow_atLuminance05_keyframe5 = new Keyframe(0.8333333f, 1f, 0f, -11.52388f, 0.006811738f, 0.3067519f); + static Keyframe greenCurveOfRainbow_atLuminance05_keyframe6 = new Keyframe(0.9234037f, 0.4471004f, -4.054608f, -5.455518f, 0.3919348f, 0.3876472f); + static Keyframe greenCurveOfRainbow_atLuminance05_keyframe7 = new Keyframe(1f, 0f, -17.81115f, -5.54757f, 0.1841612f, 0f); + static AnimationCurve greenCurveOfRainbow_atLuminance05 = new AnimationCurve(greenCurveOfRainbow_atLuminance05_keyframe0, greenCurveOfRainbow_atLuminance05_keyframe1, greenCurveOfRainbow_atLuminance05_keyframe2, greenCurveOfRainbow_atLuminance05_keyframe3, greenCurveOfRainbow_atLuminance05_keyframe4, greenCurveOfRainbow_atLuminance05_keyframe5, greenCurveOfRainbow_atLuminance05_keyframe6, greenCurveOfRainbow_atLuminance05_keyframe7); + + static Keyframe blueCurveOfRainbow_atLuminance05_keyframe0 = new Keyframe(0f, 0f, 5.103677f, 79.3868f, 0f, 0.01229945f); + static Keyframe blueCurveOfRainbow_atLuminance05_keyframe1 = new Keyframe(0.08695666f, 0.371119f, 4.460747f, 4.460747f, 0.410798f, 0.3914252f); + static Keyframe blueCurveOfRainbow_atLuminance05_keyframe2 = new Keyframe(0.166666f, 1f, 17.27078f, 0f, 0.2181011f, 0.005642463f); + static Keyframe blueCurveOfRainbow_atLuminance05_keyframe3 = new Keyframe(0.5f, 1f, 0f, -16.78093f, 0.01999663f, 0.2947439f); + static Keyframe blueCurveOfRainbow_atLuminance05_keyframe4 = new Keyframe(0.5743871f, 0.5367215f, -4.936384f, -3.610273f, 0.3874579f, 0.2659675f); + static Keyframe blueCurveOfRainbow_atLuminance05_keyframe5 = new Keyframe(0.6666666f, 0f, -17.39986f, 0f, 0.282023f, 0.01547652f); + static Keyframe blueCurveOfRainbow_atLuminance05_keyframe6 = new Keyframe(1f, 0f, 0f, 0f, 0f, 0f); + static AnimationCurve blueCurveOfRainbow_atLuminance05 = new AnimationCurve(blueCurveOfRainbow_atLuminance05_keyframe0, blueCurveOfRainbow_atLuminance05_keyframe1, blueCurveOfRainbow_atLuminance05_keyframe2, blueCurveOfRainbow_atLuminance05_keyframe3, blueCurveOfRainbow_atLuminance05_keyframe4, blueCurveOfRainbow_atLuminance05_keyframe5, blueCurveOfRainbow_atLuminance05_keyframe6); + + static Keyframe luminanceTargetCurveOfRainbow_atLuminance05_keyframe0 = new Keyframe(0f, 1.1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance05_keyframe1 = new Keyframe(0.1666666f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance05_keyframe2 = new Keyframe(0.3333333f, 1.22f, 0.002788117f, 0f, 0.8747915f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance05_keyframe3 = new Keyframe(0.5f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance05_keyframe4 = new Keyframe(0.8333333f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance05_keyframe5 = new Keyframe(1f, 1.1f, 0f, 0f, 0f, 0f); + static AnimationCurve luminanceTargetCurveOfRainbow_atLuminance05 = new AnimationCurve(luminanceTargetCurveOfRainbow_atLuminance05_keyframe0, luminanceTargetCurveOfRainbow_atLuminance05_keyframe1, luminanceTargetCurveOfRainbow_atLuminance05_keyframe2, luminanceTargetCurveOfRainbow_atLuminance05_keyframe3, luminanceTargetCurveOfRainbow_atLuminance05_keyframe4, luminanceTargetCurveOfRainbow_atLuminance05_keyframe5); + + static Keyframe redCurveOfRainbow_atLuminance044_keyframe0 = new Keyframe(0f, 1f, 0f, 0f, 0f, 0.0267929f); + static Keyframe redCurveOfRainbow_atLuminance044_keyframe1 = new Keyframe(0.1666667f, 1f, 0f, -21.46155f, 0.03435588f, 0.1358287f); + static Keyframe redCurveOfRainbow_atLuminance044_keyframe2 = new Keyframe(0.3333333f, 0.1f, -4.729165f, 0f, 0.2133534f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance044_keyframe3 = new Keyframe(0.41f, 0f, -0.2348027f, 0f, 0.7860962f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance044_keyframe4 = new Keyframe(0.6666667f, 0f, 0f, 28.39604f, 0.0103105f, 0.1390375f); + static Keyframe redCurveOfRainbow_atLuminance044_keyframe5 = new Keyframe(0.8333333f, 1f, 6.455942f, 0f, 0.3989304f, 0.01595771f); + static Keyframe redCurveOfRainbow_atLuminance044_keyframe6 = new Keyframe(1f, 1f, 0f, 0f, 0.02324617f, 0f); + static AnimationCurve redCurveOfRainbow_atLuminance044 = new AnimationCurve(redCurveOfRainbow_atLuminance044_keyframe0, redCurveOfRainbow_atLuminance044_keyframe1, redCurveOfRainbow_atLuminance044_keyframe2, redCurveOfRainbow_atLuminance044_keyframe3, redCurveOfRainbow_atLuminance044_keyframe4, redCurveOfRainbow_atLuminance044_keyframe5, redCurveOfRainbow_atLuminance044_keyframe6); + + static Keyframe greenCurveOfRainbow_atLuminance044_keyframe0 = new Keyframe(0f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance044_keyframe1 = new Keyframe(0.257754f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance044_keyframe2 = new Keyframe(0.333333f, 0.1f, 0f, 3.354114f, 0.003058169f, 0.599824f); + static Keyframe greenCurveOfRainbow_atLuminance044_keyframe3 = new Keyframe(0.4266467f, 0.4177842f, 4.944809f, 4.023407f, 0.2511761f, 0.4652202f); + static Keyframe greenCurveOfRainbow_atLuminance044_keyframe4 = new Keyframe(0.5f, 1f, 10.00402f, 0f, 0.2608117f, 0.007641078f); + static Keyframe greenCurveOfRainbow_atLuminance044_keyframe5 = new Keyframe(0.8333333f, 1f, 0f, -14.82952f, 0.006811738f, 0.2913237f); + static Keyframe greenCurveOfRainbow_atLuminance044_keyframe6 = new Keyframe(0.9234037f, 0.4471004f, -4.054608f, -5.455518f, 0.3919348f, 0.3876472f); + static Keyframe greenCurveOfRainbow_atLuminance044_keyframe7 = new Keyframe(1f, 0f, -17.81115f, -5.54757f, 0.1841612f, 0f); + static AnimationCurve greenCurveOfRainbow_atLuminance044 = new AnimationCurve(greenCurveOfRainbow_atLuminance044_keyframe0, greenCurveOfRainbow_atLuminance044_keyframe1, greenCurveOfRainbow_atLuminance044_keyframe2, greenCurveOfRainbow_atLuminance044_keyframe3, greenCurveOfRainbow_atLuminance044_keyframe4, greenCurveOfRainbow_atLuminance044_keyframe5, greenCurveOfRainbow_atLuminance044_keyframe6, greenCurveOfRainbow_atLuminance044_keyframe7); + + static Keyframe blueCurveOfRainbow_atLuminance044_keyframe0 = new Keyframe(0f, 0f, 5.103677f, 10.5359f, 0f, 0.2193234f); + static Keyframe blueCurveOfRainbow_atLuminance044_keyframe1 = new Keyframe(0.09098038f, 0.3947893f, 4.52334f, 3.623064f, 0.518025f, 0.5643008f); + static Keyframe blueCurveOfRainbow_atLuminance044_keyframe2 = new Keyframe(0.166666f, 1f, 17.27078f, 0f, 0.2237331f, 0.005642463f); + static Keyframe blueCurveOfRainbow_atLuminance044_keyframe3 = new Keyframe(0.5f, 1f, 0f, -16.78093f, 0.01999663f, 0.2947439f); + static Keyframe blueCurveOfRainbow_atLuminance044_keyframe4 = new Keyframe(0.5743871f, 0.5367215f, -4.936384f, -3.610273f, 0.3874579f, 0.2659675f); + static Keyframe blueCurveOfRainbow_atLuminance044_keyframe5 = new Keyframe(0.6666666f, 0f, -17.39986f, 0f, 0.282023f, 0.01547652f); + static Keyframe blueCurveOfRainbow_atLuminance044_keyframe6 = new Keyframe(1f, 0f, 0f, 0f, 0f, 0f); + static AnimationCurve blueCurveOfRainbow_atLuminance044 = new AnimationCurve(blueCurveOfRainbow_atLuminance044_keyframe0, blueCurveOfRainbow_atLuminance044_keyframe1, blueCurveOfRainbow_atLuminance044_keyframe2, blueCurveOfRainbow_atLuminance044_keyframe3, blueCurveOfRainbow_atLuminance044_keyframe4, blueCurveOfRainbow_atLuminance044_keyframe5, blueCurveOfRainbow_atLuminance044_keyframe6); + + static Keyframe luminanceTargetCurveOfRainbow_atLuminance044_keyframe0 = new Keyframe(0f, 1.3f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance044_keyframe1 = new Keyframe(0.1666666f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance044_keyframe2 = new Keyframe(0.3333333f, 1.3f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance044_keyframe3 = new Keyframe(0.5f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance044_keyframe4 = new Keyframe(0.8333333f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance044_keyframe5 = new Keyframe(1f, 1.3f, 0f, 0f, 0f, 0f); + static AnimationCurve luminanceTargetCurveOfRainbow_atLuminance044 = new AnimationCurve(luminanceTargetCurveOfRainbow_atLuminance044_keyframe0, luminanceTargetCurveOfRainbow_atLuminance044_keyframe1, luminanceTargetCurveOfRainbow_atLuminance044_keyframe2, luminanceTargetCurveOfRainbow_atLuminance044_keyframe3, luminanceTargetCurveOfRainbow_atLuminance044_keyframe4, luminanceTargetCurveOfRainbow_atLuminance044_keyframe5); + + static Keyframe redCurveOfRainbow_atLuminance040_keyframe0 = new Keyframe(0f, 1f, 0f, 0f, 0f, 0.0267929f); + static Keyframe redCurveOfRainbow_atLuminance040_keyframe1 = new Keyframe(0.1666667f, 1f, 0f, -21.46155f, 0.03435588f, 0.1358287f); + static Keyframe redCurveOfRainbow_atLuminance040_keyframe2 = new Keyframe(0.3333333f, 0.1f, -4.729165f, 0f, 0.2133534f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance040_keyframe3 = new Keyframe(0.5f, 0.1f, -0.02962309f, -13.02118f, 0.2406417f, 0.04171121f); + static Keyframe redCurveOfRainbow_atLuminance040_keyframe4 = new Keyframe(0.6666667f, 0f, 0.01826039f, 14.58432f, 0.7786098f, 0.2614246f); + static Keyframe redCurveOfRainbow_atLuminance040_keyframe5 = new Keyframe(0.7071924f, 0.485076f, 6.289471f, 3.807689f, 0.7160985f, 0.5661704f); + static Keyframe redCurveOfRainbow_atLuminance040_keyframe6 = new Keyframe(0.8333333f, 0.7555728f, 4.005681f, 1.052538f, 0.3659997f, 0.3454545f); + static Keyframe redCurveOfRainbow_atLuminance040_keyframe7 = new Keyframe(1f, 1f, 2.362824f, 0f, 0.2631014f, 0f); + static AnimationCurve redCurveOfRainbow_atLuminance040 = new AnimationCurve(redCurveOfRainbow_atLuminance040_keyframe0, redCurveOfRainbow_atLuminance040_keyframe1, redCurveOfRainbow_atLuminance040_keyframe2, redCurveOfRainbow_atLuminance040_keyframe3, redCurveOfRainbow_atLuminance040_keyframe4, redCurveOfRainbow_atLuminance040_keyframe5, redCurveOfRainbow_atLuminance040_keyframe6, redCurveOfRainbow_atLuminance040_keyframe7); + + static Keyframe greenCurveOfRainbow_atLuminance040_keyframe0 = new Keyframe(0f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance040_keyframe1 = new Keyframe(0.257754f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance040_keyframe2 = new Keyframe(0.333333f, 0.1f, 0f, 28.33642f, 0.003058169f, 0.02803065f); + static Keyframe greenCurveOfRainbow_atLuminance040_keyframe3 = new Keyframe(0.4223742f, 0.4059434f, 4.689831f, 4.023407f, 0.455475f, 0.4652202f); + static Keyframe greenCurveOfRainbow_atLuminance040_keyframe4 = new Keyframe(0.4989319f, 1f, 10.67839f, 0f, 0.2724356f, 0.007641078f); + static Keyframe greenCurveOfRainbow_atLuminance040_keyframe5 = new Keyframe(0.666666f, 1f, 0f, -3.810817f, 0.006811738f, 0.2820041f); + static Keyframe greenCurveOfRainbow_atLuminance040_keyframe6 = new Keyframe(0.8266703f, 0.6480225f, -1.449353f, -2.16764f, 0.4432741f, 0.402506f); + static Keyframe greenCurveOfRainbow_atLuminance040_keyframe7 = new Keyframe(0.9405828f, 0.3847077f, -3.07261f, -3.760881f, 0.5782549f, 0.6939976f); + static Keyframe greenCurveOfRainbow_atLuminance040_keyframe8 = new Keyframe(1f, -0.004608155f, -6.25816f, -5.54757f, 0.3911783f, 0f); + static AnimationCurve greenCurveOfRainbow_atLuminance040 = new AnimationCurve(greenCurveOfRainbow_atLuminance040_keyframe0, greenCurveOfRainbow_atLuminance040_keyframe1, greenCurveOfRainbow_atLuminance040_keyframe2, greenCurveOfRainbow_atLuminance040_keyframe3, greenCurveOfRainbow_atLuminance040_keyframe4, greenCurveOfRainbow_atLuminance040_keyframe5, greenCurveOfRainbow_atLuminance040_keyframe6, greenCurveOfRainbow_atLuminance040_keyframe7, greenCurveOfRainbow_atLuminance040_keyframe8); + + static Keyframe blueCurveOfRainbow_atLuminance040_keyframe0 = new Keyframe(0f, 0f, 5.103677f, 13.03066f, 0f, 0.2586207f); + static Keyframe blueCurveOfRainbow_atLuminance040_keyframe1 = new Keyframe(0.09098038f, 0.3947893f, 4.52334f, 3.623064f, 0.518025f, 0.5643008f); + static Keyframe blueCurveOfRainbow_atLuminance040_keyframe2 = new Keyframe(0.166666f, 1f, 17.27078f, 0f, 0.2237331f, 0.005642463f); + static Keyframe blueCurveOfRainbow_atLuminance040_keyframe3 = new Keyframe(0.333333f, 1f, -0.06550641f, 0f, 0.2160403f, 0.005642463f); + static Keyframe blueCurveOfRainbow_atLuminance040_keyframe4 = new Keyframe(0.5f, 1f, 1.894388f, -10.71091f, 0.4780738f, 0.352255f); + static Keyframe blueCurveOfRainbow_atLuminance040_keyframe5 = new Keyframe(0.5743871f, 0.5367215f, -4.936384f, -3.610273f, 0.3874579f, 0.2659675f); + static Keyframe blueCurveOfRainbow_atLuminance040_keyframe6 = new Keyframe(0.6666666f, 0f, -17.39986f, 0f, 0.282023f, 0.01547652f); + static Keyframe blueCurveOfRainbow_atLuminance040_keyframe7 = new Keyframe(1f, 0f, 0f, 0f, 0f, 0f); + static AnimationCurve blueCurveOfRainbow_atLuminance040 = new AnimationCurve(blueCurveOfRainbow_atLuminance040_keyframe0, blueCurveOfRainbow_atLuminance040_keyframe1, blueCurveOfRainbow_atLuminance040_keyframe2, blueCurveOfRainbow_atLuminance040_keyframe3, blueCurveOfRainbow_atLuminance040_keyframe4, blueCurveOfRainbow_atLuminance040_keyframe5, blueCurveOfRainbow_atLuminance040_keyframe6, blueCurveOfRainbow_atLuminance040_keyframe7); + + static Keyframe luminanceTargetCurveOfRainbow_atLuminance040_keyframe0 = new Keyframe(0f, 1f, 0f, 0.006816681f, 0f, 0.2125848f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance040_keyframe1 = new Keyframe(0.33333f, 1.3f, 4.02498f, -4.666481f, 0.215308f, 0.3330204f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance040_keyframe2 = new Keyframe(0.5f, 0.8f, 1.246914f, 1.343871f, 0.4983332f, 0.3648783f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance040_keyframe3 = new Keyframe(0.66666f, 0.8f, 0.1161369f, 8.206551f, 0.08776538f, 0.174981f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance040_keyframe4 = new Keyframe(0.7430212f, 1.022459f, 1.236433f, 1.362377f, 0.3987748f, 0.5715872f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance040_keyframe5 = new Keyframe(0.833333f, 1.168779f, 5.622433f, -0.4000894f, 0.2310172f, 0.3592924f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance040_keyframe6 = new Keyframe(0.9692383f, 1f, -10.4096f, 0f, 0.1525469f, 0f); + static AnimationCurve luminanceTargetCurveOfRainbow_atLuminance040 = new AnimationCurve(luminanceTargetCurveOfRainbow_atLuminance040_keyframe0, luminanceTargetCurveOfRainbow_atLuminance040_keyframe1, luminanceTargetCurveOfRainbow_atLuminance040_keyframe2, luminanceTargetCurveOfRainbow_atLuminance040_keyframe3, luminanceTargetCurveOfRainbow_atLuminance040_keyframe4, luminanceTargetCurveOfRainbow_atLuminance040_keyframe5, luminanceTargetCurveOfRainbow_atLuminance040_keyframe6); + + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe0 = new Keyframe(0f, 1f, 0f, 0f, 0f, 0.0267929f); + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe1 = new Keyframe(0.1666666f, 1f, 0f, -62.98078f, 0.03435588f, 0.05243218f); + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe2 = new Keyframe(0.2312603f, 0.4656304f, -5.133174f, -5.133174f, 0.3522511f, 0.3878298f); + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe3 = new Keyframe(0.3333333f, 0.1f, -4.912827f, 0f, 0.436582f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe4 = new Keyframe(0.41f, 0f, -0.2348027f, 0.07194741f, 0.7860962f, 0.3642307f); + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe5 = new Keyframe(0.5f, 0.15f, 12.79003f, -32.79271f, 0.124777f, 0.05083349f); + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe6 = new Keyframe(0.5946785f, 0.001490435f, -0.1213733f, -0.03375284f, 0.4860174f, 0.2922802f); + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe7 = new Keyframe(0.6666666f, 0.1f, 8.413258f, 5.895631f, 0.1535204f, 0.445222f); + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe8 = new Keyframe(0.704013f, 0.3859394f, 6.607747f, 4.422125f, 0.2726335f, 0.5933781f); + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe9 = new Keyframe(0.833333f, 1f, 3.091813f, -0.03322281f, 0.772702f, 0.4352952f); + static Keyframe redCurveOfRainbow_atLuminance0325_keyframe10 = new Keyframe(1f, 1f, -0.1315563f, 0f, 0.2181816f, 0f); + static AnimationCurve redCurveOfRainbow_atLuminance0325 = new AnimationCurve(redCurveOfRainbow_atLuminance0325_keyframe0, redCurveOfRainbow_atLuminance0325_keyframe1, redCurveOfRainbow_atLuminance0325_keyframe2, redCurveOfRainbow_atLuminance0325_keyframe3, redCurveOfRainbow_atLuminance0325_keyframe4, redCurveOfRainbow_atLuminance0325_keyframe5, redCurveOfRainbow_atLuminance0325_keyframe6, redCurveOfRainbow_atLuminance0325_keyframe7, redCurveOfRainbow_atLuminance0325_keyframe8, redCurveOfRainbow_atLuminance0325_keyframe9, redCurveOfRainbow_atLuminance0325_keyframe10); + + static Keyframe greenCurveOfRainbow_atLuminance0325_keyframe0 = new Keyframe(0f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance0325_keyframe1 = new Keyframe(0.257754f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance0325_keyframe2 = new Keyframe(0.333333f, 0.1f, 0f, 27.62473f, 0.003058169f, 0.01461566f); + static Keyframe greenCurveOfRainbow_atLuminance0325_keyframe3 = new Keyframe(0.4309248f, 0.4177842f, 4.390889f, 4.307955f, 0.42647f, 0.4129865f); + static Keyframe greenCurveOfRainbow_atLuminance0325_keyframe4 = new Keyframe(0.5010681f, 0.8421326f, 10.00402f, 0f, 0.2608117f, 0.007641078f); + static Keyframe greenCurveOfRainbow_atLuminance0325_keyframe5 = new Keyframe(0.66666f, 0.8377342f, 0f, 31.03253f, 0.006811738f, 0.02356853f); + static Keyframe greenCurveOfRainbow_atLuminance0325_keyframe6 = new Keyframe(0.8333333f, 1f, -1.449353f, -3.562928f, 0.4432741f, 0.2856619f); + static Keyframe greenCurveOfRainbow_atLuminance0325_keyframe7 = new Keyframe(1f, 0.1f, -10.88458f, -5.54757f, 0.1603991f, 0f); + static AnimationCurve greenCurveOfRainbow_atLuminance0325 = new AnimationCurve(greenCurveOfRainbow_atLuminance0325_keyframe0, greenCurveOfRainbow_atLuminance0325_keyframe1, greenCurveOfRainbow_atLuminance0325_keyframe2, greenCurveOfRainbow_atLuminance0325_keyframe3, greenCurveOfRainbow_atLuminance0325_keyframe4, greenCurveOfRainbow_atLuminance0325_keyframe5, greenCurveOfRainbow_atLuminance0325_keyframe6, greenCurveOfRainbow_atLuminance0325_keyframe7); + + static Keyframe blueCurveOfRainbow_atLuminance0325_keyframe0 = new Keyframe(0f, 0.1f, 5.103677f, 8.752334f, 0f, 0.1758645f); + static Keyframe blueCurveOfRainbow_atLuminance0325_keyframe1 = new Keyframe(0.09132262f, 0.5363793f, 4.945463f, 4.945463f, 0.387399f, 0.3577237f); + static Keyframe blueCurveOfRainbow_atLuminance0325_keyframe2 = new Keyframe(0.166666f, 1f, 5.200615f, 0f, 0.2529558f, 0.005642463f); + static Keyframe blueCurveOfRainbow_atLuminance0325_keyframe3 = new Keyframe(0.5f, 1f, 0f, -5.748352f, 0.01999663f, 0.6307411f); + static Keyframe blueCurveOfRainbow_atLuminance0325_keyframe4 = new Keyframe(0.5914994f, 0.4423819f, -4.936384f, -5.070686f, 0.3874579f, 0.2775002f); + static Keyframe blueCurveOfRainbow_atLuminance0325_keyframe5 = new Keyframe(0.6666666f, 0.1f, -8.185369f, -4.944241f, 0.4558724f, 0.2835832f); + static Keyframe blueCurveOfRainbow_atLuminance0325_keyframe6 = new Keyframe(0.7144385f, 0f, -0.6431804f, 0f, 0.5373129f, 0.01948809f); + static Keyframe blueCurveOfRainbow_atLuminance0325_keyframe7 = new Keyframe(1.001099f, 0.1f, 0.419374f, 0f, 0.3433503f, 0f); + static AnimationCurve blueCurveOfRainbow_atLuminance0325 = new AnimationCurve(blueCurveOfRainbow_atLuminance0325_keyframe0, blueCurveOfRainbow_atLuminance0325_keyframe1, blueCurveOfRainbow_atLuminance0325_keyframe2, blueCurveOfRainbow_atLuminance0325_keyframe3, blueCurveOfRainbow_atLuminance0325_keyframe4, blueCurveOfRainbow_atLuminance0325_keyframe5, blueCurveOfRainbow_atLuminance0325_keyframe6, blueCurveOfRainbow_atLuminance0325_keyframe7); + + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0325_keyframe0 = new Keyframe(0f, 0.7f, 0f, -1.716568f, 0f, 0.5813318f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0325_keyframe1 = new Keyframe(0.333333f, 1f, 2.374693f, 0f, 0.3904677f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0325_keyframe2 = new Keyframe(0.66666f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0325_keyframe3 = new Keyframe(0.833333f, 1.25f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0325_keyframe4 = new Keyframe(0.9692383f, 0.7f, -15.0162f, 0f, 0.1678049f, 0f); + static AnimationCurve luminanceTargetCurveOfRainbow_atLuminance0325 = new AnimationCurve(luminanceTargetCurveOfRainbow_atLuminance0325_keyframe0, luminanceTargetCurveOfRainbow_atLuminance0325_keyframe1, luminanceTargetCurveOfRainbow_atLuminance0325_keyframe2, luminanceTargetCurveOfRainbow_atLuminance0325_keyframe3, luminanceTargetCurveOfRainbow_atLuminance0325_keyframe4); + + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe0 = new Keyframe(0.00320816f, 0.7815781f, 0f, 0.3580622f, 0f, 0.1108752f); + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe1 = new Keyframe(0.1666666f, 1f, 0f, -62.98078f, 0.03435588f, 0.05243218f); + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe2 = new Keyframe(0.2312603f, 0.4656304f, -5.133174f, -5.133174f, 0.3522511f, 0.3878298f); + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe3 = new Keyframe(0.3333333f, 0.1f, -4.912827f, 0f, 0.436582f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe4 = new Keyframe(0.41f, 0f, -0.2348027f, 1.364813f, 0.7860962f, 0.3482143f); + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe5 = new Keyframe(0.5010681f, 0.15f, -0.003825905f, -2.337732f, 0.5930647f, 0.3713345f); + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe6 = new Keyframe(0.5946785f, 0.001490435f, -0.1213733f, -0.03375284f, 0.4860174f, 0.2922802f); + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe7 = new Keyframe(0.6666666f, 0.1f, 8.413258f, 5.895631f, 0.1535204f, 0.445222f); + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe8 = new Keyframe(0.704013f, 0.3859394f, 4.497206f, 5.18395f, 0.4940645f, 0.4610528f); + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe9 = new Keyframe(0.833333f, 1f, 3.091813f, -2.025448f, 0.772702f, 0.289987f); + static Keyframe redCurveOfRainbow_atLuminance0275_keyframe10 = new Keyframe(1.001038f, 0.7013932f, 0.06829919f, 0f, 0.2863593f, 0f); + static AnimationCurve redCurveOfRainbow_atLuminance0275 = new AnimationCurve(redCurveOfRainbow_atLuminance0275_keyframe0, redCurveOfRainbow_atLuminance0275_keyframe1, redCurveOfRainbow_atLuminance0275_keyframe2, redCurveOfRainbow_atLuminance0275_keyframe3, redCurveOfRainbow_atLuminance0275_keyframe4, redCurveOfRainbow_atLuminance0275_keyframe5, redCurveOfRainbow_atLuminance0275_keyframe6, redCurveOfRainbow_atLuminance0275_keyframe7, redCurveOfRainbow_atLuminance0275_keyframe8, redCurveOfRainbow_atLuminance0275_keyframe9, redCurveOfRainbow_atLuminance0275_keyframe10); + + static Keyframe greenCurveOfRainbow_atLuminance0275_keyframe0 = new Keyframe(0f, 0.25f, 0f, -5.423751f, 0f, 0.2033195f); + static Keyframe greenCurveOfRainbow_atLuminance0275_keyframe1 = new Keyframe(0.257754f, 0f, 0f, 0f, 0f, 0.00778269f); + static Keyframe greenCurveOfRainbow_atLuminance0275_keyframe2 = new Keyframe(0.333333f, 0.1f, 0f, 16.91939f, 0.003058169f, 0.03653381f); + static Keyframe greenCurveOfRainbow_atLuminance0275_keyframe3 = new Keyframe(0.4309248f, 0.4177842f, 4.390889f, 4.307955f, 0.42647f, 0.4129865f); + static Keyframe greenCurveOfRainbow_atLuminance0275_keyframe4 = new Keyframe(0.5010681f, 0.8421326f, 10.00402f, 0f, 0.2608117f, 0.007641078f); + static Keyframe greenCurveOfRainbow_atLuminance0275_keyframe5 = new Keyframe(0.66666f, 0.8377342f, 0f, 31.03253f, 0.006811738f, 0.02356853f); + static Keyframe greenCurveOfRainbow_atLuminance0275_keyframe6 = new Keyframe(0.8333333f, 1f, -1.449353f, -3.562928f, 0.4432741f, 0.2856619f); + static Keyframe greenCurveOfRainbow_atLuminance0275_keyframe7 = new Keyframe(1f, 0.25f, -0.5542867f, -5.54757f, 0.3016044f, 0f); + static AnimationCurve greenCurveOfRainbow_atLuminance0275 = new AnimationCurve(greenCurveOfRainbow_atLuminance0275_keyframe0, greenCurveOfRainbow_atLuminance0275_keyframe1, greenCurveOfRainbow_atLuminance0275_keyframe2, greenCurveOfRainbow_atLuminance0275_keyframe3, greenCurveOfRainbow_atLuminance0275_keyframe4, greenCurveOfRainbow_atLuminance0275_keyframe5, greenCurveOfRainbow_atLuminance0275_keyframe6, greenCurveOfRainbow_atLuminance0275_keyframe7); + + static Keyframe blueCurveOfRainbow_atLuminance0275_keyframe0 = new Keyframe(0f, 0.25f, 5.103677f, 11.81485f, 0f, 0.1369982f); + static Keyframe blueCurveOfRainbow_atLuminance0275_keyframe1 = new Keyframe(0.08596926f, 0.6425111f, 4.945463f, 3.843233f, 0.387399f, 0.4074239f); + static Keyframe blueCurveOfRainbow_atLuminance0275_keyframe2 = new Keyframe(0.166666f, 1f, 3.406605f, 0f, 0.8813255f, 0.005642463f); + static Keyframe blueCurveOfRainbow_atLuminance0275_keyframe3 = new Keyframe(0.5f, 1f, 0f, -4.492854f, 0.01999663f, 0.7253633f); + static Keyframe blueCurveOfRainbow_atLuminance0275_keyframe4 = new Keyframe(0.6107255f, 0.489562f, -4.936384f, -5.070686f, 0.3874579f, 0.2775002f); + static Keyframe blueCurveOfRainbow_atLuminance0275_keyframe5 = new Keyframe(0.6666666f, 0.1f, -8.185369f, -4.944241f, 0.4558724f, 0.2835832f); + static Keyframe blueCurveOfRainbow_atLuminance0275_keyframe6 = new Keyframe(0.7144385f, 0f, -0.6431804f, 1.59352f, 0.5373129f, 0.4285358f); + static Keyframe blueCurveOfRainbow_atLuminance0275_keyframe7 = new Keyframe(1.001099f, 0.25f, 3.545919f, 0f, 0.306275f, 0f); + static AnimationCurve blueCurveOfRainbow_atLuminance0275 = new AnimationCurve(blueCurveOfRainbow_atLuminance0275_keyframe0, blueCurveOfRainbow_atLuminance0275_keyframe1, blueCurveOfRainbow_atLuminance0275_keyframe2, blueCurveOfRainbow_atLuminance0275_keyframe3, blueCurveOfRainbow_atLuminance0275_keyframe4, blueCurveOfRainbow_atLuminance0275_keyframe5, blueCurveOfRainbow_atLuminance0275_keyframe6, blueCurveOfRainbow_atLuminance0275_keyframe7); + + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0275_keyframe0 = new Keyframe(-0.001037598f, 0.75f, 0f, -14.63627f, 0f, 0.03838513f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0275_keyframe1 = new Keyframe(0.1882049f, 0.497113f, -0.6622246f, -0.2468882f, 0.6106648f, 0.6339823f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0275_keyframe2 = new Keyframe(0.333333f, 1f, 18.33286f, 0f, 0.06071621f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0275_keyframe3 = new Keyframe(0.5f, 0.96f, -2.330969f, 7.099766f, 0.1140539f, 0.04144035f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0275_keyframe4 = new Keyframe(0.66666f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0275_keyframe5 = new Keyframe(0.833333f, 1.212746f, 0f, -1.323475f, 0f, 0.4565187f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0275_keyframe6 = new Keyframe(0.9129034f, 0.9447585f, -3.983558f, -3.688873f, 0.3326225f, 0.3312222f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0275_keyframe7 = new Keyframe(0.9692383f, 0.75f, -1.734095f, 0f, 0.422055f, 0f); + static AnimationCurve luminanceTargetCurveOfRainbow_atLuminance0275 = new AnimationCurve(luminanceTargetCurveOfRainbow_atLuminance0275_keyframe0, luminanceTargetCurveOfRainbow_atLuminance0275_keyframe1, luminanceTargetCurveOfRainbow_atLuminance0275_keyframe2, luminanceTargetCurveOfRainbow_atLuminance0275_keyframe3, luminanceTargetCurveOfRainbow_atLuminance0275_keyframe4, luminanceTargetCurveOfRainbow_atLuminance0275_keyframe5, luminanceTargetCurveOfRainbow_atLuminance0275_keyframe6, luminanceTargetCurveOfRainbow_atLuminance0275_keyframe7); + + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe0 = new Keyframe(0.00320816f, 0.7815781f, 0f, 0.3580622f, 0f, 0.1108752f); + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe1 = new Keyframe(0.1666666f, 1f, 0f, -8.082616f, 0.03435588f, 0.3589919f); + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe2 = new Keyframe(0.2643566f, 0.4491204f, -3.816614f, -5.133174f, 0.3135815f, 0.3878298f); + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe3 = new Keyframe(0.3333333f, 0.151f, -4.912827f, 0f, 0.436582f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe4 = new Keyframe(0.41f, 0f, -0.2348027f, 1.364813f, 0.7860962f, 0.3482143f); + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe5 = new Keyframe(0.5010681f, 0.15f, -0.003825905f, -2.337732f, 0.5930647f, 0.3713345f); + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe6 = new Keyframe(0.5946785f, 0.001490435f, -0.1213733f, -0.03375284f, 0.4860174f, 0.2922802f); + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe7 = new Keyframe(0.6666666f, 0.1f, 8.413258f, 5.895631f, 0.1535204f, 0.445222f); + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe8 = new Keyframe(0.704013f, 0.3859394f, 4.497206f, 5.18395f, 0.4940645f, 0.4610528f); + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe9 = new Keyframe(0.833333f, 1f, 3.091813f, -2.025448f, 0.772702f, 0.289987f); + static Keyframe redCurveOfRainbow_atLuminance0175_keyframe10 = new Keyframe(1.001038f, 0.7013932f, 0.06829919f, 0f, 0.2863593f, 0f); + static AnimationCurve redCurveOfRainbow_atLuminance0175 = new AnimationCurve(redCurveOfRainbow_atLuminance0175_keyframe0, redCurveOfRainbow_atLuminance0175_keyframe1, redCurveOfRainbow_atLuminance0175_keyframe2, redCurveOfRainbow_atLuminance0175_keyframe3, redCurveOfRainbow_atLuminance0175_keyframe4, redCurveOfRainbow_atLuminance0175_keyframe5, redCurveOfRainbow_atLuminance0175_keyframe6, redCurveOfRainbow_atLuminance0175_keyframe7, redCurveOfRainbow_atLuminance0175_keyframe8, redCurveOfRainbow_atLuminance0175_keyframe9, redCurveOfRainbow_atLuminance0175_keyframe10); + + static Keyframe greenCurveOfRainbow_atLuminance0175_keyframe0 = new Keyframe(0f, 0.25f, 0f, -1.662345f, 0f, 0.6721992f); + static Keyframe greenCurveOfRainbow_atLuminance0175_keyframe1 = new Keyframe(0.257754f, 0f, 0f, 0.2219158f, 0f, 0.3396244f); + static Keyframe greenCurveOfRainbow_atLuminance0175_keyframe2 = new Keyframe(0.333333f, 0.1514221f, 2.628582f, 16.91939f, 0.4622616f, 0.03653381f); + static Keyframe greenCurveOfRainbow_atLuminance0175_keyframe3 = new Keyframe(0.4309248f, 0.4177842f, 4.390889f, 4.307955f, 0.42647f, 0.4129865f); + static Keyframe greenCurveOfRainbow_atLuminance0175_keyframe4 = new Keyframe(0.5010681f, 0.8421326f, 10.00402f, 0f, 0.2608117f, 0.007641078f); + static Keyframe greenCurveOfRainbow_atLuminance0175_keyframe5 = new Keyframe(0.66666f, 0.8377342f, 0f, 31.03253f, 0.006811738f, 0.02356853f); + static Keyframe greenCurveOfRainbow_atLuminance0175_keyframe6 = new Keyframe(0.8333333f, 1f, -1.449353f, -3.562928f, 0.4432741f, 0.2856619f); + static Keyframe greenCurveOfRainbow_atLuminance0175_keyframe7 = new Keyframe(1f, 0.25f, -0.5542867f, -5.54757f, 0.3016044f, 0f); + static AnimationCurve greenCurveOfRainbow_atLuminance0175 = new AnimationCurve(greenCurveOfRainbow_atLuminance0175_keyframe0, greenCurveOfRainbow_atLuminance0175_keyframe1, greenCurveOfRainbow_atLuminance0175_keyframe2, greenCurveOfRainbow_atLuminance0175_keyframe3, greenCurveOfRainbow_atLuminance0175_keyframe4, greenCurveOfRainbow_atLuminance0175_keyframe5, greenCurveOfRainbow_atLuminance0175_keyframe6, greenCurveOfRainbow_atLuminance0175_keyframe7); + + static Keyframe blueCurveOfRainbow_atLuminance0175_keyframe0 = new Keyframe(0f, 0.25f, 5.103677f, 11.81485f, 0f, 0.1369982f); + static Keyframe blueCurveOfRainbow_atLuminance0175_keyframe1 = new Keyframe(0.08489856f, 0.6495866f, 2.646874f, 3.249499f, 0.5640966f, 0.680275f); + static Keyframe blueCurveOfRainbow_atLuminance0175_keyframe2 = new Keyframe(0.1473939f, 0.9339607f, 4.998507f, 19.57937f, 0.4651634f, 0.06425192f); + static Keyframe blueCurveOfRainbow_atLuminance0175_keyframe3 = new Keyframe(0.3030017f, 0.837265f, 0.1810475f, 0f, 0.531534f, 0.005642463f); + static Keyframe blueCurveOfRainbow_atLuminance0175_keyframe4 = new Keyframe(0.5f, 1f, 0f, -4.492854f, 0.01999663f, 0.7253633f); + static Keyframe blueCurveOfRainbow_atLuminance0175_keyframe5 = new Keyframe(0.6107255f, 0.489562f, -4.936384f, -5.070686f, 0.3874579f, 0.2775002f); + static Keyframe blueCurveOfRainbow_atLuminance0175_keyframe6 = new Keyframe(0.6666666f, 0.1f, -8.185369f, -4.944241f, 0.4558724f, 0.2835832f); + static Keyframe blueCurveOfRainbow_atLuminance0175_keyframe7 = new Keyframe(0.7144385f, 0f, -0.6431804f, 1.59352f, 0.5373129f, 0.4285358f); + static Keyframe blueCurveOfRainbow_atLuminance0175_keyframe8 = new Keyframe(1.001099f, 0.25f, 3.545919f, 0f, 0.306275f, 0f); + static AnimationCurve blueCurveOfRainbow_atLuminance0175 = new AnimationCurve(blueCurveOfRainbow_atLuminance0175_keyframe0, blueCurveOfRainbow_atLuminance0175_keyframe1, blueCurveOfRainbow_atLuminance0175_keyframe2, blueCurveOfRainbow_atLuminance0175_keyframe3, blueCurveOfRainbow_atLuminance0175_keyframe4, blueCurveOfRainbow_atLuminance0175_keyframe5, blueCurveOfRainbow_atLuminance0175_keyframe6, blueCurveOfRainbow_atLuminance0175_keyframe7, blueCurveOfRainbow_atLuminance0175_keyframe8); + + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0175_keyframe0 = new Keyframe(0f, 0.7969055f, 0f, -1.238152f, 0f, 0.2999468f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0175_keyframe1 = new Keyframe(0.1353185f, 0.5177611f, -3.722492f, -2.240829f, 0.1552123f, 0.2174204f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0175_keyframe2 = new Keyframe(0.289876f, 0.3924408f, 1.735897f, 1.634704f, 0.3291568f, 0.3739646f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0175_keyframe3 = new Keyframe(0.5f, 0.96f, -2.330969f, 7.099766f, 0.1140539f, 0.04144035f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0175_keyframe4 = new Keyframe(0.66666f, 1f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0175_keyframe5 = new Keyframe(0.833333f, 1.212746f, 0f, -1.323475f, 0f, 0.4565187f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0175_keyframe6 = new Keyframe(0.9129034f, 0.9447585f, -3.983558f, -3.688873f, 0.3326225f, 0.3312222f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance0175_keyframe7 = new Keyframe(0.9692383f, 0.8300476f, -1.734095f, 0f, 0.422055f, 0f); + static AnimationCurve luminanceTargetCurveOfRainbow_atLuminance0175 = new AnimationCurve(luminanceTargetCurveOfRainbow_atLuminance0175_keyframe0, luminanceTargetCurveOfRainbow_atLuminance0175_keyframe1, luminanceTargetCurveOfRainbow_atLuminance0175_keyframe2, luminanceTargetCurveOfRainbow_atLuminance0175_keyframe3, luminanceTargetCurveOfRainbow_atLuminance0175_keyframe4, luminanceTargetCurveOfRainbow_atLuminance0175_keyframe5, luminanceTargetCurveOfRainbow_atLuminance0175_keyframe6, luminanceTargetCurveOfRainbow_atLuminance0175_keyframe7); + + static Keyframe redCurveOfRainbow_atLuminance005_keyframe0 = new Keyframe(0.00320816f, 0.7815781f, 0f, 0.3580622f, 0f, 0.1108752f); + static Keyframe redCurveOfRainbow_atLuminance005_keyframe1 = new Keyframe(0.1666666f, 1f, 0f, -8.082616f, 0.03435588f, 0.3589919f); + static Keyframe redCurveOfRainbow_atLuminance005_keyframe2 = new Keyframe(0.2643566f, 0.4491204f, -3.816614f, -5.133174f, 0.3135815f, 0.3878298f); + static Keyframe redCurveOfRainbow_atLuminance005_keyframe3 = new Keyframe(0.3333333f, 0.151f, -4.912827f, 0f, 0.436582f, 0.01367907f); + static Keyframe redCurveOfRainbow_atLuminance005_keyframe4 = new Keyframe(0.41f, 0f, -0.2348027f, 1.364813f, 0.7860962f, 0.3482143f); + static Keyframe redCurveOfRainbow_atLuminance005_keyframe5 = new Keyframe(0.5010681f, 0.15f, -0.003825905f, -2.337732f, 0.5930647f, 0.3713345f); + static Keyframe redCurveOfRainbow_atLuminance005_keyframe6 = new Keyframe(0.5946785f, 0.001490435f, -0.1213733f, -0.03375284f, 0.4860174f, 0.2922802f); + static Keyframe redCurveOfRainbow_atLuminance005_keyframe7 = new Keyframe(0.6666666f, 0.1f, 8.413258f, 5.895631f, 0.1535204f, 0.445222f); + static Keyframe redCurveOfRainbow_atLuminance005_keyframe8 = new Keyframe(0.704013f, 0.3859394f, 4.497206f, 5.18395f, 0.4940645f, 0.4610528f); + static Keyframe redCurveOfRainbow_atLuminance005_keyframe9 = new Keyframe(0.833333f, 1f, 3.091813f, -2.025448f, 0.772702f, 0.289987f); + static Keyframe redCurveOfRainbow_atLuminance005_keyframe10 = new Keyframe(1.001038f, 0.7013932f, 0.06829919f, 0f, 0.2863593f, 0f); + static AnimationCurve redCurveOfRainbow_atLuminance005 = new AnimationCurve(redCurveOfRainbow_atLuminance005_keyframe0, redCurveOfRainbow_atLuminance005_keyframe1, redCurveOfRainbow_atLuminance005_keyframe2, redCurveOfRainbow_atLuminance005_keyframe3, redCurveOfRainbow_atLuminance005_keyframe4, redCurveOfRainbow_atLuminance005_keyframe5, redCurveOfRainbow_atLuminance005_keyframe6, redCurveOfRainbow_atLuminance005_keyframe7, redCurveOfRainbow_atLuminance005_keyframe8, redCurveOfRainbow_atLuminance005_keyframe9, redCurveOfRainbow_atLuminance005_keyframe10); + + static Keyframe greenCurveOfRainbow_atLuminance005_keyframe0 = new Keyframe(0f, 0.25f, 0f, -1.662345f, 0f, 0.6721992f); + static Keyframe greenCurveOfRainbow_atLuminance005_keyframe1 = new Keyframe(0.257754f, 0f, 0f, 0.2219158f, 0f, 0.3396244f); + static Keyframe greenCurveOfRainbow_atLuminance005_keyframe2 = new Keyframe(0.333333f, 0.1514221f, 2.628582f, 16.91939f, 0.4622616f, 0.03653381f); + static Keyframe greenCurveOfRainbow_atLuminance005_keyframe3 = new Keyframe(0.4309248f, 0.4177842f, 4.390889f, 4.307955f, 0.42647f, 0.4129865f); + static Keyframe greenCurveOfRainbow_atLuminance005_keyframe4 = new Keyframe(0.5010681f, 0.8421326f, 10.00402f, 0f, 0.2608117f, 0.007641078f); + static Keyframe greenCurveOfRainbow_atLuminance005_keyframe5 = new Keyframe(0.66666f, 0.8377342f, 0f, 31.03253f, 0.006811738f, 0.02356853f); + static Keyframe greenCurveOfRainbow_atLuminance005_keyframe6 = new Keyframe(0.8333333f, 1f, -1.449353f, -3.562928f, 0.4432741f, 0.2856619f); + static Keyframe greenCurveOfRainbow_atLuminance005_keyframe7 = new Keyframe(1f, 0.25f, -0.5542867f, -5.54757f, 0.3016044f, 0f); + static AnimationCurve greenCurveOfRainbow_atLuminance005 = new AnimationCurve(greenCurveOfRainbow_atLuminance005_keyframe0, greenCurveOfRainbow_atLuminance005_keyframe1, greenCurveOfRainbow_atLuminance005_keyframe2, greenCurveOfRainbow_atLuminance005_keyframe3, greenCurveOfRainbow_atLuminance005_keyframe4, greenCurveOfRainbow_atLuminance005_keyframe5, greenCurveOfRainbow_atLuminance005_keyframe6, greenCurveOfRainbow_atLuminance005_keyframe7); + + static Keyframe blueCurveOfRainbow_atLuminance005_keyframe0 = new Keyframe(0f, 0.25f, 5.103677f, 11.81485f, 0f, 0.1369982f); + static Keyframe blueCurveOfRainbow_atLuminance005_keyframe1 = new Keyframe(0.08489856f, 0.6495866f, 2.646874f, 3.249499f, 0.5640966f, 0.680275f); + static Keyframe blueCurveOfRainbow_atLuminance005_keyframe2 = new Keyframe(0.1473939f, 0.9339607f, 4.998507f, 3.770786f, 0.4651634f, 0.1555204f); + static Keyframe blueCurveOfRainbow_atLuminance005_keyframe3 = new Keyframe(0.3392435f, 1.17904f, 3.387797f, -3.471945f, 0.6513343f, 0.5786006f); + static Keyframe blueCurveOfRainbow_atLuminance005_keyframe4 = new Keyframe(0.5f, 1f, 0f, -4.492854f, 0.01999663f, 0.7253633f); + static Keyframe blueCurveOfRainbow_atLuminance005_keyframe5 = new Keyframe(0.6107255f, 0.489562f, -4.936384f, -5.070686f, 0.3874579f, 0.2775002f); + static Keyframe blueCurveOfRainbow_atLuminance005_keyframe6 = new Keyframe(0.6666666f, 0.1f, -8.185369f, -4.944241f, 0.4558724f, 0.2835832f); + static Keyframe blueCurveOfRainbow_atLuminance005_keyframe7 = new Keyframe(0.7144385f, 0f, -0.6431804f, 1.59352f, 0.5373129f, 0.4285358f); + static Keyframe blueCurveOfRainbow_atLuminance005_keyframe8 = new Keyframe(1.001099f, 0.25f, 3.545919f, 0f, 0.306275f, 0f); + static AnimationCurve blueCurveOfRainbow_atLuminance005 = new AnimationCurve(blueCurveOfRainbow_atLuminance005_keyframe0, blueCurveOfRainbow_atLuminance005_keyframe1, blueCurveOfRainbow_atLuminance005_keyframe2, blueCurveOfRainbow_atLuminance005_keyframe3, blueCurveOfRainbow_atLuminance005_keyframe4, blueCurveOfRainbow_atLuminance005_keyframe5, blueCurveOfRainbow_atLuminance005_keyframe6, blueCurveOfRainbow_atLuminance005_keyframe7, blueCurveOfRainbow_atLuminance005_keyframe8); + + static Keyframe luminanceTargetCurveOfRainbow_atLuminance005_keyframe0 = new Keyframe(0f, 0.7969055f, 0f, -0.4345227f, 0f, 0.4554668f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance005_keyframe1 = new Keyframe(0.1477589f, 0.5718302f, -0.3365634f, -0.877695f, 0.3685954f, 0.3002268f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance005_keyframe2 = new Keyframe(0.3189052f, 0.4952482f, 1.555321f, 1.448426f, 0.3855759f, 0.396134f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance005_keyframe3 = new Keyframe(0.500001f, 0.9960338f, 1.386169f, 7.099766f, 0.3321387f, 0.04144035f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance005_keyframe4 = new Keyframe(0.6656224f, 0.9299316f, 0f, 0f, 0f, 0f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance005_keyframe5 = new Keyframe(0.822957f, 1.046589f, -0.107637f, -1.172717f, 0.2380097f, 0.2087598f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance005_keyframe6 = new Keyframe(0.9129034f, 0.9447585f, -3.983558f, -3.688873f, 0.3326225f, 0.3312222f); + static Keyframe luminanceTargetCurveOfRainbow_atLuminance005_keyframe7 = new Keyframe(0.9692383f, 0.8300476f, -1.403513f, 0f, 0.460025f, 0f); + static AnimationCurve luminanceTargetCurveOfRainbow_atLuminance005 = new AnimationCurve(luminanceTargetCurveOfRainbow_atLuminance005_keyframe0, luminanceTargetCurveOfRainbow_atLuminance005_keyframe1, luminanceTargetCurveOfRainbow_atLuminance005_keyframe2, luminanceTargetCurveOfRainbow_atLuminance005_keyframe3, luminanceTargetCurveOfRainbow_atLuminance005_keyframe4, luminanceTargetCurveOfRainbow_atLuminance005_keyframe5, luminanceTargetCurveOfRainbow_atLuminance005_keyframe6, luminanceTargetCurveOfRainbow_atLuminance005_keyframe7); + + public static Color GetIteratingRainbowColor(int iterationStep, float alphaOfGeneratedColor, int numberOfColorsPerSpectrumPass, float lowerBorderOfColorLoop, float higherBorderOfColorLoop, bool sawToothTransition, float forceLuminance) + { + numberOfColorsPerSpectrumPass = Mathf.Max(numberOfColorsPerSpectrumPass, 2); + float progressThroughRainbow_exceedingThe0to1bounds = ((float)iterationStep) / (float)numberOfColorsPerSpectrumPass; + float progressThroughRainbow_as0to1_ifFullSpectrumIsUsed; + if (sawToothTransition) + { + progressThroughRainbow_as0to1_ifFullSpectrumIsUsed = UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_0_to_1(progressThroughRainbow_exceedingThe0to1bounds); + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(progressThroughRainbow_as0to1_ifFullSpectrumIsUsed, 1.0f)) + { + progressThroughRainbow_as0to1_ifFullSpectrumIsUsed = 0.0f; //-> prevents slight inconsistency for the case where the "iterationStep" transitions from negative to positive + } + } + else + { + float progressThroughRainbow_as0to1_ifFullSpectrumIsUsed_cappedTo2 = UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_0_to_x(progressThroughRainbow_exceedingThe0to1bounds, 2.0f); + if (progressThroughRainbow_as0to1_ifFullSpectrumIsUsed_cappedTo2 > 1.0f) + { + progressThroughRainbow_as0to1_ifFullSpectrumIsUsed = 2.0f - progressThroughRainbow_as0to1_ifFullSpectrumIsUsed_cappedTo2; + } + else + { + progressThroughRainbow_as0to1_ifFullSpectrumIsUsed = progressThroughRainbow_as0to1_ifFullSpectrumIsUsed_cappedTo2; + } + } + + float spanOfColorLoop = higherBorderOfColorLoop - lowerBorderOfColorLoop; + float progressThroughRainbow_as0to1InRGBSpace = lowerBorderOfColorLoop + spanOfColorLoop * progressThroughRainbow_as0to1_ifFullSpectrumIsUsed; + if (progressThroughRainbow_as0to1InRGBSpace < 0.0f) + { + progressThroughRainbow_as0to1InRGBSpace = progressThroughRainbow_as0to1InRGBSpace + 1.0f; + } + + float progressThroughRainbow_as0to1InRBGSpace = 1.0f - progressThroughRainbow_as0to1InRGBSpace; //The AnimationCurves were generated in RBG-space (meaning R at 0, B at 0.3333 and G at 0.6666), while the industry convention is RGB (R at 0, G at 0.3333 and B at 0.6666) + Color generatedRainbowColor = default; + if (UtilitiesDXXL_Math.ApproximatelyZero(forceLuminance)) + { + generatedRainbowColor.r = redCurveOfRainbow_atLuminanceNotForced.Evaluate(progressThroughRainbow_as0to1InRBGSpace); + generatedRainbowColor.g = greenCurveOfRainbow_atLuminanceNotForced.Evaluate(progressThroughRainbow_as0to1InRBGSpace); + generatedRainbowColor.b = blueCurveOfRainbow_atLuminanceNotForced.Evaluate(progressThroughRainbow_as0to1InRBGSpace); + generatedRainbowColor = SeededColorGenerator.ForceApproxLuminance(generatedRainbowColor, forceLuminance); + } + else + { + if (forceLuminance > 0.825f) + { + generatedRainbowColor.r = redCurveOfRainbow_atLuminance0825.Evaluate(progressThroughRainbow_as0to1InRBGSpace); + generatedRainbowColor.g = greenCurveOfRainbow_atLuminance0825.Evaluate(progressThroughRainbow_as0to1InRBGSpace); + generatedRainbowColor.b = blueCurveOfRainbow_atLuminance0825.Evaluate(progressThroughRainbow_as0to1InRBGSpace); + generatedRainbowColor = SeededColorGenerator.ForceApproxLuminance(generatedRainbowColor, forceLuminance * luminanceTargetCurveOfRainbow_atLuminance0825.Evaluate(progressThroughRainbow_as0to1InRBGSpace)); + } + else + { + if (forceLuminance > 0.675f) + { + generatedRainbowColor = LerpColorBetweenLuminanceAnchorPoints(0.675f, 0.825f, redCurveOfRainbow_atLuminance0675, greenCurveOfRainbow_atLuminance0675, blueCurveOfRainbow_atLuminance0675, luminanceTargetCurveOfRainbow_atLuminance0675, redCurveOfRainbow_atLuminance0825, greenCurveOfRainbow_atLuminance0825, blueCurveOfRainbow_atLuminance0825, luminanceTargetCurveOfRainbow_atLuminance0825, progressThroughRainbow_as0to1InRBGSpace, forceLuminance); + } + else + { + if (forceLuminance > 0.5f) + { + generatedRainbowColor = LerpColorBetweenLuminanceAnchorPoints(0.5f, 0.675f, redCurveOfRainbow_atLuminance05, greenCurveOfRainbow_atLuminance05, blueCurveOfRainbow_atLuminance05, luminanceTargetCurveOfRainbow_atLuminance05, redCurveOfRainbow_atLuminance0675, greenCurveOfRainbow_atLuminance0675, blueCurveOfRainbow_atLuminance0675, luminanceTargetCurveOfRainbow_atLuminance0675, progressThroughRainbow_as0to1InRBGSpace, forceLuminance); + } + else + { + if (forceLuminance > 0.44f) + { + generatedRainbowColor = LerpColorBetweenLuminanceAnchorPoints(0.44f, 0.5f, redCurveOfRainbow_atLuminance044, greenCurveOfRainbow_atLuminance044, blueCurveOfRainbow_atLuminance044, luminanceTargetCurveOfRainbow_atLuminance044, redCurveOfRainbow_atLuminance05, greenCurveOfRainbow_atLuminance05, blueCurveOfRainbow_atLuminance05, luminanceTargetCurveOfRainbow_atLuminance05, progressThroughRainbow_as0to1InRBGSpace, forceLuminance); + } + else + { + if (forceLuminance > 0.40f) + { + generatedRainbowColor = LerpColorBetweenLuminanceAnchorPoints(0.40f, 0.44f, redCurveOfRainbow_atLuminance040, greenCurveOfRainbow_atLuminance040, blueCurveOfRainbow_atLuminance040, luminanceTargetCurveOfRainbow_atLuminance040, redCurveOfRainbow_atLuminance044, greenCurveOfRainbow_atLuminance044, blueCurveOfRainbow_atLuminance044, luminanceTargetCurveOfRainbow_atLuminance044, progressThroughRainbow_as0to1InRBGSpace, forceLuminance); + } + else + { + if (forceLuminance > 0.325f) + { + generatedRainbowColor = LerpColorBetweenLuminanceAnchorPoints(0.325f, 0.40f, redCurveOfRainbow_atLuminance0325, greenCurveOfRainbow_atLuminance0325, blueCurveOfRainbow_atLuminance0325, luminanceTargetCurveOfRainbow_atLuminance0325, redCurveOfRainbow_atLuminance040, greenCurveOfRainbow_atLuminance040, blueCurveOfRainbow_atLuminance040, luminanceTargetCurveOfRainbow_atLuminance040, progressThroughRainbow_as0to1InRBGSpace, forceLuminance); + } + else + { + if (forceLuminance > 0.275f) + { + generatedRainbowColor = LerpColorBetweenLuminanceAnchorPoints(0.275f, 0.325f, redCurveOfRainbow_atLuminance0275, greenCurveOfRainbow_atLuminance0275, blueCurveOfRainbow_atLuminance0275, luminanceTargetCurveOfRainbow_atLuminance0275, redCurveOfRainbow_atLuminance0325, greenCurveOfRainbow_atLuminance0325, blueCurveOfRainbow_atLuminance0325, luminanceTargetCurveOfRainbow_atLuminance0325, progressThroughRainbow_as0to1InRBGSpace, forceLuminance); + } + else + { + if (forceLuminance > 0.175f) + { + generatedRainbowColor = LerpColorBetweenLuminanceAnchorPoints(0.175f, 0.275f, redCurveOfRainbow_atLuminance0175, greenCurveOfRainbow_atLuminance0175, blueCurveOfRainbow_atLuminance0175, luminanceTargetCurveOfRainbow_atLuminance0175, redCurveOfRainbow_atLuminance0275, greenCurveOfRainbow_atLuminance0275, blueCurveOfRainbow_atLuminance0275, luminanceTargetCurveOfRainbow_atLuminance0275, progressThroughRainbow_as0to1InRBGSpace, forceLuminance); + } + else + { + if (forceLuminance > 0.05f) + { + generatedRainbowColor = LerpColorBetweenLuminanceAnchorPoints(0.05f, 0.175f, redCurveOfRainbow_atLuminance005, greenCurveOfRainbow_atLuminance005, blueCurveOfRainbow_atLuminance005, luminanceTargetCurveOfRainbow_atLuminance005, redCurveOfRainbow_atLuminance0175, greenCurveOfRainbow_atLuminance0175, blueCurveOfRainbow_atLuminance0175, luminanceTargetCurveOfRainbow_atLuminance0175, progressThroughRainbow_as0to1InRBGSpace, forceLuminance); + } + else + { + generatedRainbowColor.r = redCurveOfRainbow_atLuminance005.Evaluate(progressThroughRainbow_as0to1InRBGSpace); + generatedRainbowColor.g = greenCurveOfRainbow_atLuminance005.Evaluate(progressThroughRainbow_as0to1InRBGSpace); + generatedRainbowColor.b = blueCurveOfRainbow_atLuminance005.Evaluate(progressThroughRainbow_as0to1InRBGSpace); + generatedRainbowColor = SeededColorGenerator.ForceApproxLuminance(generatedRainbowColor, forceLuminance * luminanceTargetCurveOfRainbow_atLuminance005.Evaluate(progressThroughRainbow_as0to1InRBGSpace)); + } + } + } + } + } + } + } + } + } + } + + generatedRainbowColor.a = alphaOfGeneratedColor; + return generatedRainbowColor; + } + + static Color LerpColorBetweenLuminanceAnchorPoints(float luminanceMarkingLowerAnchor, float luminanceMarkingHigherAnchor, AnimationCurve animCurve_lowerAnchor_red, AnimationCurve animCurve_lowerAnchor_green, AnimationCurve animCurve_lowerAnchor_blue, AnimationCurve animCurve_lowerAnchor_luminanceTargetValueModifier, AnimationCurve animCurve_higherAnchor_red, AnimationCurve animCurve_higherAnchor_green, AnimationCurve animCurve_higherAnchor_blue, AnimationCurve animCurve_higherAnchor_luminanceTargetValueModifier, float progressThroughRainbow_as0to1, float forceLuminance) + { + Color generatedRainbowColor_atLowerLuminanceAnchor = default; + generatedRainbowColor_atLowerLuminanceAnchor.r = animCurve_lowerAnchor_red.Evaluate(progressThroughRainbow_as0to1); + generatedRainbowColor_atLowerLuminanceAnchor.g = animCurve_lowerAnchor_green.Evaluate(progressThroughRainbow_as0to1); + generatedRainbowColor_atLowerLuminanceAnchor.b = animCurve_lowerAnchor_blue.Evaluate(progressThroughRainbow_as0to1); + generatedRainbowColor_atLowerLuminanceAnchor = SeededColorGenerator.ForceApproxLuminance(generatedRainbowColor_atLowerLuminanceAnchor, forceLuminance * animCurve_lowerAnchor_luminanceTargetValueModifier.Evaluate(progressThroughRainbow_as0to1)); + + Color generatedRainbowColor_atHigherLuminanceAnchor = default; + generatedRainbowColor_atHigherLuminanceAnchor.r = animCurve_higherAnchor_red.Evaluate(progressThroughRainbow_as0to1); + generatedRainbowColor_atHigherLuminanceAnchor.g = animCurve_higherAnchor_green.Evaluate(progressThroughRainbow_as0to1); + generatedRainbowColor_atHigherLuminanceAnchor.b = animCurve_higherAnchor_blue.Evaluate(progressThroughRainbow_as0to1); + generatedRainbowColor_atHigherLuminanceAnchor = SeededColorGenerator.ForceApproxLuminance(generatedRainbowColor_atHigherLuminanceAnchor, forceLuminance * animCurve_higherAnchor_luminanceTargetValueModifier.Evaluate(progressThroughRainbow_as0to1)); + + float luminanceSpan_fromLowerToHigherAnchor = luminanceMarkingHigherAnchor - luminanceMarkingLowerAnchor; + float forceLuminance_portionOverLowerAnchor = forceLuminance - luminanceMarkingLowerAnchor; + float progress0to1_fromLowerLuminanceAnchor_toHigherLuminanceAnchor = forceLuminance_portionOverLowerAnchor / luminanceSpan_fromLowerToHigherAnchor; + return Color.Lerp(generatedRainbowColor_atLowerLuminanceAnchor, generatedRainbowColor_atHigherLuminanceAnchor, progress0to1_fromLowerLuminanceAnchor_toHigherLuminanceAnchor); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Colors.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Colors.cs.meta new file mode 100644 index 0000000..e292f8b --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Colors.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82746f8e8b86a98479d1e05c4cb822c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics.cs new file mode 100644 index 0000000..f059879 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics.cs @@ -0,0 +1,1764 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_DrawBasics + { + public const int maxMaxAllowedDrawnLinesPerFrame = 2000000; //Raising the value alone may not work in some cases, because "DrawXXL_LinesManager.TryUpdateMesh_fromCachedLines.maxSubMeshesOf65535IndexesEach" also limits the maximum value. + public static float lowThreshold_ofLineWidth_forNumberOfThinLinesThatComposeTheThickLine = 0.6f / DrawBasics.Density_ofThickLines; + public static bool useMoreStrutsForFlatPyramidArrow = false; + static float default_vectorConeAngleDeg = 25.0f; //-> this default value is used for default drawing of vectors. + public static float curr_vectorConeAngleDeg = default_vectorConeAngleDeg; //-> Gets temporarily raised when arrows-style lines are drawn. + public static float min_relConeLengthForVectors = 0.005f; + public static float max_relConeLengthForVectors = 0.45f; + public static float min_blinkDurationInSec = 0.02f; + public static float min_lengthOfStripes_ofAlternatingColorLine = 0.001f; + public static Vector3 default_default_textOffsetDirection_forPointTags = new Vector3(0.65f, 1.25f, 0.0f); + + public static LineAnimationProgress Line(Vector3 start, Vector3 end, Color color, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size, float tensionFactor = 1.0f) + { + //-> amplitude specified via vector + return Line(start, end, color, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D, endPlates_size, tensionFactor); + } + + public static LineAnimationProgress Line(Vector3 start, Vector3 end, Color color, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, InternalDXXL_Plane preferredAmplitudePlane, bool flattenThickRoundLineIntoAmplitudePlane, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size, float tensionFactor = 1.0f) + { + //-> amplitude specified via plane + return Line(start, end, color, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, preferredAmplitudePlane, default(Vector3), flattenThickRoundLineIntoAmplitudePlane, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D, endPlates_size, tensionFactor); + } + + static LineAnimationProgress Line(Vector3 start, Vector3 end, Color color, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, InternalDXXL_Plane preferredAmplitudePlane, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size, float tensionFactor) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(alphaFadeOutLength_0to1, "alphaFadeOutLength_0to1")) { return null; } //<- could be refactored to: still draw the line but skip alphaFadeOut + if (style == DrawBasics.LineStyle.solid && (UtilitiesDXXL_Math.ApproximatelyZero(alphaFadeOutLength_0to1) == false)) + { + //-> has no colorFade, but alphaFade uses the same approach: coloring the subLines with different alpha + return DrawLineColorFade_forUsuallyNotSubdividedSolidLines(start, end, color, color, width, text, preferredAmplitudePlane, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D, endPlates_size); + } + else + { + return DrawLine_uniOrMultiColor(start, end, color, default, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, preferredAmplitudePlane, customAmplitudeAndTextDir, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, flattenThickRoundLineIntoAmplitudePlane, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D, endPlates_size, tensionFactor); + } + } + + public static LineAnimationProgress LineColorFade(Vector3 start, Vector3 end, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size, float tensionFactor) + { + //-> amplitude specified via vector + return LineColorFade(start, end, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, null, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D, endPlates_size, tensionFactor); + } + + public static LineAnimationProgress LineColorFade(Vector3 start, Vector3 end, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, InternalDXXL_Plane preferredAmplitudePlane, bool flattenThickRoundLineIntoAmplitudePlane, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size, float tensionFactor) + { + //-> amplitude specified via plane + return LineColorFade(start, end, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, preferredAmplitudePlane, default(Vector3), flattenThickRoundLineIntoAmplitudePlane, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D, endPlates_size, tensionFactor); + } + + static LineAnimationProgress LineColorFade(Vector3 start, Vector3 end, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, InternalDXXL_Plane preferredAmplitudePlane, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size, float tensionFactor) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + + if (style == DrawBasics.LineStyle.solid) + { + return DrawLineColorFade_forUsuallyNotSubdividedSolidLines(start, end, startColor, endColor, width, text, preferredAmplitudePlane, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D, endPlates_size); + } + else + { + return DrawLine_uniOrMultiColor(start, end, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, preferredAmplitudePlane, customAmplitudeAndTextDir, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, flattenThickRoundLineIntoAmplitudePlane, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D, endPlates_size, tensionFactor); + } + } + + static LineAnimationProgress DrawLine_uniOrMultiColor(Vector3 start, Vector3 end, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, InternalDXXL_Plane preferredAmplitudePlane, Vector3 customAmplitudeAndTextDir, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool flattenThickRoundLineIntoAmplitudePlane, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size, float tensionFactor) + { + //"uni or multicolor" is decided by "ThinLine()"/"ThickLine()/TryDrawPerpEndPlates()", depending on if "endColor" is default or specified. + //color fade is realized by coloring the sub lines (that each line style anyway produces) individually. + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stylePatternScaleFactor, "stylePatternScaleFactor")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(animationSpeed, "animationSpeed")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(alphaFadeOutLength_0to1, "alphaFadeOutLength_0to1")) { return null; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start, end)) + { + //DO NOT fallback to "Point()" here, because "Point()" calls "Line()" again, which can create an endless loop. + //PointFallback(); + //Debug.Log("'Line' is not drawn, because start and end are at the same position (" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(start) + ")."); + return precedingLineAnimationProgress; + } + + LineAnimationProgress returned_lineAnimationProgress; + InternalDXXL_AmplitudeDependentLineDetails amplitudeDependentLineDetails = Get_amplitudeDependentLineDetails(start, end, text, flattenThickRoundLineIntoAmplitudePlane, preferredAmplitudePlane, customAmplitudeAndTextDir, width, enlargeSmallTextToThisMinTextSize, style, endPlates_size, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D); + + if (amplitudeDependentLineDetails.isThinLine) + { + returned_lineAnimationProgress = ThinLine(start, end, startColor, endColor, text, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, hiddenByNearerObjects, flattenThickRoundLineIntoAmplitudePlane, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, amplitudeDependentLineDetails, tensionFactor); + } + else + { + returned_lineAnimationProgress = ThickLine(start, end, startColor, endColor, text, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, hiddenByNearerObjects, flattenThickRoundLineIntoAmplitudePlane, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, amplitudeDependentLineDetails, tensionFactor); + } + + TryDrawPerpEndPlates(amplitudeDependentLineDetails.uses_endPlates, amplitudeDependentLineDetails.endPlates_size, amplitudeDependentLineDetails.amplitudeUp_normalized, amplitudeDependentLineDetails.lengthOfDrawnLine, amplitudeDependentLineDetails.lengthOfDrawnLine_isFilled, flattenThickRoundLineIntoAmplitudePlane, start, end, startColor, endColor, durationInSec, hiddenByNearerObjects); + return returned_lineAnimationProgress; + } + + static InternalDXXL_AmplitudeDependentLineDetails Get_amplitudeDependentLineDetails(Vector3 lineStartPos, Vector3 lineEndPos, string text, bool flattenThickRoundLineIntoAmplitudePlane, InternalDXXL_Plane preferredAmplitudePlane, Vector3 customAmplitudeAndTextDir, float width, float enlargeSmallTextToThisMinTextSize, DrawBasics.LineStyle style, float endPlates_size, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D) + { + InternalDXXL_AmplitudeDependentLineDetails amplitudeDependentLineDetails = new InternalDXXL_AmplitudeDependentLineDetails(); + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + if (width < DrawBasics.thinestPossibleNonZeroWidthLine) { width = 0.0f; } + amplitudeDependentLineDetails.lineWidth = width; + amplitudeDependentLineDetails.isThinLine = UtilitiesDXXL_Math.ApproximatelyZero(width); + amplitudeDependentLineDetails.enlargeSmallText = CheckIfSmallTextGetsEnlarged(enlargeSmallTextToThisMinTextSize); + amplitudeDependentLineDetails.style = style; + amplitudeDependentLineDetails.textDrawingIsSkipped_dueToLineIsTooShort = false; + + if (UtilitiesDXXL_Math.FloatIsValid(endPlates_size)) + { + amplitudeDependentLineDetails.uses_endPlates = (UtilitiesDXXL_Math.ApproximatelyZero(endPlates_size) == false); + amplitudeDependentLineDetails.endPlates_size = endPlates_size; + } + else + { + Debug.LogError("The float value 'endPlates_size' is not a valid float, but " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(endPlates_size) + ". End plates drawing is skipped."); + amplitudeDependentLineDetails.uses_endPlates = false; + amplitudeDependentLineDetails.endPlates_size = 0.0f; + } + + Vector3 line_startToEnd = lineEndPos - lineStartPos; + bool lineIsSoShortThatItDoesntHaveADefinedAmplitude = (UtilitiesDXXL_Math.GetBiggestAbsComponent(line_startToEnd) < UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.shortestLineWithDefinedAmplitudeDir); + if (lineIsSoShortThatItDoesntHaveADefinedAmplitude) + { + //This line parameter forcing has simplifying effect on the succeeding "UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.Get_normalized_amplitudeAndTextDirVectors"-call: + //-> "to solid" means: no amplitude is required for the line style anymore (side note: line styles that don't have amplitude (like "dashed") could be preserved (instead of beeing forced to "solid"), but when is it needed in this small order of magnitude?) + //-> "to thin" means: no amplitude is needed for "flattenThickRoundLineIntoAmplitudePlane" or for the "cylidrical hull lines" anymore + //-> the only occasion that still uses the amplitude vectors is "text with enlargeSmallText" -> this will use the cheap fallback directions, that don't care about perpendicularity with the line. + + amplitudeDependentLineDetails.isThinLine = true; + amplitudeDependentLineDetails.lineWidth = 0.0f; + amplitudeDependentLineDetails.style = DrawBasics.LineStyle.solid; + amplitudeDependentLineDetails.uses_endPlates = false; + amplitudeDependentLineDetails.endPlates_size = 0.0f; + if (amplitudeDependentLineDetails.enlargeSmallText == false) { amplitudeDependentLineDetails.textDrawingIsSkipped_dueToLineIsTooShort = true; } + } + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.Get_normalized_amplitudeAndTextDirVectors(out amplitudeDependentLineDetails.amplitudeUp_normalized, out amplitudeDependentLineDetails.textDir_normalized, out amplitudeDependentLineDetails.lengthOfDrawnLine, out amplitudeDependentLineDetails.lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, amplitudeDependentLineDetails.isThinLine, lineIsSoShortThatItDoesntHaveADefinedAmplitude, text, amplitudeDependentLineDetails.textDrawingIsSkipped_dueToLineIsTooShort, amplitudeDependentLineDetails.style, flattenThickRoundLineIntoAmplitudePlane, amplitudeDependentLineDetails.uses_endPlates, preferredAmplitudePlane, customAmplitudeAndTextDir, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D); + return amplitudeDependentLineDetails; + } + + static bool CheckIfSmallTextGetsEnlarged(float enlargeSmallTextToThisMinTextSize) + { + if (UtilitiesDXXL_Math.FloatIsValid(enlargeSmallTextToThisMinTextSize)) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(enlargeSmallTextToThisMinTextSize) == false) + { + return true; + } + } + return false; + } + + public static void DrawCircleSegment(bool isThinLine, Vector3 segmentStartPos, Vector3 segmentEndPos, Color color, float width, float durationInSec, bool hiddenByNearerObjects, bool flattenThickRoundLineIntoCirclePlane, InternalDXXL_Plane circlePlane) + { + Vector3 line_startToEnd = segmentEndPos - segmentStartPos; + bool lineIsSoShortThatItDoesntHaveADefinedAmplitude = false; //<- "UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.Get_normalized_amplitudeAndTextDirVectors" does anyway not use this in the here applying "GetUpAndTextDir_insideAmplitudePlane"-case and the other cases (which require only "lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection" at most) + + InternalDXXL_AmplitudeDependentLineDetails amplitudeDependentLineDetails = new InternalDXXL_AmplitudeDependentLineDetails(); + amplitudeDependentLineDetails.lineWidth = width; + amplitudeDependentLineDetails.isThinLine = isThinLine; + amplitudeDependentLineDetails.enlargeSmallText = false; + amplitudeDependentLineDetails.textDrawingIsSkipped_dueToLineIsTooShort = false; + amplitudeDependentLineDetails.style = DrawBasics.LineStyle.solid; + amplitudeDependentLineDetails.uses_endPlates = false; + amplitudeDependentLineDetails.endPlates_size = 0.0f; + + if (isThinLine) + { + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.Get_normalized_amplitudeAndTextDirVectors(out amplitudeDependentLineDetails.amplitudeUp_normalized, out amplitudeDependentLineDetails.textDir_normalized, out amplitudeDependentLineDetails.lengthOfDrawnLine, out amplitudeDependentLineDetails.lengthOfDrawnLine_isFilled, segmentStartPos, line_startToEnd, isThinLine, lineIsSoShortThatItDoesntHaveADefinedAmplitude, null, false, DrawBasics.LineStyle.solid, flattenThickRoundLineIntoCirclePlane, false, null, default(Vector3), null, false); + ThinLine(segmentStartPos, segmentEndPos, color, default, null, 0.0f, 0.0f, durationInSec, 1.0f, 0.0f, null, hiddenByNearerObjects, flattenThickRoundLineIntoCirclePlane, false, false, amplitudeDependentLineDetails, 1.0f); + } + else + { + if (flattenThickRoundLineIntoCirclePlane) + { + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.Get_normalized_amplitudeAndTextDirVectors(out amplitudeDependentLineDetails.amplitudeUp_normalized, out amplitudeDependentLineDetails.textDir_normalized, out amplitudeDependentLineDetails.lengthOfDrawnLine, out amplitudeDependentLineDetails.lengthOfDrawnLine_isFilled, segmentStartPos, line_startToEnd, isThinLine, lineIsSoShortThatItDoesntHaveADefinedAmplitude, null, false, DrawBasics.LineStyle.solid, flattenThickRoundLineIntoCirclePlane, false, circlePlane, default(Vector3), null, false); + ThickLine(segmentStartPos, segmentEndPos, color, default, null, 0.0f, 0.0f, durationInSec, 1.0f, 0.0f, null, hiddenByNearerObjects, flattenThickRoundLineIntoCirclePlane, false, false, amplitudeDependentLineDetails, 1.0f); + } + else + { + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.Get_normalized_amplitudeAndTextDirVectors(out amplitudeDependentLineDetails.amplitudeUp_normalized, out amplitudeDependentLineDetails.textDir_normalized, out amplitudeDependentLineDetails.lengthOfDrawnLine, out amplitudeDependentLineDetails.lengthOfDrawnLine_isFilled, segmentStartPos, line_startToEnd, isThinLine, lineIsSoShortThatItDoesntHaveADefinedAmplitude, null, false, DrawBasics.LineStyle.solid, flattenThickRoundLineIntoCirclePlane, false, null, default(Vector3), null, false); + ThickLine(segmentStartPos, segmentEndPos, color, default, null, 0.0f, 0.0f, durationInSec, 1.0f, 0.0f, null, hiddenByNearerObjects, flattenThickRoundLineIntoCirclePlane, false, false, amplitudeDependentLineDetails, 1.0f); + } + } + } + + static LineAnimationProgress ThinLine(Vector3 start, Vector3 end, Color startColor, Color endColor, string text, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress lineAnimationProgressToUpdate, bool hiddenByNearerObjects, bool flattenThickRoundLineIntoAmplitudePlane, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines, InternalDXXL_AmplitudeDependentLineDetails amplitudeDependentLineDetails, float tensionFactor) + { + startColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(startColor); + Color textColor = startColor; //-> is a separate field so it is not affected by "FlipColors()" + bool hasColorFade = (UtilitiesDXXL_Colors.IsDefaultColor(endColor) == false); + if (hasColorFade && (animationSpeed < 0.0f)) { FlipColors(out startColor, out endColor, startColor, endColor); } + bool hasAlphaFade = (UtilitiesDXXL_Math.ApproximatelyZero(alphaFadeOutLength_0to1) == false); + if (amplitudeDependentLineDetails.style == DrawBasics.LineStyle.disconnectedAnchors) { hasAlphaFade = false; } + if (hasAlphaFade) { alphaFadeOutLength_0to1 = Mathf.Clamp(alphaFadeOutLength_0to1, 0.0001f, 0.4999f); } + + float lineStyleAmplitude; + int usedSlotsInListOfSubLines = UtilitiesDXXL_LineStyles.RefillListOfSubLines(start, end, amplitudeDependentLineDetails.style, stylePatternScaleFactor, 0.0f, out lineStyleAmplitude, amplitudeDependentLineDetails.amplitudeUp_normalized, animationSpeed, ref lineAnimationProgressToUpdate, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, tensionFactor); + + for (int i_subLineAnchor = 0; i_subLineAnchor < usedSlotsInListOfSubLines; i_subLineAnchor++) + { + Color colorOfCurrSubLine = GetColorOfCurrSubLine(startColor, endColor, hasColorFade, hasAlphaFade, alphaFadeOutLength_0to1, usedSlotsInListOfSubLines, i_subLineAnchor); + if (amplitudeDependentLineDetails.style == DrawBasics.LineStyle.arrows) + { + DrawThinSubLineAsVector(colorOfCurrSubLine, i_subLineAnchor, animationSpeed, flattenThickRoundLineIntoAmplitudePlane, durationInSec, hiddenByNearerObjects); + } + else + { + bool lineStyle_is_alternatingColors = (amplitudeDependentLineDetails.style == DrawBasics.LineStyle.alternatingColorStripes); + if (lineStyle_is_alternatingColors && CheckIf_alternatingColorStripeIsDrawnForCurrentSubline(i_subLineAnchor, usedSlotsInListOfSubLines)) + { + //AlternatingColorLines fill the gap between the actual subLines: + //called BEFORE the main color, because: see explanatin inside "CheckIf_alternatingColorStripeIsDrawnForCurrentSubline" + Color usedAlternateColorOfStripedLines = GetColorWithAppliedAlpha_fromSubLines(DrawBasics.defaultColor2_ofAlternatingColorLines, hasAlphaFade, alphaFadeOutLength_0to1, i_subLineAnchor, usedSlotsInListOfSubLines); + DXXLWrapperForUntiysBuildInDrawLines.TryDrawLine(UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor], UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor - 1], usedAlternateColorOfStripedLines, durationInSec, hiddenByNearerObjects); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + } + + DXXLWrapperForUntiysBuildInDrawLines.TryDrawLine(UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor], UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor + 1], colorOfCurrSubLine, durationInSec, hiddenByNearerObjects); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + } + + i_subLineAnchor++; + } + + TagLine(start, end, text, textColor, lineStyleAmplitude, enlargeSmallTextToThisMinTextSize, amplitudeDependentLineDetails, durationInSec, hiddenByNearerObjects); + return lineAnimationProgressToUpdate; + } + + static int maxNumberOfSmallLines_thatBuildTheThickLine = 100; + static Vector3[] startPositions_ofHullLines = new Vector3[maxNumberOfSmallLines_thatBuildTheThickLine]; + static LineAnimationProgress ThickLine(Vector3 start, Vector3 end, Color startColor, Color endColor, string text, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress lineAnimationProgressToUpdate, bool hiddenByNearerObjects, bool flattenThickRoundLineIntoAmplitudePlane, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines, InternalDXXL_AmplitudeDependentLineDetails amplitudeDependentLineDetails, float tensionFactor) + { + Vector3 startToEnd = end - start; + startColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(startColor); + Color textColor = startColor; //-> is a separate field so it is not affected by "FlipColors()" + bool hasColorFade = (UtilitiesDXXL_Colors.IsDefaultColor(endColor) == false); + if (hasColorFade && (animationSpeed < 0.0f)) { FlipColors(out startColor, out endColor, startColor, endColor); } + bool hasAlphaFade = (UtilitiesDXXL_Math.ApproximatelyZero(alphaFadeOutLength_0to1) == false); + if (amplitudeDependentLineDetails.style == DrawBasics.LineStyle.disconnectedAnchors) { hasAlphaFade = false; } + if (hasAlphaFade) { alphaFadeOutLength_0to1 = Mathf.Clamp(alphaFadeOutLength_0to1, 0.0001f, 0.4999f); } + + float lineStyleAmplitude; + int usedSlotsInListOfSubLines = UtilitiesDXXL_LineStyles.RefillListOfSubLines(start, end, amplitudeDependentLineDetails.style, stylePatternScaleFactor, amplitudeDependentLineDetails.lineWidth, out lineStyleAmplitude, amplitudeDependentLineDetails.amplitudeUp_normalized, animationSpeed, ref lineAnimationProgressToUpdate, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, tensionFactor); + + bool subLinesAreAssumedToBe45DegToMainLine = ((amplitudeDependentLineDetails.style == DrawBasics.LineStyle.zigzag) || (amplitudeDependentLineDetails.style == DrawBasics.LineStyle.rhombus) || (amplitudeDependentLineDetails.style == DrawBasics.LineStyle.doubleRhombus)); + bool subLinesAreAssumedToBe45DegToMainLineInclinedAlongAmplitudeDir = ((amplitudeDependentLineDetails.style == DrawBasics.LineStyle.zigzag) || (amplitudeDependentLineDetails.style == DrawBasics.LineStyle.rhombus)); + + // int numberOfSmallLines_thatBuildTheThickLine = 16 + Mathf.RoundToInt(density_ofThickLines * amplitudeDependentLineDetails.lineWidth); + int numberOfSmallLines_thatBuildTheThickLine = 4 + Mathf.RoundToInt(12.0f * Mathf.Min(amplitudeDependentLineDetails.lineWidth / lowThreshold_ofLineWidth_forNumberOfThinLinesThatComposeTheThickLine, 1.0f)) + Mathf.RoundToInt(DrawBasics.Density_ofThickLines * amplitudeDependentLineDetails.lineWidth); + numberOfSmallLines_thatBuildTheThickLine = Mathf.Min(numberOfSmallLines_thatBuildTheThickLine, maxNumberOfSmallLines_thatBuildTheThickLine); + + Vector3 end_ofPrevSubLine = (usedSlotsInListOfSubLines > 0) ? UtilitiesDXXL_LineStyles.s_listOfSubLines[0] : Vector3.zero; + for (int i_subLineAnchor = 0; i_subLineAnchor < usedSlotsInListOfSubLines; i_subLineAnchor++) + { + Vector3 start_ofCurrSubLine = UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor]; + Vector3 end_ofCurrSubLine = UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor + 1]; + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start_ofCurrSubLine, end_ofCurrSubLine)) + { + i_subLineAnchor++; + continue; + } + + Vector3 startToEnd_ofCurrSubLine = end_ofCurrSubLine - start_ofCurrSubLine; + if (UtilitiesDXXL_Math.ApproximatelyZero(startToEnd_ofCurrSubLine)) + { + i_subLineAnchor++; + continue; + } + + Color colorOfCurrSubLine = GetColorOfCurrSubLine(startColor, endColor, hasColorFade, hasAlphaFade, alphaFadeOutLength_0to1, usedSlotsInListOfSubLines, i_subLineAnchor); + + if (amplitudeDependentLineDetails.style == DrawBasics.LineStyle.arrows) + { + DrawThickSubLineAsVector(colorOfCurrSubLine, start_ofCurrSubLine, end_ofCurrSubLine, animationSpeed, amplitudeDependentLineDetails.lineWidth, flattenThickRoundLineIntoAmplitudePlane, durationInSec, hiddenByNearerObjects); + } + else + { + Fill_startPositions_ofHullLines(startToEnd, subLinesAreAssumedToBe45DegToMainLine, subLinesAreAssumedToBe45DegToMainLineInclinedAlongAmplitudeDir, start_ofCurrSubLine, numberOfSmallLines_thatBuildTheThickLine, flattenThickRoundLineIntoAmplitudePlane, amplitudeDependentLineDetails.amplitudeUp_normalized, amplitudeDependentLineDetails.lineWidth); + DrawThickSubLine(start_ofCurrSubLine, end_ofCurrSubLine, end_ofPrevSubLine, startToEnd_ofCurrSubLine, colorOfCurrSubLine, i_subLineAnchor, usedSlotsInListOfSubLines, numberOfSmallLines_thatBuildTheThickLine, hasAlphaFade, alphaFadeOutLength_0to1, amplitudeDependentLineDetails.style, durationInSec, hiddenByNearerObjects); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + } + + end_ofPrevSubLine = end_ofCurrSubLine; + i_subLineAnchor++; + } + TagLine(start, end, text, textColor, lineStyleAmplitude, enlargeSmallTextToThisMinTextSize, amplitudeDependentLineDetails, durationInSec, hiddenByNearerObjects); + return lineAnimationProgressToUpdate; + } + + static void FlipColors(out Color startColor_flipped, out Color endColor_flipped, Color startColor_preFlip, Color endColor_preFlip) + { + //-> This corresponds to the behaviour of "UtilitiesDXXL_LineStyles.RefillListOfSubLines()", where the line startPos and endPos get flipped for negative animation speed. + //-> This would also lead to flipped colors in lines with color fade + //-> In such cases the colors are flipped here to re-compensate the start/end-flipping inside "UtilitiesDXXL_LineStyles.RefillListOfSubLines()", so that as a result for negative animation speeds only the anmiation direciton is flipped, but the color fade direction stays. + + startColor_flipped = endColor_preFlip; + endColor_flipped = startColor_preFlip; + } + + static void DrawThinSubLineAsVector(Color colorOfCurrSubLine, int i_subLineAnchor, float animationSpeed, bool flattenThickRoundLineIntoAmplitudePlane, float durationInSec, bool hiddenByNearerObjects) + { + //note: danger of overwriting the classwide "verticesGlobal" or "verticesLocal" list inside the following "Vector()"-call (which may disturb the function that called this "Line()") has been prevented via "verticesLocal_ofPyramid". For details: See declaration of "verticesLocal_ofPyramid" + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor], UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor + 1]) == false) + { + Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + try + { + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine = true; + curr_vectorConeAngleDeg = 45.0f; + //"back to heading towards lineEnd", because "s_listOfSubLines" is already filled backwards due to negative animation speed: + bool flipArrowDirsBackToHeadingTowardsLineEnd = ((animationSpeed < 0.0f) && (UtilitiesDXXL_LineStyles.curr_pointersDirAlongAnimationDir == false)); + Vector3 vectorStartPos = flipArrowDirsBackToHeadingTowardsLineEnd ? UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor + 1] : UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor]; + Vector3 vectorEndPos = flipArrowDirsBackToHeadingTowardsLineEnd ? UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor] : UtilitiesDXXL_LineStyles.s_listOfSubLines[i_subLineAnchor + 1]; + //no amplitudeDir needed, because it gets auto-forced via "UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine": + Vector(vectorStartPos, vectorEndPos, colorOfCurrSubLine, 0.0f, null, 0.45f, false, flattenThickRoundLineIntoAmplitudePlane, false, 0.0f, false, durationInSec, hiddenByNearerObjects, null, default(Vector3), false, 0.0f); + } + catch { } + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine = false; + Reverse_coneLength_interpretation_forStraightVectors(); + curr_vectorConeAngleDeg = default_vectorConeAngleDeg; + } + } + + static void DrawThickSubLineAsVector(Color colorOfCurrSubLine, Vector3 start_ofCurrSubLine, Vector3 end_ofCurrSubLine, float animationSpeed, float width, bool flattenThickRoundLineIntoAmplitudePlane, float durationInSec, bool hiddenByNearerObjects) + { + Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + try + { + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine = true; + curr_vectorConeAngleDeg = 45.0f; + //"back to heading towards lineEnd", because "s_listOfSubLines" is already filled backwards due to negative animation speed: + bool flipArrowDirsBackToHeadingTowardsLineEnd = ((animationSpeed < 0.0f) && (UtilitiesDXXL_LineStyles.curr_pointersDirAlongAnimationDir == false)); + Vector3 vectorStartPos = flipArrowDirsBackToHeadingTowardsLineEnd ? end_ofCurrSubLine : start_ofCurrSubLine; + Vector3 vectorEndPos = flipArrowDirsBackToHeadingTowardsLineEnd ? start_ofCurrSubLine : end_ofCurrSubLine; + //note: danger of overwriting the classwide "verticesGlobal" or "verticesLocal" list inside the following "Vector()"-call (which may disturb the function that called this "Line()") has been prevented via "verticesLocal_ofPyramid". For details: See declaration of "verticesLocal_ofPyramid" + //no amplitudeDir needed, because it gets auto-forced via "UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine": + Vector(vectorStartPos, vectorEndPos, colorOfCurrSubLine, width, null, 0.45f, false, flattenThickRoundLineIntoAmplitudePlane, false, 0.0f, false, durationInSec, hiddenByNearerObjects, null, default(Vector3), false, 0.0f); + } + catch { } + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine = false; + Reverse_coneLength_interpretation_forStraightVectors(); + curr_vectorConeAngleDeg = default_vectorConeAngleDeg; + } + + static void Fill_startPositions_ofHullLines(Vector3 startToEnd_ofMainLine, bool subLineIsAssumedToBe45DegToMainLine, bool subLineIsAssumedToBe45DegToMainLineInclinedAlongAmplitudeDir, Vector3 start_ofCurrSubLine, int numberOfSmallLines_thatBuildTheThickLine, bool flattenThickRoundLineIntoAmplitudePlane, Vector3 amplitudeUp_normalized, float lineWidth) + { + //"subLineIsAssumedToBe45DegToMainLine" and "subLineIsAssumedToBe45DegToMainLineInclinedAlongAmplitudeDir" are there for this problem: + //-> the lineWidth gets expanded along "amplitudeUp_normalized" (which is the same for the whole mainLine). + //-> so if a subLine is inclined to the main line it gets a parallax shortening + //-> this results in an unconsistent lineWidth e.g. for "sine" lineStyle + //-> it is compenstated quiet easy/cheap at least for zigZag/rhomubs lineStyles because it can be assumed that the inclination angle is 45° there (which though is not always the case in edge cases) + //-> it is tolerated for other lineStyles + //-> the "correct" way would be to calculate "amplitudeUp_normalized" per subLine, which would be much more expensive + //---> this "correct way" also has the disadvantage, that non-zeroWidth zigZag-lineStyles have a "dent" at the 90°-corners joins + //---> these "dents" could also be prevented by extending the subLines inside "UtilitiesDXXL_LineStyles.GetListOfSubLines_forZigZagLine()", but the solution here leads to a much nicer appearance + + if (flattenThickRoundLineIntoAmplitudePlane) + { + Vector3 vector_fromLineLowerEnd_toUpperEnd = amplitudeUp_normalized * lineWidth; + if (subLineIsAssumedToBe45DegToMainLine) + { + vector_fromLineLowerEnd_toUpperEnd = vector_fromLineLowerEnd_toUpperEnd * UtilitiesDXXL_Math.sqrtOf2_precalced; + } + Vector3 lineLowerEnd = start_ofCurrSubLine - (0.5f * vector_fromLineLowerEnd_toUpperEnd); + Vector3 vector_fromFlatenedLineToNeighborFlatenedLine = vector_fromLineLowerEnd_toUpperEnd / (numberOfSmallLines_thatBuildTheThickLine - 1); + for (int i_hullLine = 0; i_hullLine < numberOfSmallLines_thatBuildTheThickLine; i_hullLine++) + { + startPositions_ofHullLines[i_hullLine] = lineLowerEnd + vector_fromFlatenedLineToNeighborFlatenedLine * i_hullLine; + } + } + else + { + float thickLineRadius = 0.5f * lineWidth; + Vector3 vector_fromStartPos_toStartPosOfFirstHullLine = amplitudeUp_normalized * thickLineRadius; + float angleDeg_betweenHullLines = 360.0f / numberOfSmallLines_thatBuildTheThickLine; + + if (subLineIsAssumedToBe45DegToMainLine) + { + for (int i_hullLine = 0; i_hullLine < numberOfSmallLines_thatBuildTheThickLine; i_hullLine++) + { + Quaternion rotation_fromFirstHullLineStartPos_toCurrentHullLineStartPos = Quaternion.AngleAxis(angleDeg_betweenHullLines * i_hullLine, startToEnd_ofMainLine); + float offsetScaleFactor; + if (subLineIsAssumedToBe45DegToMainLineInclinedAlongAmplitudeDir) + { + float progress0to1_throughWholeHullCircle = ((float)i_hullLine / (float)numberOfSmallLines_thatBuildTheThickLine); + offsetScaleFactor = 1.0f + UtilitiesDXXL_Math.sqrtOf2_precalced_minus1 * GetHullLinesModulationFactor_whichComponesatesTheDeformationOf45DegSublines(progress0to1_throughWholeHullCircle); + } + else + { + // doubleRhombus doesn't get that correction and therefore remains with uneven line intersection extents and not fully fitting the specified "lineWidth" + offsetScaleFactor = 1.0f; + } + startPositions_ofHullLines[i_hullLine] = start_ofCurrSubLine + rotation_fromFirstHullLineStartPos_toCurrentHullLineStartPos * (vector_fromStartPos_toStartPosOfFirstHullLine * offsetScaleFactor); + } + } + else + { + for (int i_hullLine = 0; i_hullLine < numberOfSmallLines_thatBuildTheThickLine; i_hullLine++) + { + // Quaternion rotation_fromFirstHullLineStartPos_toCurrentHullLineStartPos = Quaternion.AngleAxis(angleDeg_betweenHullLines * i_hullLine, startToEnd_ofCurrSubLine); + Quaternion rotation_fromFirstHullLineStartPos_toCurrentHullLineStartPos = Quaternion.AngleAxis(angleDeg_betweenHullLines * i_hullLine, startToEnd_ofMainLine); + startPositions_ofHullLines[i_hullLine] = start_ofCurrSubLine + rotation_fromFirstHullLineStartPos_toCurrentHullLineStartPos * vector_fromStartPos_toStartPosOfFirstHullLine; + } + } + } + } + + static float GetHullLinesModulationFactor_whichComponesatesTheDeformationOf45DegSublines(float progress0to1_throughWholeHullCircle) + { + //this is only an approximation: + float progress0to4_throughWholeHullCircle = 4.0f * progress0to1_throughWholeHullCircle; + if (progress0to4_throughWholeHullCircle < 1.0f) + { + return (1.0f - progress0to4_throughWholeHullCircle); + } + else + { + if (progress0to4_throughWholeHullCircle < 2.0f) + { + return (progress0to4_throughWholeHullCircle - 1.0f); + } + else + { + if (progress0to4_throughWholeHullCircle < 3.0f) + { + return (3.0f - progress0to4_throughWholeHullCircle); + } + else + { + return (progress0to4_throughWholeHullCircle - 3.0f); + } + } + } + } + + static void DrawThickSubLine(Vector3 start_ofCurrSubLine, Vector3 end_ofCurrSubLine, Vector3 end_ofPrevSubLine, Vector3 startToEnd_ofCurrSubLine, Color colorOfCurrSubLine, int i_subLineAnchor, int usedSlotsInListOfSubLines, int numberOfSmallLines_thatBuildTheThickLine, bool hasAlphaFade, float alphaFadeOutLength_0to1, DrawBasics.LineStyle lineStyle, float durationInSec, bool hiddenByNearerObjects) + { + bool lineStyle_is_alternatingColors = (lineStyle == DrawBasics.LineStyle.alternatingColorStripes); + Color usedAlternateColorOfStripedLines = default(Color); + bool drawAlternatingColorStripe = false; + if (lineStyle_is_alternatingColors) + { + usedAlternateColorOfStripedLines = GetColorWithAppliedAlpha_fromSubLines(DrawBasics.defaultColor2_ofAlternatingColorLines, hasAlphaFade, alphaFadeOutLength_0to1, i_subLineAnchor, usedSlotsInListOfSubLines); + drawAlternatingColorStripe = CheckIf_alternatingColorStripeIsDrawnForCurrentSubline(i_subLineAnchor, usedSlotsInListOfSubLines); + } + + //hull lines: + //(cylindrical around and parallel to the central line to simulate a "width" of the line) + for (int i_hullLine = 0; i_hullLine < numberOfSmallLines_thatBuildTheThickLine; i_hullLine++) + { + if (drawAlternatingColorStripe) + { + //AlternatingColorLines fill the gap between the actual subLines: + //called BEFORE the main color, because: see explanatin inside "DrawAlternatingColorStripe" + Vector3 startOfCurr_to_endOfPrevSubLine = end_ofPrevSubLine - start_ofCurrSubLine; + DXXLWrapperForUntiysBuildInDrawLines.TryDrawLine(startPositions_ofHullLines[i_hullLine], startPositions_ofHullLines[i_hullLine] + startOfCurr_to_endOfPrevSubLine, usedAlternateColorOfStripedLines, durationInSec, hiddenByNearerObjects); + } + DXXLWrapperForUntiysBuildInDrawLines.TryDrawLine(startPositions_ofHullLines[i_hullLine], startPositions_ofHullLines[i_hullLine] + startToEnd_ofCurrSubLine, colorOfCurrSubLine, durationInSec, hiddenByNearerObjects); + } + + //central line: + if (drawAlternatingColorStripe) + { + //AlternatingColorLines fill the gap between the actual subLines: + //called BEFORE the main color, because: see explanatin inside "CheckIf_alternatingColorStripeIsDrawnForCurrentSubline" + DXXLWrapperForUntiysBuildInDrawLines.TryDrawLine(start_ofCurrSubLine, end_ofPrevSubLine, usedAlternateColorOfStripedLines, durationInSec, hiddenByNearerObjects); + } + DXXLWrapperForUntiysBuildInDrawLines.TryDrawLine(start_ofCurrSubLine, end_ofCurrSubLine, colorOfCurrSubLine, durationInSec, hiddenByNearerObjects); + } + + static Color GetColorOfCurrSubLine(Color startColor, Color endColor, bool hasColorFade, bool hasAlphaFade, float alphaFadeOutLength_0to1, int usedSlotsInListOfSubLines, int i_subLineAnchor) + { + Color color; + if (hasColorFade) + { + color = GetFadedColorFromSubLines(startColor, endColor, usedSlotsInListOfSubLines, i_subLineAnchor); + } + else + { + color = startColor; + } + return GetColorWithAppliedAlpha_fromSubLines(color, hasAlphaFade, alphaFadeOutLength_0to1, i_subLineAnchor, usedSlotsInListOfSubLines); + } + + static LineAnimationProgress DrawLineColorFade_forUsuallyNotSubdividedSolidLines(Vector3 start, Vector3 end, Color startColor, Color endColor, float width, string text, InternalDXXL_Plane preferredAmplitudePlane, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(alphaFadeOutLength_0to1, "alphaFadeOutLength_0to1")) { return null; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start, end)) + { + //-> no "PointFallback()" in case of lines + //-> at least there would not be the danger of endless loops here as it is in "DrawLine_uniOrMultiColor()" + //Debug.Log("'LineColorFade' is not drawn, because start and end are at the same position (" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(start) + ")."); + return null; + } + + int numberOfSubLineSegments = 24; + bool hasAlphaFade = (UtilitiesDXXL_Math.ApproximatelyZero(alphaFadeOutLength_0to1) == false); + if (hasAlphaFade) + { + alphaFadeOutLength_0to1 = Mathf.Clamp(alphaFadeOutLength_0to1, 0.0001f, 0.4999f); + numberOfSubLineSegments = 48; + } + + Vector3 startToEnd = end - start; + Vector3 lineNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(startToEnd, out float lineLength); + float segmentLenght = lineLength / (float)numberOfSubLineSegments; + Vector3 subLineSegment = lineNormalized * segmentLenght; + InternalDXXL_AmplitudeDependentLineDetails amplitudeDependentLineDetails = Get_amplitudeDependentLineDetails(start, end, text, flattenThickRoundLineIntoAmplitudePlane, preferredAmplitudePlane, customAmplitudeAndTextDir, width, enlargeSmallTextToThisMinTextSize, DrawBasics.LineStyle.solid, endPlates_size, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D); + DrawSubLines_of_subdividedSolidLine(start, end, startColor, endColor, numberOfSubLineSegments, subLineSegment, hasAlphaFade, alphaFadeOutLength_0to1, durationInSec, hiddenByNearerObjects, flattenThickRoundLineIntoAmplitudePlane, amplitudeDependentLineDetails); + TryDrawPerpEndPlates(amplitudeDependentLineDetails.uses_endPlates, amplitudeDependentLineDetails.endPlates_size, amplitudeDependentLineDetails.amplitudeUp_normalized, amplitudeDependentLineDetails.lengthOfDrawnLine, amplitudeDependentLineDetails.lengthOfDrawnLine_isFilled, flattenThickRoundLineIntoAmplitudePlane, start, end, startColor, endColor, durationInSec, hiddenByNearerObjects); + TagLine(start, end, text, startColor, 0.0f, enlargeSmallTextToThisMinTextSize, amplitudeDependentLineDetails, durationInSec, hiddenByNearerObjects); + return null; + } + + static void DrawSubLines_of_subdividedSolidLine(Vector3 start, Vector3 end, Color startColor, Color endColor, int numberOfSubLineSegments, Vector3 subLineSegment, bool hasAlphaFade, float alphaFadeOutLength_0to1, float durationInSec, bool hiddenByNearerObjects, bool flattenThickRoundLineIntoAmplitudePlane, InternalDXXL_AmplitudeDependentLineDetails amplitudeDependentLineDetails) + { + for (int i_segment = 0; i_segment < numberOfSubLineSegments; i_segment++) + { + Vector3 segmentStartPos = start + i_segment * subLineSegment; + Vector3 segmentEndPos = start + (i_segment + 1) * subLineSegment; + Color segmentColor; + if (i_segment == (numberOfSubLineSegments - 1)) + { + segmentEndPos = end; + segmentColor = endColor; + } + else + { + segmentColor = GetFadedColorFromSegments(startColor, endColor, i_segment, numberOfSubLineSegments); + } + segmentColor = GetColorWithAppliedAlpha_fromSegments(segmentColor, hasAlphaFade, alphaFadeOutLength_0to1, i_segment, numberOfSubLineSegments); + + if (amplitudeDependentLineDetails.isThinLine) + { + ThinLine(segmentStartPos, segmentEndPos, segmentColor, default, null, 0.0f, 0.0f, durationInSec, 1.0f, 0.0f, null, hiddenByNearerObjects, flattenThickRoundLineIntoAmplitudePlane, false, false, amplitudeDependentLineDetails, 1.0f); + } + else + { + ThickLine(segmentStartPos, segmentEndPos, segmentColor, default, null, 0.0f, 0.0f, durationInSec, 1.0f, 0.0f, null, hiddenByNearerObjects, flattenThickRoundLineIntoAmplitudePlane, false, false, amplitudeDependentLineDetails, 1.0f); + } + } + } + + static void TagLine(Vector3 start, Vector3 end, string text, Color color, float lineStyleAmplitude, float enlargeSmallTextToThisMinTextSize, InternalDXXL_AmplitudeDependentLineDetails amplitudeDependentLineDetails, float durationInSec, bool hiddenByNearerObjects) + { + if (amplitudeDependentLineDetails.textDrawingIsSkipped_dueToLineIsTooShort == false) + { + if (text != null && text != "") + { + float halfLineWidth = 0.5f * amplitudeDependentLineDetails.lineWidth; + Vector3 startToEnd = end - start; + //"middleOfLine" could also be reused from "UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.GetLineCenter", but is most likely not relevant for performance/not worth the required dependency. + Vector3 middleOfLine = 0.5f * (start + end); + //text is not drawn here, but the "Write"-call is only for filling "parsedTextSpecs": + UtilitiesDXXL_Text.Write(text, Vector3.zero, default, 1.0f, default, default, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, false, durationInSec, hiddenByNearerObjects, true, true, false); //"isFrom_Write2D" enabled, because has no effect, but is cheaper + int numberOfChars_inLongestLine_ifSizeIs1 = DrawText.parsedTextSpecs.numberOfChars_inLongestLine; + float lengthOfLongestLine_ifSizeIs1 = DrawText.parsedTextSpecs.widthOfLongestLine; + if (numberOfChars_inLongestLine_ifSizeIs1 <= 0) + { + //UtilitiesDXXL_Log.PrintErrorCode("13-" + numberOfChars_inLongestLine_ifSizeIs1); //-> it may validly happen, e.g. when a string without content characters, but with markup tags (like "") is supplied + return; + } + float maxTextBlockWidth_0to1 = DrawBasics.RelSizeOfTextOnLines; + float textSizeShrinkingFactor_dueToLowCharNumber_0to1 = 1.0f; + int charNumberThreshold_belowWhichShrinkingHappens = 6; + if (numberOfChars_inLongestLine_ifSizeIs1 < charNumberThreshold_belowWhichShrinkingHappens) + { + textSizeShrinkingFactor_dueToLowCharNumber_0to1 = (float)numberOfChars_inLongestLine_ifSizeIs1 / (float)charNumberThreshold_belowWhichShrinkingHappens; + } + + float lengthOfDrawnLine = GetLengthOfDrawnLine(amplitudeDependentLineDetails.lengthOfDrawnLine, amplitudeDependentLineDetails.lengthOfDrawnLine_isFilled, startToEnd); + float finalWidthOfTextBlock = lengthOfDrawnLine * maxTextBlockWidth_0to1 * textSizeShrinkingFactor_dueToLowCharNumber_0to1; + float sizeOfScaledText = finalWidthOfTextBlock / lengthOfLongestLine_ifSizeIs1; + Vector3 textStartPos_onLine = middleOfLine - 0.5f * finalWidthOfTextBlock * amplitudeDependentLineDetails.textDir_normalized; + Vector3 textStartPos = textStartPos_onLine + amplitudeDependentLineDetails.amplitudeUp_normalized * (halfLineWidth + lineStyleAmplitude + 0.7f * sizeOfScaledText); + + if (amplitudeDependentLineDetails.enlargeSmallText) + { + // if (UtilitiesDXXL_Log.ErroLogForInvalidFloats(enlargeSmallTextToThisMinTextSize, "enlargeSmallTextToThisMinTextSize")) { return; } <- enlargeSmallTextToThisMinTextSize has already been checked for validity during the "enlargeSmallText"-derivation (inside "CheckIfSmallTextGetsEnlarged()") + enlargeSmallTextToThisMinTextSize = UtilitiesDXXL_Math.AbsNonZeroValue(enlargeSmallTextToThisMinTextSize); + sizeOfScaledText = Mathf.Max(sizeOfScaledText, enlargeSmallTextToThisMinTextSize); + maxTextBlockWidth_0to1 = 100000.0f; + } + + DrawText.TextAnchorDXXL textAnchor = DrawBasics.shiftTextPosOnLines_toNonIntersecting ? DrawText.TextAnchorDXXL.LowerLeft : DrawText.TextAnchorDXXL.LowerLeftOfFirstLine; + UtilitiesDXXL_Text.Write(text, textStartPos, color, sizeOfScaledText, amplitudeDependentLineDetails.textDir_normalized, amplitudeDependentLineDetails.amplitudeUp_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, lengthOfDrawnLine * maxTextBlockWidth_0to1, 0.0f, false, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + } + + static float GetLengthOfDrawnLine(float lengthOfDrawnLine_fromAmplitudeDependentLineDetails, bool lengthOfDrawnLine_isFilledInsideAmplitudeDependentLineDetails, Vector3 startToEnd) + { + if (lengthOfDrawnLine_isFilledInsideAmplitudeDependentLineDetails) + { + return lengthOfDrawnLine_fromAmplitudeDependentLineDetails; + } + else + { + return startToEnd.magnitude; + } + } + + static bool CheckIf_alternatingColorStripeIsDrawnForCurrentSubline(int i_subLineAnchor, int usedSlotsInListOfSubLines) + { + // if (i_subLineAnchor > 3) //skip first two segments (one is the additional unanimated segment at linestart, the other is the real first segment which doesn't have a gap to the non-existing preceding segment) <- This variant leaves a gap sometimes->See commment in next line + if (i_subLineAnchor > 1) //skip the first segment (which is the additional unanimated segment at lineStart). The second segment (which is the first animated one) is not skipped despite it often (in all unanimated cases) starts at lineStart, which causes a stripeSegment to be drawn from lineStart. It cannot be skipped, becuase this second (first animated) segment sometimes starts after the first fixed segment, which would lead a gap without the stripe color. This stripeSegment_fromLineStart is drawn before the mainColor and therefore gets overdrawn by the mainColor, so it doesn't disturb the apperance + { + if (i_subLineAnchor < (usedSlotsInListOfSubLines - 2)) //skip last segment which is the additional unanimated segment at lineEnd. + { + return true; + } + } + return false; + } + + public static void PointFallback(Vector3 position, string text, Color color, float markingCrossLinesWidth, float durationInSec, bool hiddenByNearerObjects) + { + Point(false, position, text, color, 0.5f, markingCrossLinesWidth, color, Quaternion.identity, true, true, false, true, Vector3.zero, Quaternion.identity, Vector3.one, false, durationInSec, hiddenByNearerObjects); + } + + public static void Point(bool is2D, Vector3 localPosition, string text, Color textColor, float sizeOfMarkingCross, float markingCrossLinesWidth, Color markingCrossColor, Quaternion localRotation, bool pointer_as_textAttachStyle, bool drawCoordsAsText, bool additionallyDrawGlobalCoords, bool coordSystemIsGlobalNotLocal, Vector3 parentPositionGlobal, Quaternion parentRotationGlobal, Vector3 parentScaleGlobal, bool hideZDir, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(sizeOfMarkingCross, "sizeOfMarkingCross")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(markingCrossLinesWidth, "markingCrossLinesWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(localPosition, "localPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(parentPositionGlobal, "parentPositionGlobal")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(parentScaleGlobal, "parentScaleGlobal")) { return; } + + localRotation = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(localRotation); + bool isZeroParentRotation = (parentRotationGlobal == Quaternion.identity); + bool isZeroLocalRotation = (localRotation == Quaternion.identity); + markingCrossLinesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(markingCrossLinesWidth); + float halfAbsMarkingCrossLinesWidth = 0.5f * markingCrossLinesWidth; + sizeOfMarkingCross = Mathf.Abs(sizeOfMarkingCross); + sizeOfMarkingCross = UtilitiesDXXL_Math.Max(sizeOfMarkingCross, 4.0f * markingCrossLinesWidth, 0.01f); + float halfMarkingCrossExtent = 0.5f * sizeOfMarkingCross; + + Color color_x = UtilitiesDXXL_Colors.red_xAxis; + Color color_y = UtilitiesDXXL_Colors.green_yAxis; + Color color_z = UtilitiesDXXL_Colors.blue_zAxis; + if (UtilitiesDXXL_Colors.IsDefaultColor(markingCrossColor) == false) + { + color_x = markingCrossColor; + color_y = markingCrossColor; + color_z = markingCrossColor; + } + + Vector3 parentForward_normalized = Vector3.forward; + Vector3 parentUp_normalized = Vector3.up; + Vector3 parentRight_normalized = Vector3.right; + + if (isZeroParentRotation == false) + { + parentForward_normalized = parentRotationGlobal * Vector3.forward; + parentUp_normalized = parentRotationGlobal * Vector3.up; + parentRight_normalized = parentRotationGlobal * Vector3.right; + } + + Vector3 locallyRotatedForward_normalized = parentForward_normalized; + Vector3 locallyRotatedUp_normalized = parentUp_normalized; + Vector3 locallyRotatedRight_normalized = parentRight_normalized; + + if (isZeroLocalRotation == false) + { + locallyRotatedForward_normalized = localRotation * parentForward_normalized; + locallyRotatedUp_normalized = localRotation * parentUp_normalized; + locallyRotatedRight_normalized = localRotation * parentRight_normalized; + } + + Vector3 worldPosition = localPosition; + if (UtilitiesDXXL_Math.ApproximatelyZero(parentPositionGlobal) == false) + { + worldPosition = parentPositionGlobal + parentRight_normalized * parentScaleGlobal.x * localPosition.x + parentUp_normalized * parentScaleGlobal.y * localPosition.y + parentForward_normalized * parentScaleGlobal.z * localPosition.z; + } + + if (hideZDir == false) + { + Line_fadeableAnimSpeed.InternalDraw(worldPosition - locallyRotatedForward_normalized * halfMarkingCrossExtent, worldPosition + locallyRotatedForward_normalized * halfMarkingCrossExtent, color_z, markingCrossLinesWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + Line_fadeableAnimSpeed.InternalDraw(worldPosition - locallyRotatedUp_normalized * halfMarkingCrossExtent, worldPosition + locallyRotatedUp_normalized * halfMarkingCrossExtent, color_y, markingCrossLinesWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, is2D, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed.InternalDraw(worldPosition - locallyRotatedRight_normalized * halfMarkingCrossExtent, worldPosition + locallyRotatedRight_normalized * halfMarkingCrossExtent, color_x, markingCrossLinesWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, is2D, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + if (markingCrossLinesWidth > 0.0f) + { + if (is2D) + { + //"DrawShapes.Circle" is allowed to fallback to point (for edge cases) because this fallback will be called with "is2D == false", therefore no danger of endless loop. + DrawShapes.Circle(worldPosition, halfAbsMarkingCrossLinesWidth, Color.white, Vector3.forward, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, true, false, durationInSec, hiddenByNearerObjects); + } + else + { + int numberOfSphereStruts = 8; + DrawShapes.Sphere(worldPosition, halfAbsMarkingCrossLinesWidth, Color.white, locallyRotatedUp_normalized, locallyRotatedForward_normalized, 0.0f, null, numberOfSphereStruts, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + } + } + + DrawCoordsAsText(drawCoordsAsText, coordSystemIsGlobalNotLocal, worldPosition, localPosition, sizeOfMarkingCross, halfAbsMarkingCrossLinesWidth, color_x, color_y, color_z, parentRotationGlobal, isZeroLocalRotation, markingCrossLinesWidth, hideZDir, additionallyDrawGlobalCoords, durationInSec, hiddenByNearerObjects); + + if (text != null && text != "") + { + if (pointer_as_textAttachStyle) + { + float widthOfLinesTowardsText = 0.3f * markingCrossLinesWidth; + if (is2D) + { + Vector2 positionV2 = new Vector2(localPosition.x, localPosition.y); + DrawBasics2D.PointTag(positionV2, text, textColor, widthOfLinesTowardsText, 1.5f * sizeOfMarkingCross, default(Vector2), localPosition.z, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + else + { + DrawBasics.PointTag(worldPosition, text, textColor, widthOfLinesTowardsText, 1.5f * sizeOfMarkingCross, default(Vector3), 1.0f, false, durationInSec, hiddenByNearerObjects); + } + } + else + { + float textSize = 0.25f * sizeOfMarkingCross; + float spacingFromMarkerCross = 0.1f * textSize; + Vector3 textPos = worldPosition - locallyRotatedUp_normalized * (1.1f * textSize + halfAbsMarkingCrossLinesWidth) + locallyRotatedRight_normalized * (spacingFromMarkerCross + halfAbsMarkingCrossLinesWidth); + UtilitiesDXXL_Text.Write(text, textPos, textColor, textSize, locallyRotatedRight_normalized, locallyRotatedUp_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + } + + static void DrawCoordsAsText(bool drawCoordsAsText, bool coordSystemIsGlobalNotLocal, Vector3 worldPosition, Vector3 localPosition, float markingCrossExtent, float halfAbsMarkerLinesWidth, Color color_x, Color color_y, Color color_z, Quaternion parentRotationGlobal, bool isZeroLocalRotation, float markingCrossLinesWidth, bool hideZDir, bool additionallyDrawGlobalCoords, float durationInSec, bool hiddenByNearerObjects) + { + if (drawCoordsAsText) + { + if (coordSystemIsGlobalNotLocal) + { + DrawCoordAxesAtPoint(worldPosition, worldPosition, markingCrossExtent, false, halfAbsMarkerLinesWidth, color_x, color_y, color_z, !isZeroLocalRotation, false, false, Quaternion.identity, false, markingCrossLinesWidth, hideZDir, durationInSec, hiddenByNearerObjects); + } + else + { + if (additionallyDrawGlobalCoords) + { + float doubleShrinkFactor_ofLocalPointsGlobalCoordsText = 1.0f; + if (isZeroLocalRotation == false) + { + doubleShrinkFactor_ofLocalPointsGlobalCoordsText = 0.5f; + } + DrawCoordAxesAtPoint(worldPosition, worldPosition, markingCrossExtent * doubleShrinkFactor_ofLocalPointsGlobalCoordsText, true, halfAbsMarkerLinesWidth, color_x, color_y, color_z, true, true, false, Quaternion.identity, true, markingCrossLinesWidth, hideZDir, durationInSec, hiddenByNearerObjects); + } + DrawCoordAxesAtPoint(worldPosition, localPosition, markingCrossExtent, false, halfAbsMarkerLinesWidth, color_x, color_y, color_z, !isZeroLocalRotation, true, true, parentRotationGlobal, false, markingCrossLinesWidth, hideZDir, durationInSec, hiddenByNearerObjects); + } + } + } + + static string globalCoordSystemSpecifyingText = "global"; + static string localCoordSystemSpecifyingText = "local"; + static void DrawCoordAxesAtPoint(Vector3 drawPosition, Vector3 positionCoordsToWrite, float markingCrossExtent, bool shrinkToSmaller, float halfAbsMarkerLinesWidth, Color color_x, Color color_y, Color color_z, bool drawThinButWithOwnAxisLines, bool drawCoordSystemSpecifyingString, bool coordSystemSpecifyingStringIsLocal, Quaternion rotation, bool coordTextBelowAxes, float markingCrossLinesWidth, bool hideZDir, float durationInSec, bool hiddenByNearerObjects) + { + float halfMarkingCrossExtent = 0.5f * markingCrossExtent; + float coordsTextSize = 0.05f * markingCrossExtent; + float spacingFromMarkerCross = 1.75f * coordsTextSize; + if (shrinkToSmaller) + { + coordsTextSize = coordsTextSize * 0.4f; + } + float spacingAboveLine = 0.5f * coordsTextSize; + float maxTextLength = halfMarkingCrossExtent - (spacingFromMarkerCross + halfAbsMarkerLinesWidth); + float coordSystemSpecifier_alpha = 0.4f; + bool isZeroRotation = (rotation == Quaternion.identity); + + Vector3 forward_normalized = Vector3.forward; + Vector3 up_normalized = Vector3.up; + Vector3 right_normalized = Vector3.right; + if (isZeroRotation == false) + { + forward_normalized = rotation * Vector3.forward; + up_normalized = rotation * Vector3.up; + right_normalized = rotation * Vector3.right; + } + + if (drawThinButWithOwnAxisLines) + { + coordSystemSpecifier_alpha = 0.8f; + float coordsTextAndThinLinesAlpha = 0.5f; + if (markingCrossLinesWidth > 0.0f) + { + coordsTextAndThinLinesAlpha = 0.6f; + } + color_x = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_x, coordsTextAndThinLinesAlpha); + color_y = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_y, coordsTextAndThinLinesAlpha); + color_z = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_z, coordsTextAndThinLinesAlpha); + + float lenghtOfThinHalfLine = halfMarkingCrossExtent; + if (shrinkToSmaller) + { + lenghtOfThinHalfLine = lenghtOfThinHalfLine * 0.73f; + } + + if (hideZDir == false) + { + Line_fadeableAnimSpeed.InternalDraw(drawPosition, drawPosition + forward_normalized * lenghtOfThinHalfLine, color_z, 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(drawPosition, drawPosition + up_normalized * lenghtOfThinHalfLine, color_y, 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(drawPosition, drawPosition + right_normalized * lenghtOfThinHalfLine, color_x, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + ///z: + if (hideZDir == false) + { + Vector3 zTextPos; + if (coordTextBelowAxes) + { + zTextPos = drawPosition - up_normalized * (spacingAboveLine + halfAbsMarkerLinesWidth + coordsTextSize) + forward_normalized * (spacingFromMarkerCross + halfAbsMarkerLinesWidth); + } + else + { + zTextPos = drawPosition + up_normalized * (spacingAboveLine + halfAbsMarkerLinesWidth) + forward_normalized * (spacingFromMarkerCross + halfAbsMarkerLinesWidth); + } + string coordSystemSpecifyingText_z = drawCoordSystemSpecifyingString ? (DrawText.MarkupColor(coordSystemSpecifyingStringIsLocal ? localCoordSystemSpecifyingText : globalCoordSystemSpecifyingText, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_z, coordSystemSpecifier_alpha))) : null; + string drawnCoordsText_z = (DrawBasics.strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM == 0) ? (coordSystemSpecifyingText_z + "z = " + positionCoordsToWrite.z) : (coordSystemSpecifyingText_z + "z = " + positionCoordsToWrite.z + ""); + UtilitiesDXXL_Text.Write(drawnCoordsText_z, zTextPos, color_z, coordsTextSize, forward_normalized, up_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, maxTextLength, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + + ///y: + Vector3 yTextPos; + if (coordTextBelowAxes) + { + yTextPos = drawPosition - Vector3.left * (spacingAboveLine + halfAbsMarkerLinesWidth + coordsTextSize) + up_normalized * (spacingFromMarkerCross + halfAbsMarkerLinesWidth); + } + else + { + yTextPos = drawPosition + Vector3.left * (spacingAboveLine + halfAbsMarkerLinesWidth) + up_normalized * (spacingFromMarkerCross + halfAbsMarkerLinesWidth); + } + string coordSystemSpecifyingText_y = drawCoordSystemSpecifyingString ? (DrawText.MarkupColor(coordSystemSpecifyingStringIsLocal ? localCoordSystemSpecifyingText : globalCoordSystemSpecifyingText, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_y, coordSystemSpecifier_alpha))) : null; + string drawnCoordsText_y = (DrawBasics.strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM == 0) ? (coordSystemSpecifyingText_y + "y = " + positionCoordsToWrite.y) : (coordSystemSpecifyingText_y + "y = " + positionCoordsToWrite.y + ""); + UtilitiesDXXL_Text.Write(drawnCoordsText_y, yTextPos, color_y, coordsTextSize, up_normalized, (-right_normalized), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, maxTextLength, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + + ///x: + Vector3 xTextPos; + if (coordTextBelowAxes) + { + xTextPos = drawPosition - up_normalized * (spacingAboveLine + halfAbsMarkerLinesWidth + coordsTextSize) + right_normalized * (spacingFromMarkerCross + halfAbsMarkerLinesWidth); + } + else + { + xTextPos = drawPosition + up_normalized * (spacingAboveLine + halfAbsMarkerLinesWidth) + right_normalized * (spacingFromMarkerCross + halfAbsMarkerLinesWidth); + } + string coordSystemSpecifyingText_x = drawCoordSystemSpecifyingString ? (DrawText.MarkupColor(coordSystemSpecifyingStringIsLocal ? localCoordSystemSpecifyingText : globalCoordSystemSpecifyingText, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_x, coordSystemSpecifier_alpha))) : null; + string drawnCoordsText_x = (DrawBasics.strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM == 0) ? (coordSystemSpecifyingText_x + "x = " + positionCoordsToWrite.x) : (coordSystemSpecifyingText_x + "x = " + positionCoordsToWrite.x + ""); + UtilitiesDXXL_Text.Write(drawnCoordsText_x, xTextPos, color_x, coordsTextSize, right_normalized, up_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, maxTextLength, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + + public static float pointTagsTextSize_relToOffset = 0.1f; + public static void PointTag(Vector3 position, string text = null, Color color = default(Color), float linesWidth = 0.0f, float size_asTextOffsetDistance = 1.0f, Vector3 textOffsetDirection = default(Vector3), float textSizeScaleFactor = 1.0f, bool skipConeDrawing = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size_asTextOffsetDistance, "size_asTextOffsetDistance")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(textSizeScaleFactor, "textSizeScaleFactor")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textOffsetDirection, "textOffsetDirection")) { return; } + + //DO NOT fallback to "Point()" here, because "Point()" calls "PointTag()" again, which can create an endless loop. + + UtilitiesDXXL_TextDirAndUpCalculation.GetTextDirAndUpNormalized(out Vector3 textDir_normalized, out Vector3 textUp_normalized, default(Vector3), default(Vector3), position, false, false); + Vector3 textForward_normalized = Vector3.Cross(textDir_normalized, textUp_normalized); + if (UtilitiesDXXL_Math.IsDefaultVector(textOffsetDirection)) + { + Quaternion rotation = Quaternion.LookRotation(textForward_normalized, textUp_normalized); + textOffsetDirection = rotation * DrawBasics.Default_textOffsetDirection_forPointTags; + } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + size_asTextOffsetDistance = GetClamped_pointTagSize_asTextOffsetDistance(size_asTextOffsetDistance, linesWidth); + textSizeScaleFactor = Mathf.Abs(textSizeScaleFactor); + textSizeScaleFactor = Mathf.Max(textSizeScaleFactor, 0.01f); + + Vector3 textOffsetDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(textOffsetDirection); + Vector3 pos_to_startOfUnderLine = textOffsetDir_normalized * size_asTextOffsetDistance; + float coneHeight = 0.2f * size_asTextOffsetDistance; + coneHeight = Mathf.Max(coneHeight, 2.4f * linesWidth); + Vector3 startOfTextUnderline = position + pos_to_startOfUnderLine; + + if (skipConeDrawing) + { + Line_fadeableAnimSpeed.InternalDraw(position, startOfTextUnderline, color, linesWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + float offsetDistance_forStartAnchorOfLineToText = (3.0f * linesWidth); + offsetDistance_forStartAnchorOfLineToText = Mathf.Min(offsetDistance_forStartAnchorOfLineToText, coneHeight); + Vector3 offsettedStartAnchor_ofLineToText = position + offsetDistance_forStartAnchorOfLineToText * textOffsetDir_normalized; + Line_fadeableAnimSpeed.InternalDraw(offsettedStartAnchor_ofLineToText, startOfTextUnderline, color, linesWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + float textLength = 0.2f * size_asTextOffsetDistance; + if (text != null && text != "") + { + float textSize = pointTagsTextSize_relToOffset * textSizeScaleFactor * size_asTextOffsetDistance; + UtilitiesDXXL_Text.Write(text, startOfTextUnderline + textUp_normalized * (0.3f * textSize + 0.5f * linesWidth), color, textSize, textDir_normalized, textUp_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + float lengthOfLongestLine_inText = DrawText.parsedTextSpecs.widthOfLongestLine; + textLength = Mathf.Max(textLength, lengthOfLongestLine_inText); + } + Line_fadeableAnimSpeed.InternalDraw(startOfTextUnderline, startOfTextUnderline + textDir_normalized * textLength, color, linesWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + if (skipConeDrawing == false) + { + float coneAngleDeg = 25.0f; + Vector3 upVector_ofConeBaseRect = textForward_normalized; + DrawShapes.ConeFilled(position, coneHeight, pos_to_startOfUnderLine, upVector_ofConeBaseRect, 0.0f, coneAngleDeg, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + } + + public static float GetClamped_pointTagSize_asTextOffsetDistance(float size_asTextOffsetDistance_unclamped, float linesWidth) + { + size_asTextOffsetDistance_unclamped = Mathf.Abs(size_asTextOffsetDistance_unclamped); + return UtilitiesDXXL_Math.Max(size_asTextOffsetDistance_unclamped, 3.0f * linesWidth, 0.01f); + } + + static DrawBasics.LengthInterpretation endPlates_sizeInterpretation_before; + public static void Set_endPlates_sizeInterpretation_reversible(DrawBasics.LengthInterpretation newSizeInterpretation) + { + endPlates_sizeInterpretation_before = DrawBasics.endPlates_sizeInterpretation; + DrawBasics.endPlates_sizeInterpretation = newSizeInterpretation; + } + public static void Reverse_endPlates_sizeInterpretation() + { + DrawBasics.endPlates_sizeInterpretation = endPlates_sizeInterpretation_before; + } + + static bool disableEndPlates_atLineStart_before; + public static void Set_disableEndPlates_atLineStart_reversible(bool new_disableEndPlates_atLineStart) + { + disableEndPlates_atLineStart_before = DrawBasics.disableEndPlates_atLineStart; + DrawBasics.disableEndPlates_atLineStart = new_disableEndPlates_atLineStart; + } + public static void Reverse_disableEndPlates_atLineStart() + { + DrawBasics.disableEndPlates_atLineStart = disableEndPlates_atLineStart_before; + } + + static bool disableEndPlates_atLineEnd_before; + public static void Set_disableEndPlates_atLineEnd_reversible(bool new_disableEndPlates_atLineEnd) + { + disableEndPlates_atLineEnd_before = DrawBasics.disableEndPlates_atLineEnd; + DrawBasics.disableEndPlates_atLineEnd = new_disableEndPlates_atLineEnd; + } + public static void Reverse_disableEndPlates_atLineEnd() + { + DrawBasics.disableEndPlates_atLineEnd = disableEndPlates_atLineEnd_before; + } + + public static float Set_coneLength_interpretation_forStraightVectors_reversible(bool setConeLengthToRelative_notToAbsolute, float coneLength_ifSetToRelative, float coneLength_ifSetToAbsolute) + { + if (setConeLengthToRelative_notToAbsolute) + { + Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + return coneLength_ifSetToRelative; + } + else + { + Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + return coneLength_ifSetToAbsolute; + } + } + + static DrawBasics.LengthInterpretation coneLength_interpretationn_forStraightVectors_before; + public static void Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation newLengthInterpretation) + { + coneLength_interpretationn_forStraightVectors_before = DrawBasics.coneLength_interpretation_forStraightVectors; + DrawBasics.coneLength_interpretation_forStraightVectors = newLengthInterpretation; + } + public static void Reverse_coneLength_interpretation_forStraightVectors() + { + DrawBasics.coneLength_interpretation_forStraightVectors = coneLength_interpretationn_forStraightVectors_before; + } + + public static float Set_coneLength_interpretation_forCircledVectors_reversible(bool setConeLengthToRelative_notToAbsolute, float coneLength_ifSetToRelative, float coneLength_ifSetToAbsolute) + { + if (setConeLengthToRelative_notToAbsolute) + { + Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + return coneLength_ifSetToRelative; + } + else + { + Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + return coneLength_ifSetToAbsolute; + } + } + + static DrawBasics.LengthInterpretation coneLength_interpretationn_forCircledVectors_before; + public static void Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation newLengthInterpretation) + { + coneLength_interpretationn_forCircledVectors_before = DrawBasics.coneLength_interpretation_forCircledVectors; + DrawBasics.coneLength_interpretation_forCircledVectors = newLengthInterpretation; + } + public static void Reverse_coneLength_interpretation_forCircledVectors() + { + DrawBasics.coneLength_interpretation_forCircledVectors = coneLength_interpretationn_forCircledVectors_before; + } + + static DrawBasics.AutomaticAmplitudeAndTextAlignment automaticAmplitudeAndTextAlignment_before; + public static void Set_automaticAmplitudeAndTextAlignment_reversible(DrawBasics.AutomaticAmplitudeAndTextAlignment new_automaticAmplitudeAndTextAlignment) + { + automaticAmplitudeAndTextAlignment_before = DrawBasics.automaticAmplitudeAndTextAlignment; + DrawBasics.automaticAmplitudeAndTextAlignment = new_automaticAmplitudeAndTextAlignment; + } + public static void Reverse_automaticAmplitudeAndTextAlignment() + { + DrawBasics.automaticAmplitudeAndTextAlignment = automaticAmplitudeAndTextAlignment_before; + } + + static DrawBasics.CameraForAutomaticOrientation cameraForAutomaticOrientation_before; + public static void Set_cameraForAutomaticOrientation_reversible(DrawBasics.CameraForAutomaticOrientation new_cameraForAutomaticOrientation) + { + cameraForAutomaticOrientation_before = DrawBasics.cameraForAutomaticOrientation; + DrawBasics.cameraForAutomaticOrientation = new_cameraForAutomaticOrientation; + } + public static void Reverse_cameraForAutomaticOrientation() + { + DrawBasics.cameraForAutomaticOrientation = cameraForAutomaticOrientation_before; + } + + static DrawBasics.UsedUnityLineDrawingMethod usedLineDrawingMethod_before; + public static void Set_usedLineDrawingMethod_reversible(DrawBasics.UsedUnityLineDrawingMethod new_usedLineDrawingMethod) + { +#if UNITY_EDITOR + usedLineDrawingMethod_before = DrawBasics.usedUnityLineDrawingMethod; + DrawBasics.usedUnityLineDrawingMethod = new_usedLineDrawingMethod; +#else + DrawBasics.usedUnityLineDrawingMethod = DrawBasics.UsedUnityLineDrawingMethod.wireMesh; +#endif + } + public static void Reverse_usedLineDrawingMethod() + { +#if UNITY_EDITOR + DrawBasics.usedUnityLineDrawingMethod = usedLineDrawingMethod_before; +#endif + } + + static Matrix4x4 gizmoMatrix_before; + public static void Set_gizmoMatrix_reversible(Matrix4x4 new_gizmoMatrix) + { + gizmoMatrix_before = Gizmos.matrix; + Gizmos.matrix = new_gizmoMatrix; + } + public static void Reverse_gizmoMatrix() + { + Gizmos.matrix = gizmoMatrix_before; + } + + static int strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_before; + public static void Set_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_reversible(int new_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM) + { + strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_before = DrawBasics.strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM; + DrawBasics.strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM = new_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM; + } + public static void Reverse_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM() + { + DrawBasics.strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM = strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_before; + } + + static float relSizeOfTextOnLines_before; + public static void Set_relSizeOfTextOnLines_reversible(float new_relSizeOfTextOnLines) + { + relSizeOfTextOnLines_before = DrawBasics.RelSizeOfTextOnLines; + DrawBasics.RelSizeOfTextOnLines = new_relSizeOfTextOnLines; + } + public static void Reverse_relSizeOfTextOnLines() + { + DrawBasics.RelSizeOfTextOnLines = relSizeOfTextOnLines_before; + } + + static bool shiftTextPosOnLines_toNonIntersecting_before; + public static void Set_shiftTextPosOnLines_toNonIntersecting_reversible(bool new_shiftTextPosOnLines_toNonIntersecting) + { + shiftTextPosOnLines_toNonIntersecting_before = DrawBasics.shiftTextPosOnLines_toNonIntersecting; + DrawBasics.shiftTextPosOnLines_toNonIntersecting = new_shiftTextPosOnLines_toNonIntersecting; + } + public static void Reverse_shiftTextPosOnLines_toNonIntersecting() + { + DrawBasics.shiftTextPosOnLines_toNonIntersecting = shiftTextPosOnLines_toNonIntersecting_before; + } + + static float globalAlphaFactor_before; + public static void Set_globalAlphaFactor_reversible(float new_globalAlphaFactor) + { + globalAlphaFactor_before = DrawBasics.GlobalAlphaFactor; + DrawBasics.GlobalAlphaFactor = new_globalAlphaFactor; + } + public static void Reverse_globalAlphaFactor() + { + DrawBasics.GlobalAlphaFactor = globalAlphaFactor_before; + } + + public static void Vector(Vector3 vectorStartPos, Vector3 vectorEndPos, Color color, float lineWidth, string text, float coneLength, bool pointerAtBothSides, bool flattenThickRoundLineIntoAmplitudePlane, bool addNormalizedMarkingText, float enlargeSmallTextToThisMinTextSize, bool writeComponentValuesAsText, float durationInSec, bool hiddenByNearerObjects, Vector3 customAmplitudeAndTextDir, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size) + { + //-> amplitude specified via vector + Vector(vectorStartPos, vectorEndPos, color, lineWidth, text, coneLength, pointerAtBothSides, flattenThickRoundLineIntoAmplitudePlane, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, durationInSec, hiddenByNearerObjects, null, customAmplitudeAndTextDir, drawnLineIsFrom_DrawBasics2D, endPlates_size); + } + + public static void Vector(Vector3 vectorStartPos, Vector3 vectorEndPos, Color color, float lineWidth, string text, float coneLength, bool pointerAtBothSides, bool flattenThickRoundLineIntoAmplitudePlane, bool addNormalizedMarkingText, float enlargeSmallTextToThisMinTextSize, bool writeComponentValuesAsText, float durationInSec, bool hiddenByNearerObjects, InternalDXXL_Plane preferredAmplitudePlane, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size) + { + //-> amplitude specified via plane + Vector(vectorStartPos, vectorEndPos, color, lineWidth, text, coneLength, pointerAtBothSides, flattenThickRoundLineIntoAmplitudePlane, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, durationInSec, hiddenByNearerObjects, preferredAmplitudePlane, default(Vector3), drawnLineIsFrom_DrawBasics2D, endPlates_size); + } + + public static void Vector(Vector3 vectorStartPos, Vector3 vectorEndPos, Color color, float lineWidth, string text, float coneLength, bool pointerAtBothSides, bool flattenThickRoundLineIntoAmplitudePlane, bool addNormalizedMarkingText, float enlargeSmallTextToThisMinTextSize, bool writeComponentValuesAsText, float durationInSec, bool hiddenByNearerObjects, InternalDXXL_Plane preferredAmplitudePlane, Vector3 customAmplitudeAndTextDir, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorStartPos, "vectorStartPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorEndPos, "vectorEndPos")) { return; } + VectorFrom(vectorStartPos, vectorEndPos - vectorStartPos, color, lineWidth, text, coneLength, pointerAtBothSides, flattenThickRoundLineIntoAmplitudePlane, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, durationInSec, hiddenByNearerObjects, preferredAmplitudePlane, customAmplitudeAndTextDir, drawnLineIsFrom_DrawBasics2D, endPlates_size); + } + + public static void VectorFrom(Vector3 vectorStartPos, Vector3 vector, Color color, float lineWidth, string text, float coneLength, bool pointerAtBothSides, bool flattenThickRoundLineIntoAmplitudePlane, bool addNormalizedMarkingText, float enlargeSmallTextToThisMinTextSize, bool writeComponentValuesAsText, float durationInSec, bool hiddenByNearerObjects, Vector3 customAmplitudeAndTextDir, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size) + { + VectorFrom(vectorStartPos, vector, color, lineWidth, text, coneLength, pointerAtBothSides, flattenThickRoundLineIntoAmplitudePlane, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, durationInSec, hiddenByNearerObjects, null, customAmplitudeAndTextDir, drawnLineIsFrom_DrawBasics2D, endPlates_size); + } + + public static void VectorFrom(Vector3 vectorStartPos, Vector3 vector, Color color, float lineWidth, string text, float coneLength, bool pointerAtBothSides, bool flattenThickRoundLineIntoAmplitudePlane, bool addNormalizedMarkingText, float enlargeSmallTextToThisMinTextSize, bool writeComponentValuesAsText, float durationInSec, bool hiddenByNearerObjects, InternalDXXL_Plane preferredAmplitudePlane, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size) + { + VectorFrom(vectorStartPos, vector, color, lineWidth, text, coneLength, pointerAtBothSides, flattenThickRoundLineIntoAmplitudePlane, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, writeComponentValuesAsText, durationInSec, hiddenByNearerObjects, preferredAmplitudePlane, default(Vector3), drawnLineIsFrom_DrawBasics2D, endPlates_size); + } + + public static void VectorFrom(Vector3 vectorStartPos, Vector3 vector, Color color, float lineWidth, string text, float coneLength, bool pointerAtBothSides, bool flattenThickRoundLineIntoAmplitudePlane, bool addNormalizedMarkingText, float enlargeSmallTextToThisMinTextSize, bool writeComponentValuesAsText, float durationInSec, bool hiddenByNearerObjects, InternalDXXL_Plane preferredAmplitudePlane, Vector3 customAmplitudeAndTextDir, bool drawnLineIsFrom_DrawBasics2D, float endPlates_size) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth, "lineWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(coneLength, "coneLength")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorStartPos, "vectorStartPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector, "vector")) { return; } + + lineWidth = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth); + + if (UtilitiesDXXL_Math.ApproximatelyZero(vector)) + { + if (UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine == false) + { + DrawFallbackForApproxZeroLengthVectors(drawnLineIsFrom_DrawBasics2D, vectorStartPos, color, lineWidth, text, durationInSec, hiddenByNearerObjects); + } + return; + } + + Vector3 vectorEndPos = vectorStartPos + vector; + bool isThinLine = UtilitiesDXXL_Math.ApproximatelyZero(lineWidth); + Vector3 vectorNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(vector, out float vectorLength); + + if (vectorLength < UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.shortestLineWithDefinedAmplitudeDir) + { + if (UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine == false) + { + DrawFallbackForApproxZeroLengthVectors(drawnLineIsFrom_DrawBasics2D, vectorStartPos, color, lineWidth, text, durationInSec, hiddenByNearerObjects); + } + return; + } + + if (DrawBasics.coneLength_interpretation_forStraightVectors == DrawBasics.LengthInterpretation.relativeToLineLength) { coneLength = coneLength * vectorLength; } + coneLength = Mathf.Clamp(coneLength, min_relConeLengthForVectors * vectorLength, max_relConeLengthForVectors * vectorLength); + + float coneAngleDeg = curr_vectorConeAngleDeg; + if (isThinLine == false) + { + float coneSize_to_lineWidth_scaler = 1.0f; + float minConeAngleDeg = 2.0f * Mathf.Rad2Deg * Mathf.Atan(coneSize_to_lineWidth_scaler * lineWidth / coneLength); + coneAngleDeg = Mathf.Max(coneAngleDeg, minConeAngleDeg); + } + + float lengthTillConeStart = vectorLength - coneLength; + Vector3 endConeBaseCenter = vectorStartPos + vectorNormalized * lengthTillConeStart; + Vector3 startConeBaseCenter = vectorStartPos; + if (pointerAtBothSides) + { + startConeBaseCenter = vectorStartPos + vectorNormalized * coneLength; + } + + if (writeComponentValuesAsText) + { + if (drawnLineIsFrom_DrawBasics2D) + { + text = "( " + vector.x + " , " + vector.y + " )
" + text; + } + else + { + text = "( " + vector.x + " , " + vector.y + " , " + vector.z + " )
" + text; + } + } + Line(startConeBaseCenter, endConeBaseCenter, color, lineWidth, text, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, preferredAmplitudePlane, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, 0.0f, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, false, false, null, drawnLineIsFrom_DrawBasics2D, 0.0f, 1.0f); + + float shorteningOf_straightLineInsideCone = 0.0f; + if (isThinLine == false) + { + shorteningOf_straightLineInsideCone = (0.5f * lineWidth) / Mathf.Tan(Mathf.Deg2Rad * 0.5f * coneAngleDeg); + shorteningOf_straightLineInsideCone = Mathf.Min(shorteningOf_straightLineInsideCone, 0.99f * coneLength); + } + + Vector3 lineEndInsideEndCone = vectorEndPos - vectorNormalized * shorteningOf_straightLineInsideCone; + Line(endConeBaseCenter, lineEndInsideEndCone, color, lineWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, preferredAmplitudePlane, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + if (pointerAtBothSides) + { + Vector3 lineEndInsideStartCone = vectorStartPos + vectorNormalized * shorteningOf_straightLineInsideCone; + Line(startConeBaseCenter, lineEndInsideStartCone, color, lineWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, preferredAmplitudePlane, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + } + + DrawBasics.LineStyle dummyStyle_forForcingCalcDefinedAmplitudeDir = DrawBasics.LineStyle.zigzag; //-> the logic in which cases a definedUp_amplitude is needed here differs from the default implementation in "UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.CheckWhichDirectionsAreNeeded()", therefore this dummyStyle is used to ensure that such a definedUp_amplitude is always calced (also if it is not always required). It may also get overwritten by "UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine" + UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.Get_normalized_amplitudeAndTextDirVectors(out Vector3 upVector_insideConeBaseCircle, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, vectorStartPos, vector, false, false, null, false, dummyStyle_forForcingCalcDefinedAmplitudeDir, true, false, preferredAmplitudePlane, customAmplitudeAndTextDir, null, false); + + useMoreStrutsForFlatPyramidArrow = ((isThinLine == false) && color.a < 0.8f); //thick arrows with low alpha (like in "DrawPhysics.VolumeCast()") look irregular with lower values of "DrawShapes.cornersOnFlatPyramidBase" + float coneAngleDeg_inHorizDir = flattenThickRoundLineIntoAmplitudePlane ? 0.0f : coneAngleDeg; + DrawShapes.ConeFilled(vectorEndPos, coneLength, -vector, upVector_insideConeBaseCircle, coneAngleDeg, coneAngleDeg_inHorizDir, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + if (pointerAtBothSides) + { + DrawShapes.ConeFilled(vectorStartPos, coneLength, vector, upVector_insideConeBaseCircle, coneAngleDeg, coneAngleDeg_inHorizDir, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + useMoreStrutsForFlatPyramidArrow = false; + + if (addNormalizedMarkingText) + { + Vector3 aVectorPerpToDrawnVector_normalized = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(vectorNormalized); + Vector3 textsInitialDir_normalized = Vector3.Cross(aVectorPerpToDrawnVector_normalized, vectorNormalized); + float half_lineWidth = 0.5f * lineWidth; + float textRadius = 0.05f + half_lineWidth; + float textSize = 0.4f * textRadius; + UtilitiesDXXL_Text.WriteOnCircle("normalized", vectorStartPos + vectorNormalized, textRadius, color, textSize, textsInitialDir_normalized, aVectorPerpToDrawnVector_normalized, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + Line_fadeableAnimSpeed.InternalDraw(vectorStartPos, vectorStartPos + vectorNormalized, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.2f), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(endPlates_size) == false) + { + DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.invisible; + Line(vectorStartPos, vectorEndPos, color, 0.0f, null, lineStyle, 1.0f, 0.0f, null, preferredAmplitudePlane, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, endPlates_size, 1.0f); + } + } + + static void DrawFallbackForApproxZeroLengthVectors(bool drawnLineIsFrom_DrawBasics2D, Vector3 vectorStartPos, Color color, float lineWidth, string text, float durationInSec, bool hiddenByNearerObjects) + { + if (drawnLineIsFrom_DrawBasics2D) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(vectorStartPos, "[ Vector with length of approximately 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + } + else + { + PointFallback(vectorStartPos, "[ Vector with length of approximately 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + } + } + + public static LineAnimationProgress MovingArrowsLine(Vector3 start, Vector3 end, Color color, float lineWidth, float distanceBetweenArrows, float lengthOfArrows, string text, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, bool pointersDirAlongAnimationDir, bool flattenThickRoundLineIntoAmplitudePlane, Vector3 customAmplitudeAndTextDir, float endPlates_size, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool drawnLineIsFrom_DrawBasics2D) + { + //-> amplitude specified via vector + return MovingArrowsLine(start, end, color, lineWidth, distanceBetweenArrows, lengthOfArrows, text, animationSpeed, precedingLineAnimationProgress, pointersDirAlongAnimationDir, flattenThickRoundLineIntoAmplitudePlane, null, customAmplitudeAndTextDir, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, drawnLineIsFrom_DrawBasics2D); + } + + public static LineAnimationProgress MovingArrowsLine(Vector3 start, Vector3 end, Color color, float lineWidth, float distanceBetweenArrows, float lengthOfArrows, string text, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, bool pointersDirAlongAnimationDir, bool flattenThickRoundLineIntoAmplitudePlane, InternalDXXL_Plane preferredAmplitudePlane, float endPlates_size, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool drawnLineIsFrom_DrawBasics2D) + { + //-> amplitude specified via plane + return MovingArrowsLine(start, end, color, lineWidth, distanceBetweenArrows, lengthOfArrows, text, animationSpeed, precedingLineAnimationProgress, pointersDirAlongAnimationDir, flattenThickRoundLineIntoAmplitudePlane, preferredAmplitudePlane, default(Vector3), endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, drawnLineIsFrom_DrawBasics2D); + } + + public static LineAnimationProgress MovingArrowsLine(Vector3 start, Vector3 end, Color color, float lineWidth, float distanceBetweenArrows, float lengthOfArrows, string text, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, bool pointersDirAlongAnimationDir, bool flattenThickRoundLineIntoAmplitudePlane, InternalDXXL_Plane preferredAmplitudePlane, Vector3 customAmplitudeAndTextDir, float endPlates_size, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool drawnLineIsFrom_DrawBasics2D) + { + //Lines drawn with this function have a higher likelyhood of accidentially using up high numbers of drawnLinePerFrame, because "distanceBetweenArrows" and "lengthOfArrows" can be set manually instead of beeing determined by the lineStyle-code + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth, "lineWidth")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceBetweenArrows, "distanceBetweenArrows")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lengthOfArrows, "lengthOfArrows")) { return null; } + + lineWidth = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth); + //small or big values of "distanceBetweenArrows" and "lengthOfArrows" may additionally get changed in "UtilitiesDXXL_LineStyles" inside the "skipPatternEnlargementFor*Lines == false" mechanic. + distanceBetweenArrows = Mathf.Max(distanceBetweenArrows, 0.0002f); + lengthOfArrows = Mathf.Min(lengthOfArrows, 0.9f * distanceBetweenArrows); + lengthOfArrows = Mathf.Max(lengthOfArrows, 0.0001f); + float lengthOfEmptySpaces = distanceBetweenArrows - lengthOfArrows; + LineAnimationProgress lineAnimProgressAfterDrawing = null; + + UtilitiesDXXL_LineStyles.curr_pointersDirAlongAnimationDir = pointersDirAlongAnimationDir; + try + { + UtilitiesDXXL_LineStyles.curr_dashLength_forArrowLine = lengthOfArrows; + if (UtilitiesDXXL_Math.ApproximatelyZero(lineWidth) == false) + { + UtilitiesDXXL_LineStyles.curr_minRatio_for_dashLengthToLineWidth_forArrowLine = lengthOfArrows / lineWidth; + } + UtilitiesDXXL_LineStyles.curr_spaceToDash_ratio_forArrowLine = lengthOfEmptySpaces / lengthOfArrows; + UtilitiesDXXL_LineStyles.curr_minEmptySpacesLength_forArrowLine = lengthOfEmptySpaces; + lineAnimProgressAfterDrawing = Line(start, end, color, lineWidth, text, DrawBasics.LineStyle.arrows, 1.0f, animationSpeed, precedingLineAnimationProgress, preferredAmplitudePlane, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, 0.0f, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, false, false, null, drawnLineIsFrom_DrawBasics2D, endPlates_size, 1.0f); + } + catch { } + + UtilitiesDXXL_LineStyles.curr_pointersDirAlongAnimationDir = UtilitiesDXXL_LineStyles.default_pointersDirAlongAnimationDir; + UtilitiesDXXL_LineStyles.curr_dashLength_forArrowLine = UtilitiesDXXL_LineStyles.default_dashLength_forArrowLine; + UtilitiesDXXL_LineStyles.curr_minRatio_for_dashLengthToLineWidth_forArrowLine = UtilitiesDXXL_LineStyles.default_minRatio_for_dashLengthToLineWidth_forArrowLine; + UtilitiesDXXL_LineStyles.curr_spaceToDash_ratio_forArrowLine = UtilitiesDXXL_LineStyles.default_spaceToDash_ratio_forArrowLine; + UtilitiesDXXL_LineStyles.curr_minEmptySpacesLength_forArrowLine = UtilitiesDXXL_LineStyles.default_minEmptySpacesLength_forArrowLine; + + return lineAnimProgressAfterDrawing; + } + + public static bool GetSpecsOfLineUnderTension(out float tensionFactor, out Color usedColor, out float lineLength, Vector3 start, Vector3 end, float relaxedLength, Color relaxedColor, Color color_forStretchedTension, Color color_forSqueezedTension, float stretchFactor_forStretchedTensionColor, float stretchFactor_forSqueezedTensionColor) + { + //returns "parametersAreInvalid" + + tensionFactor = 1.0f; //-> for invalid early returns + usedColor = default; //-> for invalid early returns + lineLength = 1.0f; //-> for invalid early returns + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return true; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return true; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(relaxedLength, "relaxedLength")) { return true; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stretchFactor_forStretchedTensionColor, "stretchFactor_forStretchedTensionColor")) { return true; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stretchFactor_forSqueezedTensionColor, "stretchFactor_forSqueezedTensionColor")) { return true; } + + lineLength = (end - start).magnitude; + relaxedLength = Mathf.Abs(relaxedLength); + relaxedLength = Mathf.Max(relaxedLength, 0.001f); + tensionFactor = lineLength / relaxedLength; + tensionFactor = Mathf.Max(tensionFactor, 0.001f); + usedColor = GetColorOfLineUnderTension(relaxedColor, color_forStretchedTension, color_forSqueezedTension, lineLength, relaxedLength, stretchFactor_forStretchedTensionColor, stretchFactor_forSqueezedTensionColor); + return false; + } + + static Color GetColorOfLineUnderTension(Color relaxedColor, Color color_forStretchedTension, Color color_forSqueezedTension, float lineLength, float relaxedLength, float stretchFactor_forStretchedTensionColor, float stretchFactor_forSqueezedTensionColor) + { + stretchFactor_forStretchedTensionColor = Mathf.Abs(stretchFactor_forStretchedTensionColor); + stretchFactor_forStretchedTensionColor = Mathf.Max(1.001f, stretchFactor_forStretchedTensionColor); + + stretchFactor_forSqueezedTensionColor = Mathf.Abs(stretchFactor_forSqueezedTensionColor); + stretchFactor_forSqueezedTensionColor = Mathf.Min(0.999f, stretchFactor_forSqueezedTensionColor); + + float lineLength_markingStretchedColor = relaxedLength * stretchFactor_forStretchedTensionColor; + float lineLength_markingSqueezedColor = relaxedLength * stretchFactor_forSqueezedTensionColor; + + relaxedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(relaxedColor, UtilitiesDXXL_Colors.green_boolTrue); + color_forStretchedTension = UtilitiesDXXL_Colors.OverwriteDefaultColor(color_forStretchedTension, UtilitiesDXXL_Colors.red_boolFalse); + color_forSqueezedTension = UtilitiesDXXL_Colors.OverwriteDefaultColor(color_forSqueezedTension, UtilitiesDXXL_Colors.red_boolFalse); + + if (lineLength < lineLength_markingSqueezedColor) + { + return color_forSqueezedTension; + } + else + { + if (lineLength > lineLength_markingStretchedColor) + { + return color_forStretchedTension; + } + else + { + float absLengthDifference_fromRelaxed_toActualLineLength = Mathf.Abs(relaxedLength - lineLength); + if (lineLength < relaxedLength) + { + float absLengthDifference_fromRelaxed_toSqueezed = Mathf.Abs(relaxedLength - lineLength_markingSqueezedColor); + float progress0to1_fromRelaxedToSqueezed = absLengthDifference_fromRelaxed_toActualLineLength / absLengthDifference_fromRelaxed_toSqueezed; + return Color.Lerp(relaxedColor, color_forSqueezedTension, progress0to1_fromRelaxedToSqueezed); + } + else + { + float absLengthDifference_fromRelaxed_toStretched = Mathf.Abs(relaxedLength - lineLength_markingStretchedColor); + float progress0to1_fromRelaxedToStreched = absLengthDifference_fromRelaxed_toActualLineLength / absLengthDifference_fromRelaxed_toStretched; + return Color.Lerp(relaxedColor, color_forStretchedTension, progress0to1_fromRelaxedToStreched); + } + } + } + } + + public static void TryDrawReferenceLengthDisplay_ofLineUnderTension(Vector3 start, Vector3 end, float alphaOfReferenceLengthDisplay, float relaxedLength, Color relaxedColor, float lineLength, InternalDXXL_Plane preferredAmplitudePlane, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(alphaOfReferenceLengthDisplay) == false) + { + if (lineLength > 0.0001f) //-> prevent wrong results and divisionByZero in the region of float calculation imprecision + { + Vector3 startToEnd = end - start; + Vector3 startToEnd_normalized = startToEnd / lineLength; + Vector3 startToRelaxedLength = startToEnd_normalized * relaxedLength; + Color usedColor = UtilitiesDXXL_Colors.Get_color_butWithFixedAlpha(relaxedColor, alphaOfReferenceLengthDisplay); + bool flattenThickRoundLineIntoAmplitudePlane = true; + float endPlates_size = 0.06f; + Set_endPlates_sizeInterpretation_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + Line(start, start + startToRelaxedLength, usedColor, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, preferredAmplitudePlane, flattenThickRoundLineIntoAmplitudePlane, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, endPlates_size, 1.0f); + Reverse_endPlates_sizeInterpretation(); + } + } + } + + static void TryDrawPerpEndPlates(bool uses_endPlates, float endPlates_size, Vector3 amplitudeUp_normalized_ofMountingLine, float length_ofMountingLine, bool length_ofMountingLine_isFilled, bool flattenThickRoundLineIntoAmplitudePlane, Vector3 start_ofMountingLine, Vector3 end_ofMountingLine, Color startColor, Color endColor, float durationInSec, bool hiddenByNearerObjects) + { + if (uses_endPlates) + { + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) { endColor = startColor; } + Vector3 startToEnd = end_ofMountingLine - start_ofMountingLine; + float half_lengthOfPlate = GetHalfLengthOfEndPlate(startToEnd, endPlates_size, length_ofMountingLine, length_ofMountingLine_isFilled); + + if (flattenThickRoundLineIntoAmplitudePlane) + { + Vector3 mountingPosTo_plateStart = amplitudeUp_normalized_ofMountingLine * half_lengthOfPlate; + Vector3 mountingPosTo_plateEnd = (-mountingPosTo_plateStart); + InternalDXXL_AmplitudeDependentLineDetails amplitudeDependentLineDetails = Get_amplitudeDependentLineDetails_forThinEndPlateLine(); + + if (DrawBasics.disableEndPlates_atLineStart == false) + { + ThinLine(start_ofMountingLine + mountingPosTo_plateStart, start_ofMountingLine + mountingPosTo_plateEnd, startColor, startColor, null, 0.0f, 0.0f, durationInSec, 1.0f, 0.0f, null, hiddenByNearerObjects, false, false, false, amplitudeDependentLineDetails, 1.0f); + } + + if (DrawBasics.disableEndPlates_atLineEnd == false) + { + ThinLine(end_ofMountingLine + mountingPosTo_plateStart, end_ofMountingLine + mountingPosTo_plateEnd, endColor, endColor, null, 0.0f, 0.0f, durationInSec, 1.0f, 0.0f, null, hiddenByNearerObjects, false, false, false, amplitudeDependentLineDetails, 1.0f); + } + } + else + { + Vector3 up_insideDecagonPlane = default(Vector3); + Vector3 normal = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(startToEnd); + + if (DrawBasics.disableEndPlates_atLineStart == false) + { + UtilitiesDXXL_Shapes.Decagon(start_ofMountingLine, half_lengthOfPlate, startColor, normal, up_insideDecagonPlane, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, true, false, durationInSec, hiddenByNearerObjects, false); + } + + if (DrawBasics.disableEndPlates_atLineEnd == false) + { + UtilitiesDXXL_Shapes.Decagon(end_ofMountingLine, half_lengthOfPlate, endColor, normal, up_insideDecagonPlane, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, true, false, durationInSec, hiddenByNearerObjects, false); + } + } + } + } + + static float GetHalfLengthOfEndPlate(Vector3 startToEnd, float endPlates_size, float length_ofMountingLine, bool length_ofMountingLine_isFilled) + { + if (DrawBasics.endPlates_sizeInterpretation == DrawBasics.LengthInterpretation.relativeToLineLength) + { + float startToEnd_length; + if (length_ofMountingLine_isFilled) + { + startToEnd_length = length_ofMountingLine; + } + else + { + startToEnd_length = startToEnd.magnitude; + } + float lengthOfPlate = startToEnd_length * endPlates_size; + return (0.5f * lengthOfPlate); + } + else + { + return (0.5f * endPlates_size); + } + } + + static InternalDXXL_AmplitudeDependentLineDetails Get_amplitudeDependentLineDetails_forThinEndPlateLine() + { + InternalDXXL_AmplitudeDependentLineDetails amplitudeDependentLineDetails = new InternalDXXL_AmplitudeDependentLineDetails(); + amplitudeDependentLineDetails.lineWidth = 0.0f; + amplitudeDependentLineDetails.isThinLine = true; + amplitudeDependentLineDetails.enlargeSmallText = false; + amplitudeDependentLineDetails.textDrawingIsSkipped_dueToLineIsTooShort = false; + amplitudeDependentLineDetails.style = DrawBasics.LineStyle.solid; + amplitudeDependentLineDetails.uses_endPlates = false; //-> the now drawnLine is itself the endPlate -> this endPlate doesn't need further endPlates at itself. + amplitudeDependentLineDetails.endPlates_size = 0.0f; + amplitudeDependentLineDetails.amplitudeUp_normalized = default(Vector3); //-> the endPlates are thinLines of style=solid without text so they don't need an amplitudeDir + amplitudeDependentLineDetails.textDir_normalized = default(Vector3); + amplitudeDependentLineDetails.lengthOfDrawnLine_isFilled = false; + amplitudeDependentLineDetails.lengthOfDrawnLine = 0.0f; + return amplitudeDependentLineDetails; + } + + static List duplicatesPrintOffsetsForThickLineIcons = new List(); + static int usedSlots_inIconDuplicatesPrintOffsetList; + public static void Icon(Vector3 position, DrawBasics.IconType icon, Color color, float size, string text, Quaternion rotation, int strokeWidth_asPPMofSize, bool mirrorHorizontally, float durationInSec, bool hiddenByNearerObjects, float textScaleFactor, float minTextSize, bool autoFlipMirroredText_toFitObserverCam) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size, "size")) { return; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(size)) + { + PointFallback(position, "[Icon " + DrawText.MarkupIcon(icon) + " with size of 0]
" + text, color, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + //"UtilitiesDXXL_FlatShapesNormaAndUpCalculation" delivers "forward", not "normal" (see notes inside "UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetNormalAndUpInsidePlane()") + Quaternion unmirroredRotation = UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetQuaternion(rotation, position); + Quaternion mirroredRotation = default; + if (mirrorHorizontally) + { + Vector3 unmirroredUp = unmirroredRotation * Vector3.up; + Vector3 unmirroredForward = unmirroredRotation * Vector3.forward; + mirroredRotation = Quaternion.LookRotation((-unmirroredForward), unmirroredUp); + } + Quaternion usedRotation = mirrorHorizontally ? mirroredRotation : unmirroredRotation; + + strokeWidth_asPPMofSize = Mathf.Max(strokeWidth_asPPMofSize, 0); + strokeWidth_asPPMofSize = Mathf.Min(strokeWidth_asPPMofSize, 100000); + + UtilitiesDXXL_CharsAndIcons.RefillCurrPrintedCharDefWithZeroCenteredIcon(icon); + for (int i = 0; i < DrawXXL_LinesManager.instance.numberOfStrokes_forCurrUsedChar; i++) + { + UtilitiesDXXL_Text.TurnCharDef(ref DrawXXL_LinesManager.instance.currPrinted_charDef[i], usedRotation); + } + + float relativeStrokeWidth = (strokeWidth_asPPMofSize == 0) ? 0.0f : (0.000001f * strokeWidth_asPPMofSize); + usedSlots_inIconDuplicatesPrintOffsetList = UtilitiesDXXL_Text.GetDuplicatesPrintOffsetsUnrotated_ofTextIndependentIconOfSize1(ref duplicatesPrintOffsetsForThickLineIcons, size, relativeStrokeWidth); + UtilitiesDXXL_Text.TurnCharDef(ref duplicatesPrintOffsetsForThickLineIcons, usedSlots_inIconDuplicatesPrintOffsetList, usedRotation); + + for (int i_stroke = 0; i_stroke < DrawXXL_LinesManager.instance.numberOfStrokes_forCurrUsedChar; i_stroke++) + { + int linesInsideCurrStroke = DrawXXL_LinesManager.instance.numberOfPointsForEachStroke_forCurrUsedChar[i_stroke] - 1; + for (int i_point = 0; i_point < linesInsideCurrStroke; i_point++) + { + for (int i_duplicatePrint = 0; i_duplicatePrint < usedSlots_inIconDuplicatesPrintOffsetList; i_duplicatePrint++) + { + Vector3 lineStartPos = position + duplicatesPrintOffsetsForThickLineIcons[i_duplicatePrint] + DrawXXL_LinesManager.instance.currPrinted_charDef[i_stroke][i_point] * size; + Vector3 lineEndPos = position + duplicatesPrintOffsetsForThickLineIcons[i_duplicatePrint] + DrawXXL_LinesManager.instance.currPrinted_charDef[i_stroke][i_point + 1] * size; + Line_fadeableAnimSpeed.InternalDraw(lineStartPos, lineEndPos, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + + if (text != null && text != "") + { + Vector3 up_insideIconPlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(unmirroredRotation * Vector3.up); + float halfSize = 0.5f * size; + Vector3 textPosition = position - up_insideIconPlane_normalized * halfSize; + float textSize = textScaleFactor * size; + textSize = Mathf.Max(textSize, minTextSize); + float autoLineBreakWidth = size; + UtilitiesDXXL_Text.WriteFramed(text, textPosition, color, textSize, unmirroredRotation, DrawText.TextAnchorDXXL.UpperCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0025f, 0.0f, autoLineBreakWidth, autoFlipMirroredText_toFitObserverCam, durationInSec, hiddenByNearerObjects); + } + } + + public static Quaternion GetRotationOfIcon(Vector3 position, Vector3 normal, Vector3 up_insideIconPlane) + { + if (UtilitiesDXXL_Math.IsDefaultVector(normal) && UtilitiesDXXL_Math.IsDefaultVector(up_insideIconPlane)) + { + return default(Quaternion); //-> will use "DrawShapes.automaticOrientationOfFlatShapes" + } + else + { + Vector3 forward = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(-normal); + up_insideIconPlane = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(up_insideIconPlane); + UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetNormalAndUpInsidePlane(out Vector3 forward_final_notGuaranteedNormalized, out Vector3 up_insideIconPlane_normalized, forward, up_insideIconPlane, position); + return Quaternion.LookRotation(forward_final_notGuaranteedNormalized, up_insideIconPlane_normalized); + } + } + + public static void Dot(Vector3 position, float radius, Vector3 normal, Color color, string text, float density, float durationInSec, bool hiddenByNearerObjects, bool autoFlipMirroredText_toFitObserverCam) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal, "normal")) { return; } + + Quaternion rotation = GetRotationOfIcon(position, normal, default(Vector3)); + Dot(position, radius, rotation, color, text, density, durationInSec, hiddenByNearerObjects, 0.1f, 0.004f, autoFlipMirroredText_toFitObserverCam); + } + + public static void Dot(Vector3 position, float radius, Quaternion rotation, Color color, string text, float density, float durationInSec, bool hiddenByNearerObjects, float textScaleFactor, float minTextSize, bool autoFlipMirroredText_toFitObserverCam) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(density, "density")) { return; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(radius)) + { + PointFallback(position, "[ Dot with radius of 0]
" + text, color, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + int numberOfDrawnRings = 4 + Mathf.RoundToInt(Mathf.Abs(density) * 14); + float diameter = 2.0f * radius; + float diameterReduction_perDrawnCircle = diameter / (float)numberOfDrawnRings; + for (int i = 0; i < numberOfDrawnRings; i++) + { + string textAtCurrIcon = (i == 0) ? text : null; + float sizeOfCurrIcon = diameter - diameterReduction_perDrawnCircle * i; + Icon(position, DrawBasics.IconType.unitCircle, color, sizeOfCurrIcon, textAtCurrIcon, rotation, 0, false, durationInSec, hiddenByNearerObjects, textScaleFactor, minTextSize, autoFlipMirroredText_toFitObserverCam); + } + } + + static Color GetFadedColorFromSubLines(Color startColor, Color endColor, int usedSlotsInListOfSubLines, int i_startAnchorOfSubLine) + { + int numberOfSubLines = Mathf.RoundToInt(0.5f * usedSlotsInListOfSubLines); + int numberOfSubLinesMinus1 = numberOfSubLines - 1; + if (numberOfSubLinesMinus1 == 0) + { + return startColor; + } + + int i_subLine = Mathf.RoundToInt(0.5f * i_startAnchorOfSubLine); + + if (i_subLine == 0) + { + return startColor; + } + else + { + if (i_subLine == (numberOfSubLines - 1)) + { + return endColor; + } + else + { + float progress0to1 = (float)i_subLine / (float)(numberOfSubLinesMinus1); + return Color.Lerp(startColor, endColor, progress0to1); + } + } + } + + public static Color GetFadedColorFromSegments(Color startColor, Color endColor, int i_segment, int segments) + { + if (segments == 0) + { + return startColor; + } + + if (i_segment == 0) + { + return startColor; + } + else + { + if (i_segment == (segments - 1)) + { + return endColor; + } + else + { + return Color.Lerp(startColor, endColor, (float)i_segment / (float)segments); + } + } + } + + static Color GetColorWithAppliedAlpha_fromSubLines(Color colorToModify, bool hasAlphaFade, float alphaFadeOutLength_0to1, int i_subLineAnchor, int usedSlotsInListOfSubLines) + { + if (hasAlphaFade) + { + if (usedSlotsInListOfSubLines == 0) + { + return colorToModify; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(alphaFadeOutLength_0to1)) + { + return colorToModify; + } + + float maxAllowedAlpha = 1.0f; + if (i_subLineAnchor == 0 || i_subLineAnchor >= (usedSlotsInListOfSubLines - 2)) + { + maxAllowedAlpha = 0.1f; + } + float progress0to1 = (float)(i_subLineAnchor + 1) / (float)usedSlotsInListOfSubLines; + return ModifyColorWithAlpha(colorToModify, progress0to1, alphaFadeOutLength_0to1, maxAllowedAlpha); + } + else + { + return colorToModify; + } + } + + static Color GetColorWithAppliedAlpha_fromSegments(Color colorToModify, bool hasAlphaFade, float alphaFadeOutLength_0to1, int i_segment, int segments) + { + if (hasAlphaFade) + { + int segmentsPlus1 = segments + 1; + if (segmentsPlus1 == 0) + { + return colorToModify; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(alphaFadeOutLength_0to1)) + { + return colorToModify; + } + + float maxAllowedAlpha = 1.0f; + if (i_segment == 0 || i_segment >= (segments - 1)) + { + maxAllowedAlpha = 0.1f; + } + float progress0to1 = (float)(i_segment + 1) / (float)segmentsPlus1; + return ModifyColorWithAlpha(colorToModify, progress0to1, alphaFadeOutLength_0to1, maxAllowedAlpha); + } + else + { + return colorToModify; + } + } + + static Color ModifyColorWithAlpha(Color colorToModify, float progress0to1, float alphaFadeOutLength_0to1, float maxAllowedAlpha) + { + if (progress0to1 < 0.5f) + { + if (progress0to1 < alphaFadeOutLength_0to1) + { + float currAlpha = UtilitiesDXXL_Math.Get_2degParabolicSteepeningRise(progress0to1 / alphaFadeOutLength_0to1); + currAlpha = Mathf.Min(currAlpha, maxAllowedAlpha); + return UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorToModify, currAlpha); + } + else + { + return colorToModify; + } + } + else + { + float progressTillEnd_as0to1 = 1.0f - progress0to1; + if (progressTillEnd_as0to1 < alphaFadeOutLength_0to1) + { + float currAlpha = UtilitiesDXXL_Math.Get_2degParabolicSteepeningRise(progressTillEnd_as0to1 / alphaFadeOutLength_0to1); + currAlpha = Mathf.Min(currAlpha, maxAllowedAlpha); + return UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorToModify, currAlpha); + } + else + { + return colorToModify; + } + } + } + + public static void OverwriteDefaultVectorsWithStandardIdentity(ref Vector3 up, ref Vector3 forward, bool up_persistsDuringParallelCheck) + { + up = UtilitiesDXXL_Math.OverwriteDefaultVectors(up, Vector3.up); + forward = UtilitiesDXXL_Math.OverwriteDefaultVectors(forward, Vector3.forward); + if (up_persistsDuringParallelCheck) + { + forward = OverwriteParallelVectorsWithPerpVector(forward, up); + } + else + { + up = OverwriteParallelVectorsWithPerpVector(up, forward); + } + } + + static Vector3 OverwriteParallelVectorsWithPerpVector(Vector3 vectorToOverwrite_ifParallel, Vector3 referenceVector) + { + if (UtilitiesDXXL_Math.Check_ifTwoVectorsAreApproxParallel_butCanHeadToDifferntDirs_DXXL(vectorToOverwrite_ifParallel, referenceVector)) + { + return UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(referenceVector); + } + else + { + return vectorToOverwrite_ifParallel; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics.cs.meta new file mode 100644 index 0000000..1c8b7e6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9386eecb4b03c744b907131863ce3a1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics2D.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics2D.cs new file mode 100644 index 0000000..1f744c1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics2D.cs @@ -0,0 +1,131 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_DrawBasics2D + { + + public static InternalDXXL_Plane xyPlane_throughZero = new InternalDXXL_Plane(Vector3.zero, Vector3.forward); + + public static float TryFallbackToDefaultZ(float z_fromFunctionCallParameters) + { + if (float.IsNaN(z_fromFunctionCallParameters)) + { + //Debug.LogWarning("'custom_zPos' is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(z_fromFunctionCallParameters) + " -> fallback to Draw2D.Default_zPos_forDrawing (" + DrawBasics2D.Default_zPos_forDrawing + ")"); + return DrawBasics2D.Default_zPos_forDrawing; + } + else + { + if (float.IsInfinity(z_fromFunctionCallParameters)) + { + return DrawBasics2D.Default_zPos_forDrawing; + } + else + { + return z_fromFunctionCallParameters; + } + } + } + + public static Quaternion QuaternionFromAngle(float angleDegCC) + { + if (float.IsNaN(angleDegCC) || float.IsInfinity(angleDegCC)) + { + Debug.LogWarning("'angleDegCC' is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(angleDegCC) + " -> fallback to 'angleDegCC = 0'"); + return Quaternion.identity; + } + else + { + return ((UtilitiesDXXL_Math.ApproximatelyZero(angleDegCC)) ? Quaternion.identity : Quaternion.AngleAxis(angleDegCC, Vector3.forward)); + } + } + + public static Vector3 Position_V2toV3(Vector2 vector2Position, float zPos) + { + return new Vector3(vector2Position.x, vector2Position.y, zPos); + } + + public static Vector3 Direction_V2toV3(Vector2 vector2Direction) + { + return new Vector3(vector2Direction.x, vector2Direction.y, 0.0f); + } + + public static void PointFallback(Vector3 position, string text, Color color, float markingCrossLinesWidth, float durationInSec, bool hiddenByNearerObjects) + { + UtilitiesDXXL_DrawBasics.Point(true, position, text, color, 0.5f, markingCrossLinesWidth, color, Quaternion.identity, true, true, false, true, Vector3.zero, Quaternion.identity, Vector3.one, true, durationInSec, hiddenByNearerObjects); + } + + public static void PointFallback(Vector2 position, float zPos, string text, Color color, float markingCrossLinesWidth, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 positionV3 = new Vector3(position.x, position.y, zPos); + UtilitiesDXXL_DrawBasics.Point(true, positionV3, text, color, 0.5f, markingCrossLinesWidth, color, Quaternion.identity, true, true, false, true, Vector3.zero, Quaternion.identity, Vector3.one, true, durationInSec, hiddenByNearerObjects); + } + + public static void PointTag(Vector3 position, string text = null, Color color = default(Color), float linesWidth = 0.0f, float size_asTextOffsetDistance = 1.0f, Vector3 textOffsetDirection = default(Vector3), float textSizeScaleFactor = 1.0f, bool skipConeDrawing = false, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size_asTextOffsetDistance, "size_asTextOffsetDistance")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(textSizeScaleFactor, "textSizeScaleFactor")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textOffsetDirection, "textOffsetDirection")) { return; } + + //DO NOT fallback to "Point()" here, because "Point()" calls "PointTag()" again, which can create an endless loop. + + if (UtilitiesDXXL_Math.IsDefaultVector(textOffsetDirection)) { textOffsetDirection = new Vector3(DrawBasics.Default_textOffsetDirection_forPointTags.x, DrawBasics.Default_textOffsetDirection_forPointTags.y, 0.0f); } + if (UtilitiesDXXL_Math.IsDefaultVector(textOffsetDirection)) { textOffsetDirection = UtilitiesDXXL_DrawBasics.default_default_textOffsetDirection_forPointTags; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + size_asTextOffsetDistance = UtilitiesDXXL_DrawBasics.GetClamped_pointTagSize_asTextOffsetDistance(size_asTextOffsetDistance, linesWidth); + textSizeScaleFactor = Mathf.Abs(textSizeScaleFactor); + textSizeScaleFactor = Mathf.Max(textSizeScaleFactor, 0.01f); + + Vector3 textOffsetDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(textOffsetDirection); + Vector3 pos_to_startOfUnderLine = textOffsetDir_normalized * size_asTextOffsetDistance; + float coneHeight = 0.2f * size_asTextOffsetDistance; + coneHeight = Mathf.Max(coneHeight, 2.4f * linesWidth); + Vector3 startOfTextUnderline = position + pos_to_startOfUnderLine; + + if (skipConeDrawing) + { + Line_fadeableAnimSpeed.InternalDraw(position, startOfTextUnderline, color, linesWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + float offsetDistance_forStartAnchorOfLineToText = (3.0f * linesWidth); + offsetDistance_forStartAnchorOfLineToText = Mathf.Min(offsetDistance_forStartAnchorOfLineToText, coneHeight); + Vector3 offsettedStartAnchor_ofLineToText = position + offsetDistance_forStartAnchorOfLineToText * textOffsetDir_normalized; + Line_fadeableAnimSpeed.InternalDraw(offsettedStartAnchor_ofLineToText, startOfTextUnderline, color, linesWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + float dotProductResult_of_globalRight_and_textOffsetDir = Vector3.Dot(Vector3.right, textOffsetDir_normalized); + float absDotProductResult_of_globalRight_and_textOffsetDir = Mathf.Abs(dotProductResult_of_globalRight_and_textOffsetDir); + bool pointerIsApproxVert = (absDotProductResult_of_globalRight_and_textOffsetDir < UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.absDotProductResult_ofTwoApproxNormalizedVectors_belowWhichVectorsAreConsideredPerp); + bool textIsOnLeftSideOfPoint = dotProductResult_of_globalRight_and_textOffsetDir < 0.0f; + if (pointerIsApproxVert) { textIsOnLeftSideOfPoint = false; } //-> this prevents jitter in vert case (which is otherwise bistable due to float calculation imprecision) + + float textLength = 0.2f * size_asTextOffsetDistance; + if (text != null && text != "") + { + float textSize = UtilitiesDXXL_DrawBasics.pointTagsTextSize_relToOffset * textSizeScaleFactor * size_asTextOffsetDistance; + DrawText.TextAnchorDXXL textAnchor = textIsOnLeftSideOfPoint ? DrawText.TextAnchorDXXL.LowerRightOfFirstLine : DrawText.TextAnchorDXXL.LowerLeftOfFirstLine; + UtilitiesDXXL_Text.Write(text, startOfTextUnderline + Vector3.up * (0.3f * textSize + 0.5f * linesWidth), color, textSize, Vector3.right, Vector3.up, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + float lengthOfLongestLine_inText = DrawText.parsedTextSpecs.widthOfLongestLine; + textLength = Mathf.Max(textLength, lengthOfLongestLine_inText); + } + + Vector3 lineEnd = textIsOnLeftSideOfPoint ? (startOfTextUnderline + Vector3.left * textLength) : (startOfTextUnderline + Vector3.right * textLength); + Line_fadeableAnimSpeed.InternalDraw(startOfTextUnderline, lineEnd, color, linesWidth, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + if (skipConeDrawing == false) + { + float coneAngleDeg = 25.0f; + Vector3 upVector_ofConeBaseRect = Vector3.forward; + DrawShapes.ConeFilled(position, coneHeight, pos_to_startOfUnderLine, upVector_ofConeBaseRect, 0.0f, coneAngleDeg, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics2D.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics2D.cs.meta new file mode 100644 index 0000000..73489b9 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawBasics2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57a03eec29326c84b88fc0230c7d2cbc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawCollections.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawCollections.cs new file mode 100644 index 0000000..55db2dc --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawCollections.cs @@ -0,0 +1,364 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_DrawCollections + { + public delegate string FlexibleGetColumnContentAtIndexAsString(T collection, int i_whereToObtain); + static bool saveDrawnLines_forBoolCollections = false; + static int boolCollectionLength_aboveWhichDrawnLinesAreSaved = 20; + + public static string GetBoolAsStringFromArray(bool[] boolArray, int i_whereToObtain) + { + return DrawText.MarkupBoolDisplayer(boolArray[i_whereToObtain], saveDrawnLines_forBoolCollections); + } + + public static string GetBoolAsStringFromList(List boolList, int i_whereToObtain) + { + return DrawText.MarkupBoolDisplayer(boolList[i_whereToObtain], saveDrawnLines_forBoolCollections); + } + + public static string GetIntAsStringFromArray(int[] intArray, int i_whereToObtain) + { + return "" + intArray[i_whereToObtain]; + } + + public static string GetIntAsStringFromList(List intList, int i_whereToObtain) + { + return "" + intList[i_whereToObtain]; + } + + public static string GetFloatAsStringFromArray(float[] floatArray, int i_whereToObtain) + { + return "" + floatArray[i_whereToObtain]; + } + + public static string GetFloatAsStringFromList(List floatList, int i_whereToObtain) + { + return "" + floatList[i_whereToObtain]; + } + + public static string GetStringFromArray(string[] stringArray, int i_whereToObtain) + { + return stringArray[i_whereToObtain]; + } + + public static string GetStringFromList(List stringList, int i_whereToObtain) + { + return stringList[i_whereToObtain]; + } + + //Vector2: + public static string GetVector2XAsStringFromArray(Vector2[] vector2Array, int i_whereToObtain) + { + return "" + vector2Array[i_whereToObtain].x; + } + + public static string GetVector2XAsStringFromList(List vector2List, int i_whereToObtain) + { + return "" + vector2List[i_whereToObtain].x; + } + + public static string GetVector2YAsStringFromArray(Vector2[] vector2Array, int i_whereToObtain) + { + return "" + vector2Array[i_whereToObtain].y; + } + + public static string GetVector2YAsStringFromList(List vector2List, int i_whereToObtain) + { + return "" + vector2List[i_whereToObtain].y; + } + + //Vector3: + public static string GetVector3XAsStringFromArray(Vector3[] vector3Array, int i_whereToObtain) + { + return "" + vector3Array[i_whereToObtain].x; + } + + public static string GetVector3XAsStringFromList(List vector3List, int i_whereToObtain) + { + return "" + vector3List[i_whereToObtain].x; + } + + public static string GetVector3YAsStringFromArray(Vector3[] vector3Array, int i_whereToObtain) + { + return "" + vector3Array[i_whereToObtain].y; + } + + public static string GetVector3YAsStringFromList(List vector3List, int i_whereToObtain) + { + return "" + vector3List[i_whereToObtain].y; + } + + public static string GetVector3ZAsStringFromArray(Vector3[] vector3Array, int i_whereToObtain) + { + return "" + vector3Array[i_whereToObtain].z; + } + + public static string GetVector3ZAsStringFromList(List vector3List, int i_whereToObtain) + { + return "" + vector3List[i_whereToObtain].z; + } + + //Vector4: + public static string GetVector4XAsStringFromArray(Vector4[] vector4Array, int i_whereToObtain) + { + return "" + vector4Array[i_whereToObtain].x; + } + + public static string GetVector4XAsStringFromList(List vector4List, int i_whereToObtain) + { + return "" + vector4List[i_whereToObtain].x; + } + + public static string GetVector4YAsStringFromArray(Vector4[] vector4Array, int i_whereToObtain) + { + return "" + vector4Array[i_whereToObtain].y; + } + + public static string GetVector4YAsStringFromList(List vector4List, int i_whereToObtain) + { + return "" + vector4List[i_whereToObtain].y; + } + + public static string GetVector4ZAsStringFromArray(Vector4[] vector4Array, int i_whereToObtain) + { + return "" + vector4Array[i_whereToObtain].z; + } + + public static string GetVector4ZAsStringFromList(List vector4List, int i_whereToObtain) + { + return "" + vector4List[i_whereToObtain].z; + } + + public static string GetVector4WAsStringFromArray(Vector4[] vector4Array, int i_whereToObtain) + { + return "" + vector4Array[i_whereToObtain].w; + } + + public static string GetVector4WAsStringFromList(List vector4List, int i_whereToObtain) + { + return "" + vector4List[i_whereToObtain].w; + } + + public static void WriteCollection_in3D(CollectionType collectionToDraw, int countOfCollection, FlexibleGetColumnContentAtIndexAsString GetColumn1ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn2ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn3ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn4ContentAsString, string nameOfColumn1, string nameOfColumn2, string nameOfColumn3, string nameOfColumn4, Vector3 position, bool position_isTopLeft_notLowLeft, float forceHeightOfWholeTableBox, float textSize, Color color, Quaternion rotation, string title, string titleFallback, bool collectionRepresentsBools, float durationInSec, bool hiddenByNearerObjects) + { + bool autoFlipToPreventMirrorInverted = true; + WriteCollection(collectionToDraw, countOfCollection, GetColumn1ContentAsString, GetColumn2ContentAsString, GetColumn3ContentAsString, GetColumn4ContentAsString, nameOfColumn1, nameOfColumn2, nameOfColumn3, nameOfColumn4, position, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, autoFlipToPreventMirrorInverted, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteCollection_in2D(CollectionType collectionToDraw, int countOfCollection, FlexibleGetColumnContentAtIndexAsString GetColumn1ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn2ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn3ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn4ContentAsString, string nameOfColumn1, string nameOfColumn2, string nameOfColumn3, string nameOfColumn4, Vector2 position, bool position_isTopLeft_notLowLeft, float forceHeightOfWholeTableBox, float textSize, Color color, float custom_zPos, string title, string titleFallback, bool collectionRepresentsBools, float durationInSec, bool hiddenByNearerObjects) + { + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 positionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(position, zPos); + bool autoFlipToPreventMirrorInverted = true; + WriteCollection(collectionToDraw, countOfCollection, GetColumn1ContentAsString, GetColumn2ContentAsString, GetColumn3ContentAsString, GetColumn4ContentAsString, nameOfColumn1, nameOfColumn2, nameOfColumn3, nameOfColumn4, positionV3, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox, textSize, autoFlipToPreventMirrorInverted, color, Quaternion.identity, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + public static void WriteCollection_inScreenspace(Camera screenCamera, CollectionType collectionToDraw, int countOfCollection, FlexibleGetColumnContentAtIndexAsString GetColumn1ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn2ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn3ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn4ContentAsString, string nameOfColumn1, string nameOfColumn2, string nameOfColumn3, string nameOfColumn4, Vector2 position_in2DViewportSpace, bool position_isTopLeft_notLowLeft, float forceHeightOfWholeTableBox_relToViewportHeight, float textSize_relToViewportHeight, Color color, string title, string titleFallback, bool collectionRepresentsBools, float durationInSec) + { + Vector3 positionV3 = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(screenCamera, position_in2DViewportSpace, false); + float textSize_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(screenCamera, position_in2DViewportSpace, true, textSize_relToViewportHeight); + float forceHeightOfWholeTableBox_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(forceHeightOfWholeTableBox_relToViewportHeight) == false) + { + forceHeightOfWholeTableBox_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(screenCamera, position_in2DViewportSpace, true, forceHeightOfWholeTableBox_relToViewportHeight); + } + Quaternion rotation = screenCamera.transform.rotation; + bool autoFlipToPreventMirrorInverted = false; + bool hiddenByNearerObjects = false; + WriteCollection(collectionToDraw, countOfCollection, GetColumn1ContentAsString, GetColumn2ContentAsString, GetColumn3ContentAsString, GetColumn4ContentAsString, nameOfColumn1, nameOfColumn2, nameOfColumn3, nameOfColumn4, positionV3, position_isTopLeft_notLowLeft, forceHeightOfWholeTableBox_worldSpace, textSize_worldSpace, autoFlipToPreventMirrorInverted, color, rotation, title, titleFallback, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + } + + static void WriteCollection(CollectionType collectionToDraw, int countOfCollection, FlexibleGetColumnContentAtIndexAsString GetColumn1ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn2ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn3ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn4ContentAsString, string nameOfColumn1, string nameOfColumn2, string nameOfColumn3, string nameOfColumn4, Vector3 position, bool position_isTopLeft_notLowLeft, float forceHeightOfWholeTableBox, float textSize, bool autoFlipToPreventMirrorInverted, Color color, Quaternion rotation, string title, string titleFallback, bool collectionRepresentsBools, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(textSize, "textSize")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(forceHeightOfWholeTableBox, "forceHeightOfWholeTableBox")) { return; } + + saveDrawnLines_forBoolCollections = (countOfCollection > boolCollectionLength_aboveWhichDrawnLinesAreSaved); //-> has only effect on bool collection. Doesn't harm other collections. + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + Color color_ofBoundaryLines = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.5f); + Color color_ofLowerAlphaHorizLines = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.2f); + int numberOfAllLinesInclTitles = countOfCollection + 2; //"2" -> "title line" and "column titles line" + float factor_textSize_to_paddingSize = 1.15f; + bool heightOfWholeOutlineBox_isForced = (UtilitiesDXXL_Math.ApproximatelyZero(forceHeightOfWholeTableBox) == false); + float factor_letterWidth_to_lineHeight = 2.9f; //is similar to as "UtilitiesDXXL_Text.relLineDistance" + + float used_textSize; + if (heightOfWholeOutlineBox_isForced) + { + forceHeightOfWholeTableBox = Mathf.Abs(forceHeightOfWholeTableBox); + float linesThatNeedToFitInWholeOutline = (float)countOfCollection + 2.0f + (factor_textSize_to_paddingSize / factor_letterWidth_to_lineHeight); + used_textSize = forceHeightOfWholeTableBox / (linesThatNeedToFitInWholeOutline * factor_letterWidth_to_lineHeight); + } + else + { + used_textSize = Mathf.Max(textSize, 2.0f * UtilitiesDXXL_Text.minTextSize); + } + + float height_fromLineToLine = used_textSize * factor_letterWidth_to_lineHeight; + float paddingBetween_outlines_and_text = used_textSize * factor_textSize_to_paddingSize; + float heightOfWholeTableOutline; + + if (heightOfWholeOutlineBox_isForced) + { + heightOfWholeTableOutline = forceHeightOfWholeTableBox; + } + else + { + heightOfWholeTableOutline = height_fromLineToLine * numberOfAllLinesInclTitles + paddingBetween_outlines_and_text; //only one "paddingBetween_outlines_and_text" at the bottom. The top has no such padding because the text doesn't fill the whole vertical space of it's line. + } + + bool dirAndUp_areAlreadyGuaranteed_perpAndNormalized = UtilitiesDXXL_TextDirAndUpCalculation.ConvertQuaternionToTextDirAndUpVectors(out Vector3 textDir_candidate, out Vector3 textUp_candidate, rotation); + UtilitiesDXXL_TextDirAndUpCalculation.GetTextDirAndUpNormalized(out Vector3 rightward_ofCollection_normalized, out Vector3 upward_ofCollection_normalized, textDir_candidate, textUp_candidate, position, false, dirAndUp_areAlreadyGuaranteed_perpAndNormalized); + dirAndUp_areAlreadyGuaranteed_perpAndNormalized = true; + + Vector3 downward_ofCollection_normalized = -upward_ofCollection_normalized; + Vector3 vertVector_downwardFromLineToLine = height_fromLineToLine * downward_ofCollection_normalized; + Vector3 vertVector_downwardFromTextEndToHorizLines = 0.32f * height_fromLineToLine * downward_ofCollection_normalized; + Vector3 vertVector_offsetForHighlightedHorizLines = 0.02f * height_fromLineToLine * downward_ofCollection_normalized; + Vector3 vertVector_offsetForTitleText = 0.2f * height_fromLineToLine * upward_ofCollection_normalized; + + Vector3 topLeftCorner_ofWholeOutlineBox; + if (position_isTopLeft_notLowLeft) + { + topLeftCorner_ofWholeOutlineBox = position; + } + else + { + topLeftCorner_ofWholeOutlineBox = position + upward_ofCollection_normalized * heightOfWholeTableOutline; + } + + Vector3 lowLeftPos_ofTitleTextLine_alreadyIndentedFromBoundaryLine = topLeftCorner_ofWholeOutlineBox + rightward_ofCollection_normalized * paddingBetween_outlines_and_text + vertVector_downwardFromLineToLine + vertVector_offsetForTitleText; + string usedTitle = string.IsNullOrEmpty(title) ? titleFallback : title; + usedTitle = (countOfCollection == 0) ? usedTitle + " (with zero elements)" : usedTitle; + + UtilitiesDXXL_Text.Write(usedTitle, lowLeftPos_ofTitleTextLine_alreadyIndentedFromBoundaryLine, color, used_textSize, rightward_ofCollection_normalized, upward_ofCollection_normalized, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, false, false, dirAndUp_areAlreadyGuaranteed_perpAndNormalized); + float widthOfTitleTextInclPaddings = paddingBetween_outlines_and_text + DrawText.parsedTextSpecs.widthOfLongestLine + paddingBetween_outlines_and_text; + float widthOfAllColumnsInclPaddings = WriteColumns(collectionToDraw, countOfCollection, GetColumn1ContentAsString, GetColumn2ContentAsString, GetColumn3ContentAsString, GetColumn4ContentAsString, nameOfColumn1, nameOfColumn2, nameOfColumn3, nameOfColumn4, upward_ofCollection_normalized, rightward_ofCollection_normalized, vertVector_downwardFromTextEndToHorizLines, lowLeftPos_ofTitleTextLine_alreadyIndentedFromBoundaryLine, vertVector_downwardFromLineToLine, vertVector_offsetForTitleText, color, color_ofBoundaryLines, paddingBetween_outlines_and_text, used_textSize, autoFlipToPreventMirrorInverted, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + DrawBoxLines(countOfCollection, topLeftCorner_ofWholeOutlineBox, downward_ofCollection_normalized, rightward_ofCollection_normalized, vertVector_downwardFromLineToLine, vertVector_downwardFromTextEndToHorizLines, vertVector_offsetForHighlightedHorizLines, widthOfTitleTextInclPaddings, widthOfAllColumnsInclPaddings, heightOfWholeTableOutline, color_ofBoundaryLines, color_ofLowerAlphaHorizLines, durationInSec, hiddenByNearerObjects); + } + + static float WriteColumns(CollectionType collectionToDraw, int countOfCollection, FlexibleGetColumnContentAtIndexAsString GetColumn1ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn2ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn3ContentAsString, FlexibleGetColumnContentAtIndexAsString GetColumn4ContentAsString, string nameOfColumn1, string nameOfColumn2, string nameOfColumn3, string nameOfColumn4, Vector3 upward_ofCollection_normalized, Vector3 rightward_ofCollection_normalized, Vector3 vertVector_downwardFromTextEndToHorizLines, Vector3 lowLeftPos_ofTitleTextLine_alreadyIndentedFromBoundaryLine, Vector3 vertVector_downwardFromLineToLine, Vector3 vertVector_offsetForTitleText, Color color, Color color_ofBoundaryLines, float paddingBetween_outlines_and_text, float used_textSize, bool autoFlipToPreventMirrorInverted, bool collectionRepresentsBools, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine = lowLeftPos_ofTitleTextLine_alreadyIndentedFromBoundaryLine + vertVector_downwardFromLineToLine - vertVector_offsetForTitleText; + + float width_ofTextInIndexColumn = DrawIndexColumn(lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine, countOfCollection, vertVector_downwardFromLineToLine, upward_ofCollection_normalized, rightward_ofCollection_normalized, used_textSize, color, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0.0f; } + + float widthOfAllColumnsInclPaddings = paddingBetween_outlines_and_text + width_ofTextInIndexColumn + paddingBetween_outlines_and_text; + + lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine = lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine + (width_ofTextInIndexColumn + paddingBetween_outlines_and_text + paddingBetween_outlines_and_text) * rightward_ofCollection_normalized; + float width_ofTextInContentColumn1 = TryDrawContentColumn(lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine, collectionToDraw, countOfCollection, GetColumn1ContentAsString, nameOfColumn1, vertVector_downwardFromLineToLine, vertVector_downwardFromTextEndToHorizLines, upward_ofCollection_normalized, rightward_ofCollection_normalized, paddingBetween_outlines_and_text, used_textSize, color, autoFlipToPreventMirrorInverted, color_ofBoundaryLines, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0.0f; } + widthOfAllColumnsInclPaddings = widthOfAllColumnsInclPaddings + paddingBetween_outlines_and_text + width_ofTextInContentColumn1 + paddingBetween_outlines_and_text; + + if (GetColumn2ContentAsString != null) + { + lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine = lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine + (width_ofTextInContentColumn1 + paddingBetween_outlines_and_text + paddingBetween_outlines_and_text) * rightward_ofCollection_normalized; + float width_ofTextInContentColumn2 = TryDrawContentColumn(lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine, collectionToDraw, countOfCollection, GetColumn2ContentAsString, nameOfColumn2, vertVector_downwardFromLineToLine, vertVector_downwardFromTextEndToHorizLines, upward_ofCollection_normalized, rightward_ofCollection_normalized, paddingBetween_outlines_and_text, used_textSize, color, autoFlipToPreventMirrorInverted, color_ofBoundaryLines, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0.0f; } + widthOfAllColumnsInclPaddings = widthOfAllColumnsInclPaddings + paddingBetween_outlines_and_text + width_ofTextInContentColumn2 + paddingBetween_outlines_and_text; + + if (GetColumn3ContentAsString != null) + { + lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine = lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine + (width_ofTextInContentColumn2 + paddingBetween_outlines_and_text + paddingBetween_outlines_and_text) * rightward_ofCollection_normalized; + float width_ofTextInContentColumn3 = TryDrawContentColumn(lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine, collectionToDraw, countOfCollection, GetColumn3ContentAsString, nameOfColumn3, vertVector_downwardFromLineToLine, vertVector_downwardFromTextEndToHorizLines, upward_ofCollection_normalized, rightward_ofCollection_normalized, paddingBetween_outlines_and_text, used_textSize, color, autoFlipToPreventMirrorInverted, color_ofBoundaryLines, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0.0f; } + widthOfAllColumnsInclPaddings = widthOfAllColumnsInclPaddings + paddingBetween_outlines_and_text + width_ofTextInContentColumn3 + paddingBetween_outlines_and_text; + + if (GetColumn4ContentAsString != null) + { + lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine = lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine + (width_ofTextInContentColumn3 + paddingBetween_outlines_and_text + paddingBetween_outlines_and_text) * rightward_ofCollection_normalized; + float width_ofTextInContentColumn4 = TryDrawContentColumn(lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine, collectionToDraw, countOfCollection, GetColumn4ContentAsString, nameOfColumn4, vertVector_downwardFromLineToLine, vertVector_downwardFromTextEndToHorizLines, upward_ofCollection_normalized, rightward_ofCollection_normalized, paddingBetween_outlines_and_text, used_textSize, color, autoFlipToPreventMirrorInverted, color_ofBoundaryLines, collectionRepresentsBools, durationInSec, hiddenByNearerObjects); + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0.0f; } + widthOfAllColumnsInclPaddings = widthOfAllColumnsInclPaddings + paddingBetween_outlines_and_text + width_ofTextInContentColumn4 + paddingBetween_outlines_and_text; + } + } + } + return widthOfAllColumnsInclPaddings; + } + + static float DrawIndexColumn(Vector3 lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine, int countOfCollection, Vector3 vertVector_downwardFromLineToLine, Vector3 upward_ofCollection_normalized, Vector3 rightward_ofCollection_normalized, float used_textSize, Color color, bool autoFlipToPreventMirrorInverted, float durationInSec, bool hiddenByNearerObjects) + { + float width_ofWidestTextInWholeColumn = 0.0f; + UtilitiesDXXL_Text.Write("i", lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine, color, used_textSize, rightward_ofCollection_normalized, upward_ofCollection_normalized, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, false, false, true); + width_ofWidestTextInWholeColumn = Mathf.Max(width_ofWidestTextInWholeColumn, DrawText.parsedTextSpecs.widthOfLongestLine); + + Vector3 lowLeftPos_ofCurrentLinesTextLine = lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine; + for (int i = 0; i < countOfCollection; i++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return width_ofWidestTextInWholeColumn; } + lowLeftPos_ofCurrentLinesTextLine = lowLeftPos_ofCurrentLinesTextLine + vertVector_downwardFromLineToLine; + UtilitiesDXXL_Text.Write("" + i, lowLeftPos_ofCurrentLinesTextLine, color, used_textSize, rightward_ofCollection_normalized, upward_ofCollection_normalized, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, false, false, true); + width_ofWidestTextInWholeColumn = Mathf.Max(width_ofWidestTextInWholeColumn, DrawText.parsedTextSpecs.widthOfLongestLine); + } + + return width_ofWidestTextInWholeColumn; + } + + static float TryDrawContentColumn(Vector3 lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine, CollectionType collectionToDraw, int countOfCollection, FlexibleGetColumnContentAtIndexAsString GetContentOfColumnAtIndex, string nameOfColumn, Vector3 vertVector_downwardFromLineToLine, Vector3 vertVector_downwardFromTextEndToHorizLines, Vector3 upward_ofCollection_normalized, Vector3 rightward_ofCollection_normalized, float paddingBetween_outlines_and_text, float used_textSize, Color color, bool autoFlipToPreventMirrorInverted, Color color_ofBoundaryLines, bool collectionRepresentsBools, float durationInSec, bool hiddenByNearerObjects) + { + float width_ofWidestTextInWholeColumn = 0.0f; + UtilitiesDXXL_Text.Write(nameOfColumn, lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine, color, used_textSize, rightward_ofCollection_normalized, upward_ofCollection_normalized, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, false, false, true); + width_ofWidestTextInWholeColumn = Mathf.Max(width_ofWidestTextInWholeColumn, DrawText.parsedTextSpecs.widthOfLongestLine); + + Vector3 vertShiftOffsetFor_sizeAmplifiedBools = collectionRepresentsBools ? (0.175f * vertVector_downwardFromLineToLine) : Vector3.zero; + Vector3 lowLeftPos_ofCurrentLinesTextLine = lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine + vertShiftOffsetFor_sizeAmplifiedBools; + float used_textSize_inclSizeAmplificationOfBools = collectionRepresentsBools ? (2.0f * used_textSize) : used_textSize; + for (int i = 0; i < countOfCollection; i++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return width_ofWidestTextInWholeColumn; } + lowLeftPos_ofCurrentLinesTextLine = lowLeftPos_ofCurrentLinesTextLine + vertVector_downwardFromLineToLine; + + string collectionSlotContentAsString = GetContentOfColumnAtIndex(collectionToDraw, i); + if (collectionSlotContentAsString == null) { collectionSlotContentAsString = "null"; } + + UtilitiesDXXL_Text.Write(collectionSlotContentAsString, lowLeftPos_ofCurrentLinesTextLine, color, used_textSize_inclSizeAmplificationOfBools, rightward_ofCollection_normalized, upward_ofCollection_normalized, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, false, false, true); + width_ofWidestTextInWholeColumn = Mathf.Max(width_ofWidestTextInWholeColumn, DrawText.parsedTextSpecs.widthOfLongestLine); + } + + Vector3 lowerEndOfText_atVertColumnBorderLineAtLeftSide = lowLeftPos_ofCurrentColumnsTitleTextLine_alreadyIndentedFromBoundaryLine - rightward_ofCollection_normalized * paddingBetween_outlines_and_text - vertVector_downwardFromLineToLine; + Vector3 upperEnd_ofVertColumnBorderLineAtLeftSide = lowerEndOfText_atVertColumnBorderLineAtLeftSide + vertVector_downwardFromTextEndToHorizLines; + Vector3 lowerEnd_ofVertColumnBorderLineAtLeftSide = lowerEndOfText_atVertColumnBorderLineAtLeftSide + vertVector_downwardFromLineToLine * (1 + countOfCollection) - upward_ofCollection_normalized * paddingBetween_outlines_and_text; + Line_fadeableAnimSpeed.InternalDraw(upperEnd_ofVertColumnBorderLineAtLeftSide, lowerEnd_ofVertColumnBorderLineAtLeftSide, color_ofBoundaryLines, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + return width_ofWidestTextInWholeColumn; + } + + static void DrawBoxLines(int countOfCollection, Vector3 topLeftCorner_ofWholeOutlineBox, Vector3 downward_ofCollection_normalized, Vector3 rightward_ofCollection_normalized, Vector3 vertVector_downwardFromLineToLine, Vector3 vertVector_downwardFromTextEndToHorizLines, Vector3 vertVector_offsetForHighlightedHorizLines, float widthOfTitleTextInclPaddings, float widthOfAllColumnsInclPaddings, float heightOfWholeTableOutline, Color color_ofBoundaryLines, Color color_ofLowerAlphaHorizLines, float durationInSec, bool hiddenByNearerObjects) + { + float width_fromLeftWholeTableOutline_toRightWholeTableOutline = Mathf.Max(widthOfTitleTextInclPaddings, widthOfAllColumnsInclPaddings); + Vector3 downwardEdge_ofWholeTableOutLine = downward_ofCollection_normalized * heightOfWholeTableOutline; + Vector3 rightwardEdge_ofWholeTableOutLine = rightward_ofCollection_normalized * width_fromLeftWholeTableOutline_toRightWholeTableOutline; + Vector3 lowLeftCorner_ofWholeOutlineBox = topLeftCorner_ofWholeOutlineBox + downwardEdge_ofWholeTableOutLine; + Vector3 topRightCorner_ofWholeOutlineBox = topLeftCorner_ofWholeOutlineBox + rightwardEdge_ofWholeTableOutLine; + Vector3 lowRightCorner_ofWholeOutlineBox = topRightCorner_ofWholeOutlineBox + downwardEdge_ofWholeTableOutLine; + Line_fadeableAnimSpeed.InternalDraw(topLeftCorner_ofWholeOutlineBox, lowLeftCorner_ofWholeOutlineBox, color_ofBoundaryLines, 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(lowLeftCorner_ofWholeOutlineBox, lowRightCorner_ofWholeOutlineBox, color_ofBoundaryLines, 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(lowRightCorner_ofWholeOutlineBox, topRightCorner_ofWholeOutlineBox, color_ofBoundaryLines, 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(topRightCorner_ofWholeOutlineBox, topLeftCorner_ofWholeOutlineBox, color_ofBoundaryLines, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + for (int i = 1; i < countOfCollection + 2; i++) + { + Vector3 vertOffsetVector_fromTopEndOfWholeOutlineBox = vertVector_downwardFromLineToLine * i + vertVector_downwardFromTextEndToHorizLines; + Vector3 leftEndOfHorizLine = topLeftCorner_ofWholeOutlineBox + vertOffsetVector_fromTopEndOfWholeOutlineBox; + Vector3 rightEndOfHorizLine = topRightCorner_ofWholeOutlineBox + vertOffsetVector_fromTopEndOfWholeOutlineBox; + + Color used_color = (i >= 3) ? color_ofLowerAlphaHorizLines : color_ofBoundaryLines; + Line_fadeableAnimSpeed.InternalDraw(leftEndOfHorizLine, rightEndOfHorizLine, used_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); + + if (i < 3) + { + Line_fadeableAnimSpeed.InternalDraw(leftEndOfHorizLine + vertVector_offsetForHighlightedHorizLines, rightEndOfHorizLine + vertVector_offsetForHighlightedHorizLines, used_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); + } + } + } + + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawCollections.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawCollections.cs.meta new file mode 100644 index 0000000..8b5bab4 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_DrawCollections.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87f2190109ae5c349a83182b408d7904 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_EngineBasics.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_EngineBasics.cs new file mode 100644 index 0000000..5a3e8fc --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_EngineBasics.cs @@ -0,0 +1,1659 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_EngineBasics + { + + public static void VectorFrom_local(Vector3 origin_ofLocalSpace_inGlobalSpace, Vector3 scale_ofLocalSpace, Quaternion rotation_ofLocalSpace, Vector3 vectorStartPos, Vector3 vector, Color color, float lineWidth, string text, float durationInSec, bool hiddenByNearerObjects, bool isLocal) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth, "lineWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vectorStartPos, "vectorStartPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector, "vector")) { return; } + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + Color colorOfBoxLines = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(Color.white, 0.2f); + + Vector3 vector_inLocalSpace = vector; + Vector3 vectorStartPos_inLocalSpace = vectorStartPos; + Vector3 vectorEndPos_inLocalSpace = vectorStartPos_inLocalSpace + vector_inLocalSpace; + + Vector3 vectorStartPos_inGlobalSpace = origin_ofLocalSpace_inGlobalSpace + rotation_ofLocalSpace * Vector3.Scale(scale_ofLocalSpace, vectorStartPos_inLocalSpace); + Vector3 vectorEndPos_inGlobalSpace = origin_ofLocalSpace_inGlobalSpace + rotation_ofLocalSpace * Vector3.Scale(scale_ofLocalSpace, vectorEndPos_inLocalSpace); + Vector3 vector_inGlobalSpace = vectorEndPos_inGlobalSpace - vectorStartPos_inGlobalSpace; + + Vector3 localVectorsXComponentAsVector_inLocalSpace = new Vector3(vector_inLocalSpace.x, 0.0f, 0.0f); + Vector3 localVectorsYComponentAsVector_inLocalSpace = new Vector3(0.0f, vector_inLocalSpace.y, 0.0f); + Vector3 localVectorsZComponentAsVector_inLocalSpace = new Vector3(0.0f, 0.0f, vector_inLocalSpace.z); + + Vector3 localVectorsLocalXComponentAsVector_inGlobalSpace = rotation_ofLocalSpace * Vector3.Scale(scale_ofLocalSpace, localVectorsXComponentAsVector_inLocalSpace); + Vector3 localVectorsLocalYComponentAsVector_inGlobalSpace = rotation_ofLocalSpace * Vector3.Scale(scale_ofLocalSpace, localVectorsYComponentAsVector_inLocalSpace); + Vector3 localVectorsLocalZComponentAsVector_inGlobalSpace = rotation_ofLocalSpace * Vector3.Scale(scale_ofLocalSpace, localVectorsZComponentAsVector_inLocalSpace); + + Vector3 endPos_ofXDirComponentFromVectorStart_inGlobalSpace = vectorStartPos_inGlobalSpace + localVectorsLocalXComponentAsVector_inGlobalSpace; + Vector3 endPos_ofYDirComponentFromVectorStart_inGlobalSpace = vectorStartPos_inGlobalSpace + localVectorsLocalYComponentAsVector_inGlobalSpace; + Vector3 endPos_ofZDirComponentFromVectorStart_inGlobalSpace = vectorStartPos_inGlobalSpace + localVectorsLocalZComponentAsVector_inGlobalSpace; + + //grey box lines: + Line_fadeableAnimSpeed.InternalDraw(vectorStartPos_inGlobalSpace, endPos_ofXDirComponentFromVectorStart_inGlobalSpace, colorOfBoxLines, 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(vectorStartPos_inGlobalSpace, endPos_ofYDirComponentFromVectorStart_inGlobalSpace, colorOfBoxLines, 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(vectorStartPos_inGlobalSpace, endPos_ofZDirComponentFromVectorStart_inGlobalSpace, colorOfBoxLines, 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(endPos_ofXDirComponentFromVectorStart_inGlobalSpace, endPos_ofXDirComponentFromVectorStart_inGlobalSpace + localVectorsLocalYComponentAsVector_inGlobalSpace, colorOfBoxLines, 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(endPos_ofXDirComponentFromVectorStart_inGlobalSpace, endPos_ofXDirComponentFromVectorStart_inGlobalSpace + localVectorsLocalZComponentAsVector_inGlobalSpace, colorOfBoxLines, 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(endPos_ofYDirComponentFromVectorStart_inGlobalSpace, endPos_ofYDirComponentFromVectorStart_inGlobalSpace + localVectorsLocalXComponentAsVector_inGlobalSpace, colorOfBoxLines, 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(endPos_ofYDirComponentFromVectorStart_inGlobalSpace, endPos_ofYDirComponentFromVectorStart_inGlobalSpace + localVectorsLocalZComponentAsVector_inGlobalSpace, colorOfBoxLines, 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(endPos_ofZDirComponentFromVectorStart_inGlobalSpace, endPos_ofZDirComponentFromVectorStart_inGlobalSpace + localVectorsLocalXComponentAsVector_inGlobalSpace, colorOfBoxLines, 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(endPos_ofZDirComponentFromVectorStart_inGlobalSpace, endPos_ofZDirComponentFromVectorStart_inGlobalSpace + localVectorsLocalYComponentAsVector_inGlobalSpace, colorOfBoxLines, 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(vectorEndPos_inGlobalSpace, vectorEndPos_inGlobalSpace - localVectorsLocalXComponentAsVector_inGlobalSpace, colorOfBoxLines, 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(vectorEndPos_inGlobalSpace, vectorEndPos_inGlobalSpace - localVectorsLocalYComponentAsVector_inGlobalSpace, colorOfBoxLines, 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(vectorEndPos_inGlobalSpace, vectorEndPos_inGlobalSpace - localVectorsLocalZComponentAsVector_inGlobalSpace, colorOfBoxLines, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //three component vectors: + Vector3 absLocalVector_scaledToGlobalUnits_butNotYetRotatedToGlobalSpace = UtilitiesDXXL_Math.Abs(Vector3.Scale(scale_ofLocalSpace, vector_inLocalSpace)); + float biggestAbsComponent_inGlobalSpace = UtilitiesDXXL_Math.GetBiggestAbsComponent(vector_inGlobalSpace); + float componentVectorsConeLength = 0.03f * biggestAbsComponent_inGlobalSpace; + float minTextSize_ofNonZeroComponents = Mathf.Max(biggestAbsComponent_inGlobalSpace * 0.02f, 0.02f); + float textSize_ifComponentIsZero = Mathf.Max(biggestAbsComponent_inGlobalSpace * 0.05f, 0.02f); + + string text_ofXComponent = isLocal ? ("localx = " + vector_inLocalSpace.x) : ("x = " + vector_inLocalSpace.x); + if (absLocalVector_scaledToGlobalUnits_butNotYetRotatedToGlobalSpace.x < 0.0001f) + { + float textSize = (vector_inLocalSpace.x == 0.0f) ? textSize_ifComponentIsZero : minTextSize_ofNonZeroComponents; //"==" instead of "ApproxZero"-Check is intentional + UtilitiesDXXL_Text.Write(text_ofXComponent, vectorStartPos_inGlobalSpace, UtilitiesDXXL_Colors.red_xAxis, textSize, rotation_ofLocalSpace * Vector3.right, rotation_ofLocalSpace * Vector3.up, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + else + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.Vector(vectorStartPos_inGlobalSpace, endPos_ofXDirComponentFromVectorStart_inGlobalSpace, UtilitiesDXXL_Colors.red_xAxis, 0.0f, text_ofXComponent, componentVectorsConeLength, false, false, default(Vector3), false, minTextSize_ofNonZeroComponents, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + Vector3 startPosOfFinalZSegment_inGlobalSpace = endPos_ofXDirComponentFromVectorStart_inGlobalSpace + localVectorsLocalYComponentAsVector_inGlobalSpace; + string text_ofYComponent = isLocal ? ("localy = " + vector_inLocalSpace.y) : ("y = " + vector_inLocalSpace.y); + if (absLocalVector_scaledToGlobalUnits_butNotYetRotatedToGlobalSpace.y < 0.0001f) + { + float textSize = (vector_inLocalSpace.y == 0.0f) ? textSize_ifComponentIsZero : minTextSize_ofNonZeroComponents; //"==" instead of "ApproxZero"-Check is intentional + UtilitiesDXXL_Text.Write(text_ofYComponent, endPos_ofXDirComponentFromVectorStart_inGlobalSpace, UtilitiesDXXL_Colors.green_yAxis, textSize, rotation_ofLocalSpace * Vector3.up, rotation_ofLocalSpace * Vector3.left, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + else + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.Vector(endPos_ofXDirComponentFromVectorStart_inGlobalSpace, startPosOfFinalZSegment_inGlobalSpace, UtilitiesDXXL_Colors.green_yAxis, 0.0f, text_ofYComponent, componentVectorsConeLength, false, false, default(Vector3), false, minTextSize_ofNonZeroComponents, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + string text_ofZComponent = isLocal ? ("localz = " + vector_inLocalSpace.z) : ("z = " + vector_inLocalSpace.z); + if (absLocalVector_scaledToGlobalUnits_butNotYetRotatedToGlobalSpace.z < 0.0001f) + { + float textSize = (vector_inLocalSpace.z == 0.0f) ? textSize_ifComponentIsZero : minTextSize_ofNonZeroComponents; //"==" instead of "ApproxZero"-Check is intentional + UtilitiesDXXL_Text.Write(text_ofZComponent, startPosOfFinalZSegment_inGlobalSpace, UtilitiesDXXL_Colors.blue_zAxis, textSize, rotation_ofLocalSpace * Vector3.forward, rotation_ofLocalSpace * Vector3.up, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + else + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.Vector(startPosOfFinalZSegment_inGlobalSpace, vectorEndPos_inGlobalSpace, UtilitiesDXXL_Colors.blue_zAxis, 0.0f, text_ofZComponent, componentVectorsConeLength, false, false, default(Vector3), false, minTextSize_ofNonZeroComponents, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + //main vector: + float lineWidth_inGlobalSpace = lineWidth; + lineWidth_inGlobalSpace = Mathf.Max(lineWidth_inGlobalSpace, 0.005f); + float length_inGlobalSpace = vector_inGlobalSpace.magnitude; + float length_inLocalSpace = vector_inLocalSpace.magnitude; + lineWidth_inGlobalSpace = Mathf.Min(lineWidth_inGlobalSpace, 0.2f * length_inGlobalSpace); + bool addNormalizedMarkingText = !isLocal; + string mainVectorText = isLocal ? ("locallength = " + length_inLocalSpace + "

" + text) : ("length = " + length_inLocalSpace + "

" + text); + + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.Vector(vectorStartPos_inGlobalSpace, vectorEndPos_inGlobalSpace, color, lineWidth_inGlobalSpace, mainVectorText, 0.17f, false, false, default(Vector3), addNormalizedMarkingText, 0.01f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + public static void LocalScale(Vector3 localPosition, Vector3 localScale, Transform parentTransform, Quaternion localRotation, float lineWidth, string text, bool drawXDim, bool drawYDim, bool drawZDim, float relSizeOfPlanes, Color overwriteColor, float durationInSec, bool hiddenByNearerObjects, bool isGlobalNotLocalScale) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth, "lineWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(relSizeOfPlanes, "relSizeOfPlanes")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(localPosition, "localPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(localScale, "localScale")) { return; } + + Color color_forX = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor, UtilitiesDXXL_Colors.red_xAxis); + Color color_forY = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor, UtilitiesDXXL_Colors.green_yAxis); + Color color_forZ = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor, UtilitiesDXXL_Colors.blue_zAxis); + + bool noParent = parentTransform == null; + bool noLocalRotation = UtilitiesDXXL_Math.IsDefaultInvalidQuaternion(localRotation) || UtilitiesDXXL_Math.IsQuaternionIdentity(localRotation); + Vector3 worldPosition = noParent ? localPosition : parentTransform.TransformPoint(localPosition); + Vector3 lossyScale = noParent ? localScale : Vector3.Scale(localScale, parentTransform.lossyScale); + + Vector3 rightOfChildTransform_insideHisLocalSpace_normalized = noLocalRotation ? Vector3.right : localRotation * Vector3.right; + Vector3 upOfChildTransform_insideHisLocalSpace_normalized = noLocalRotation ? Vector3.up : localRotation * Vector3.up; + Vector3 forwardOfChildTransform_insideHisLocalSpace_normalized = noLocalRotation ? Vector3.forward : localRotation * Vector3.forward; + + Vector3 localRight_expressedInWorldSpaceUnits_normalized = noParent ? rightOfChildTransform_insideHisLocalSpace_normalized : parentTransform.rotation * rightOfChildTransform_insideHisLocalSpace_normalized; + Vector3 localUp_expressedInWorldSpaceUnits_normalized = noParent ? upOfChildTransform_insideHisLocalSpace_normalized : parentTransform.rotation * upOfChildTransform_insideHisLocalSpace_normalized; + Vector3 localForward_expressedInWorldSpaceUnits_normalized = noParent ? forwardOfChildTransform_insideHisLocalSpace_normalized : parentTransform.rotation * forwardOfChildTransform_insideHisLocalSpace_normalized; + + Vector3 absLossyScale = UtilitiesDXXL_Math.Abs(lossyScale); + Vector3 halfAbsLossyScale = 0.5f * lossyScale; + + Vector3 x_negativeEnd_worldSpace = worldPosition - localRight_expressedInWorldSpaceUnits_normalized * halfAbsLossyScale.x; + Vector3 x_positiveEnd_worldSpace = worldPosition + localRight_expressedInWorldSpaceUnits_normalized * halfAbsLossyScale.x; + + float vectorLenghtThreshold_belowWhichToUseRelConeLengths = 0.45f; + + if (drawXDim) + { + if (absLossyScale.x > 0.002f) + { + bool setConeLengthToRelative_notToAbsolute = (absLossyScale.x < vectorLenghtThreshold_belowWhichToUseRelConeLengths); + float coneLength_ifSetToRelative = 0.1f / vectorLenghtThreshold_belowWhichToUseRelConeLengths; + float coneLength_ifSetToAbsolute = 0.1f; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + DrawBasics.Vector(x_negativeEnd_worldSpace, x_positiveEnd_worldSpace, color_forX, lineWidth, isGlobalNotLocalScale ? "x = " + localScale.x : "localx = " + localScale.x, coneLength, true, false, default(Vector3), false, 0.005f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + else + { + UtilitiesDXXL_Text.Write(isGlobalNotLocalScale ? "x = " + localScale.x : "localx = " + localScale.x, worldPosition, color_forX, 0.01f, localRight_expressedInWorldSpaceUnits_normalized, localUp_expressedInWorldSpaceUnits_normalized, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + + Vector3 y_negativeEnd_worldSpace = worldPosition - localUp_expressedInWorldSpaceUnits_normalized * halfAbsLossyScale.y; + Vector3 y_positiveEnd_worldSpace = worldPosition + localUp_expressedInWorldSpaceUnits_normalized * halfAbsLossyScale.y; + if (drawYDim) + { + if (absLossyScale.y > 0.002f) + { + bool setConeLengthToRelative_notToAbsolute = (absLossyScale.y < vectorLenghtThreshold_belowWhichToUseRelConeLengths); + float coneLength_ifSetToRelative = 0.1f / vectorLenghtThreshold_belowWhichToUseRelConeLengths; + float coneLength_ifSetToAbsolute = 0.1f; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + DrawBasics.Vector(y_negativeEnd_worldSpace, y_positiveEnd_worldSpace, color_forY, lineWidth, isGlobalNotLocalScale ? "y = " + localScale.y : "localy = " + localScale.y, coneLength, true, false, default(Vector3), false, 0.005f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + else + { + UtilitiesDXXL_Text.Write(isGlobalNotLocalScale ? "y = " + localScale.y : "localy = " + localScale.y, worldPosition, color_forY, 0.01f, localUp_expressedInWorldSpaceUnits_normalized, -localRight_expressedInWorldSpaceUnits_normalized, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + + Vector3 z_negativeEnd_worldSpace = worldPosition - localForward_expressedInWorldSpaceUnits_normalized * halfAbsLossyScale.z; + Vector3 z_positiveEnd_worldSpace = worldPosition + localForward_expressedInWorldSpaceUnits_normalized * halfAbsLossyScale.z; + if (drawZDim) + { + if (absLossyScale.z > 0.002f) + { + bool setConeLengthToRelative_notToAbsolute = (absLossyScale.z < vectorLenghtThreshold_belowWhichToUseRelConeLengths); + float coneLength_ifSetToRelative = 0.1f / vectorLenghtThreshold_belowWhichToUseRelConeLengths; + float coneLength_ifSetToAbsolute = 0.1f; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + DrawBasics.Vector(z_negativeEnd_worldSpace, z_positiveEnd_worldSpace, color_forZ, lineWidth, isGlobalNotLocalScale ? "z = " + localScale.z : "localz = " + localScale.z, coneLength, true, false, default(Vector3), false, 0.005f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + else + { + UtilitiesDXXL_Text.Write(isGlobalNotLocalScale ? "z = " + localScale.z : "localz = " + localScale.z, worldPosition, color_forZ, 0.01f, localForward_expressedInWorldSpaceUnits_normalized, localUp_expressedInWorldSpaceUnits_normalized, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + + relSizeOfPlanes = Mathf.Abs(relSizeOfPlanes); + bool drawPlanes = (relSizeOfPlanes > 0.01f); + if (drawPlanes) + { + relSizeOfPlanes = Mathf.Min(relSizeOfPlanes, 1.0f); + Vector3 planesScale_worldSpace = relSizeOfPlanes * lossyScale; + + if (drawXDim) + { + if (absLossyScale.y > 0.002 || absLossyScale.z > 0.002) + { + DrawShapes.Plane(x_negativeEnd_worldSpace, localRight_expressedInWorldSpaceUnits_normalized, default(Vector3), color_forX, planesScale_worldSpace.z, planesScale_worldSpace.y, localUp_expressedInWorldSpaceUnits_normalized, 0.0f, null, 6, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Plane(x_positiveEnd_worldSpace, localRight_expressedInWorldSpaceUnits_normalized, default(Vector3), color_forX, planesScale_worldSpace.z, planesScale_worldSpace.y, localUp_expressedInWorldSpaceUnits_normalized, 0.0f, null, 6, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + } + + if (drawYDim) + { + if (absLossyScale.x > 0.002 || absLossyScale.z > 0.002) + { + DrawShapes.Plane(y_negativeEnd_worldSpace, localUp_expressedInWorldSpaceUnits_normalized, default(Vector3), color_forY, planesScale_worldSpace.x, planesScale_worldSpace.z, localForward_expressedInWorldSpaceUnits_normalized, 0.0f, null, 6, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Plane(y_positiveEnd_worldSpace, localUp_expressedInWorldSpaceUnits_normalized, default(Vector3), color_forY, planesScale_worldSpace.x, planesScale_worldSpace.z, localForward_expressedInWorldSpaceUnits_normalized, 0.0f, null, 6, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + } + + if (drawZDim) + { + if (absLossyScale.x > 0.002 || absLossyScale.y > 0.002) + { + DrawShapes.Plane(z_negativeEnd_worldSpace, localForward_expressedInWorldSpaceUnits_normalized, default(Vector3), color_forZ, planesScale_worldSpace.x, planesScale_worldSpace.y, localUp_expressedInWorldSpaceUnits_normalized, 0.0f, null, 6, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Plane(z_positiveEnd_worldSpace, localForward_expressedInWorldSpaceUnits_normalized, default(Vector3), color_forZ, planesScale_worldSpace.x, planesScale_worldSpace.y, localUp_expressedInWorldSpaceUnits_normalized, 0.0f, null, 6, false, 0.0f, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + } + } + + if (drawXDim == false && drawYDim == false && drawZDim == false) + { + if (isGlobalNotLocalScale) + { + text = "[ Scale with all dimensions deactivated]
" + text; + } + else + { + text = "[ LocalScale with all dimensions deactivated]
" + text; + } + } + + if (CheckIf_transformOrAParentHasNonUniformScale(parentTransform)) + { + text = "[ LocalScale: Transform has a parent with non-uniform scale
-> possibly weird results]
" + text; + } + + if (text != null && text != "") + { + Vector3 textPos = worldPosition + localRight_expressedInWorldSpaceUnits_normalized * halfAbsLossyScale.x + localUp_expressedInWorldSpaceUnits_normalized * halfAbsLossyScale.y - localForward_expressedInWorldSpaceUnits_normalized * halfAbsLossyScale.z; + Vector3 textOffsetDir = textPos - worldPosition; + DrawBasics.PointTag(worldPosition, text, Color.Lerp(color_forX, Color.white, 0.5f), 0.3f * lineWidth, textOffsetDir.magnitude, textOffsetDir, 1.0f, true, durationInSec, hiddenByNearerObjects); + } + } + + public static bool CheckIf_transformOrAParentHasNonUniformScale(Transform transformToCheck) + { + if (transformToCheck != null) + { + if (UtilitiesDXXL_Math.IsVectorApproxUniform(transformToCheck.localScale) == false) + { + return true; + } + else + { + Transform[] transformsOfParents = transformToCheck.GetComponentsInParent(true); + if (transformsOfParents != null) + { + for (int i = 0; i < transformsOfParents.Length; i++) + { + if (transformsOfParents[i] != null) + { + if (UtilitiesDXXL_Math.IsVectorApproxUniform(transformsOfParents[i].localScale) == false) + { + return true; + } + } + } + } + } + } + return false; + } + + public static bool CheckIf_transformOrAParentHasNonUniformScale_2D(Transform transformToCheck) + { + if (transformToCheck != null) + { + Vector2 parentLocalScale_withoutZ = new Vector2(transformToCheck.localScale.x, transformToCheck.localScale.y); + if (UtilitiesDXXL_Math.IsVectorApproxUniform(parentLocalScale_withoutZ) == false) + { + return true; + } + else + { + Transform[] transformsOfParents = transformToCheck.GetComponentsInParent(true); + if (transformsOfParents != null) + { + for (int i = 0; i < transformsOfParents.Length; i++) + { + if (transformsOfParents[i] != null) + { + Vector2 currParentLocalScale_withoutZ = new Vector2(transformsOfParents[i].localScale.x, transformsOfParents[i].localScale.y); + if (UtilitiesDXXL_Math.IsVectorApproxUniform(currParentLocalScale_withoutZ) == false) + { + return true; + } + } + } + } + } + } + return false; + } + + public static bool CheckIfThisOrAParentHasANonZRotation_2D(Transform thisTransform) + { + if (thisTransform != null) + { + Vector3 localEulerAngles_ofThisTransform = thisTransform.localRotation.eulerAngles; + if (CheckIfAnEulerAngleSetContainsANonZRotation(localEulerAngles_ofThisTransform)) + { + return true; + } + else + { + if (thisTransform.parent != null) + { + Transform[] transformsOfParents = thisTransform.parent.GetComponentsInParent(true); + if (transformsOfParents != null) + { + for (int i = 0; i < transformsOfParents.Length; i++) + { + if (transformsOfParents[i] != null) + { + Vector3 localEulerAngles_ofCurrParentTransform = transformsOfParents[i].localRotation.eulerAngles; + if (CheckIfAnEulerAngleSetContainsANonZRotation(localEulerAngles_ofCurrParentTransform)) + { + return true; + } + } + } + } + } + } + } + return false; + } + + static bool CheckIfAnEulerAngleSetContainsANonZRotation(Vector3 eulerAngles_toCheck) + { + if (CheckIfAnEulerAngleMeansApproxNoRotation(eulerAngles_toCheck.x) == false) + { + return true; + } + if (CheckIfAnEulerAngleMeansApproxNoRotation(eulerAngles_toCheck.y) == false) + { + return true; + } + return false; + } + + static bool CheckIfAnEulerAngleMeansApproxNoRotation(float eulerAngle_toCheck) + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(0.0f, eulerAngle_toCheck, 0.001f)) + { + return true; + } + else + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(360.0f, eulerAngle_toCheck, 0.001f)) + { + return true; + } + else + { + if (UtilitiesDXXL_Math.CheckIfValueLiesInsideDistanceNearAnotherValue(-360.0f, eulerAngle_toCheck, 0.001f)) + { + return true; + } + } + } + return false; + } + + static Color colorOfVector1_forDotProduct_before; + public static void Set_colorOfVector1_forDotProduct_reversible(Color new_colorOfVector1_forDotProduct) + { + colorOfVector1_forDotProduct_before = DrawEngineBasics.colorOfVector1_forDotProduct; + DrawEngineBasics.colorOfVector1_forDotProduct = new_colorOfVector1_forDotProduct; + } + public static void Reverse_colorOfVector1_forDotProduct() + { + DrawEngineBasics.colorOfVector1_forDotProduct = colorOfVector1_forDotProduct_before; + } + + static Color colorOfVector2_forDotProduct_before; + public static void Set_colorOfVector2_forDotProduct_reversible(Color new_colorOfVector2_forDotProduct) + { + colorOfVector2_forDotProduct_before = DrawEngineBasics.colorOfVector2_forDotProduct; + DrawEngineBasics.colorOfVector2_forDotProduct = new_colorOfVector2_forDotProduct; + } + public static void Reverse_colorOfVector2_forDotProduct() + { + DrawEngineBasics.colorOfVector2_forDotProduct = colorOfVector2_forDotProduct_before; + } + + static Color colorOfAngle_forDotProduct_before; + public static void Set_colorOfAngle_forDotProduct_reversible(Color new_colorOfAngle_forDotProduct) + { + colorOfAngle_forDotProduct_before = DrawEngineBasics.colorOfAngle_forDotProduct; + DrawEngineBasics.colorOfAngle_forDotProduct = new_colorOfAngle_forDotProduct; + } + public static void Reverse_colorOfAngle_forDotProduct() + { + DrawEngineBasics.colorOfAngle_forDotProduct = colorOfAngle_forDotProduct_before; + } + + static Color colorOfResult_forDotProduct_before; + public static void Set_colorOfResult_forDotProduct_reversible(Color new_colorOfResult_forDotProduct) + { + colorOfResult_forDotProduct_before = DrawEngineBasics.colorOfResult_forDotProduct; + DrawEngineBasics.colorOfResult_forDotProduct = new_colorOfResult_forDotProduct; + } + public static void Reverse_colorOfResult_forDotProduct() + { + DrawEngineBasics.colorOfResult_forDotProduct = colorOfResult_forDotProduct_before; + } + + //static float minTextSize_atVectorFrom_dotAndCrossProduct = 0.04f; //-> bigger text size: better readable, but interfering with vectorCone + static float minTextSize_atVectorFrom_dotAndCrossProduct = 0.03f; + static InternalDXXL_Plane planePerpTo_vector1 = new InternalDXXL_Plane(); + static InternalDXXL_Plane planePerpTo_vector2 = new InternalDXXL_Plane(); + + public static void DotProduct(Vector3 vector1_lhs, Vector3 vector2_rhs, Vector3 posWhereToDraw = default(Vector3), float linesWidth = 0.0025f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //"lhs" = "left hand side (of equation)" + //"rhs" = "right hand side (of equation)" + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector1_lhs, "vector1_lhs")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector2_rhs, "vector2_rhs")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(posWhereToDraw, "posWhereToDraw")) { return; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + + float vector1_magnitude = vector1_lhs.magnitude; + float vector2_magnitude = vector2_rhs.magnitude; + + Vector3 vector1_scaledIntoRegionOfFloatPrecision = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(vector1_lhs); + Vector3 vector2_scaledIntoRegionOfFloatPrecision = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(vector2_rhs); + + float angleDeg = Vector3.Angle(vector1_scaledIntoRegionOfFloatPrecision, vector2_scaledIntoRegionOfFloatPrecision); + float angleRad = Mathf.Deg2Rad * angleDeg; + bool angleIsTooSmallForStableDrawing = angleDeg < 0.1f; + + Color color_ofVector1 = DrawEngineBasics.colorOfVector1_forDotProduct; + Color color_ofVector2 = DrawEngineBasics.colorOfVector2_forDotProduct; + Color color_ofAngle = DrawEngineBasics.colorOfAngle_forDotProduct; + Color color_ofVertAxis = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(Color.white, 0.2f); + + Vector3 perpVector = Vector3.Cross(vector1_lhs, vector2_rhs); + if (perpVector.y < 0.0f) { perpVector = -perpVector; } + Vector3 perpVector_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(perpVector); + bool perpVectorIsTooShortForNormalizing = UtilitiesDXXL_Math.GetBiggestAbsComponent(perpVector_normalized) < 0.001f; + if (perpVectorIsTooShortForNormalizing) { perpVector_normalized = Vector3.up; } + + //thin short grey line through turnAxisCenter: + Line_fadeableAnimSpeed.InternalDraw(posWhereToDraw - 0.03f * perpVector_normalized, posWhereToDraw + 0.03f * perpVector_normalized, color_ofVertAxis, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + bool vector1_isTooShortForStableDrawing = UtilitiesDXXL_Math.GetBiggestAbsComponent(vector1_lhs) < 0.00001f; + bool vector2_isTooShortForStableDrawing = UtilitiesDXXL_Math.GetBiggestAbsComponent(vector2_rhs) < 0.00001f; + + if (vector1_isTooShortForStableDrawing == false) + { + planePerpTo_vector1.Recreate(posWhereToDraw, posWhereToDraw + vector1_lhs, posWhereToDraw + perpVector_normalized); + } + + if (vector2_isTooShortForStableDrawing == false) + { + planePerpTo_vector2.Recreate(posWhereToDraw, posWhereToDraw + vector2_rhs, posWhereToDraw + perpVector_normalized); + } + + float vectorLengthThreshold_belowWhichToUseRelConeLengths = 0.45f; + if (vector1_isTooShortForStableDrawing == false) + { + bool setConeLengthToRelative_notToAbsolute = (vector1_magnitude < vectorLengthThreshold_belowWhichToUseRelConeLengths); + float coneLength_ifSetToRelative = (0.1f / vectorLengthThreshold_belowWhichToUseRelConeLengths); + float coneLength_ifSetToAbsolute = 0.1f; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + UtilitiesDXXL_DrawBasics.VectorFrom(posWhereToDraw, vector1_lhs, color_ofVector1, linesWidth, "length(lhs) = " + vector1_magnitude, coneLength, false, false, true, minTextSize_atVectorFrom_dotAndCrossProduct, false, durationInSec, hiddenByNearerObjects, vector1_isTooShortForStableDrawing ? null : planePerpTo_vector1, false, 0.0f); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + if (vector2_isTooShortForStableDrawing == false) + { + bool setConeLengthToRelative_notToAbsolute = (vector2_magnitude < vectorLengthThreshold_belowWhichToUseRelConeLengths); + float coneLength_ifSetToRelative = (0.1f / vectorLengthThreshold_belowWhichToUseRelConeLengths); + float coneLength_ifSetToAbsolute = 0.1f; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + UtilitiesDXXL_DrawBasics.VectorFrom(posWhereToDraw, vector2_rhs, color_ofVector2, linesWidth, "length(rhs) = " + vector2_magnitude, coneLength, false, false, true, minTextSize_atVectorFrom_dotAndCrossProduct, false, durationInSec, hiddenByNearerObjects, vector2_isTooShortForStableDrawing ? null : planePerpTo_vector2, false, 0.0f); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + string text; + if (vector1_isTooShortForStableDrawing || vector2_isTooShortForStableDrawing || angleIsTooSmallForStableDrawing) + { + text = "dot product=
length(lhs) * length(rhs) * cos(angleBeweenVectors[rad])=
" + vector1_magnitude + " * " + vector2_magnitude + " * cos(" + angleRad + ")=
" + vector1_magnitude + " * " + vector2_magnitude + " * " + Mathf.Cos(angleRad) + "=
" + Vector3.Dot(vector1_lhs, vector2_rhs) + ""; + } + else + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + UtilitiesDXXL_Measurements.Set_defaultColors_reversible(color_ofAngle); + DrawMeasurements.AngleSpan(vector1_lhs, vector2_rhs, posWhereToDraw, color_ofAngle, 0.8f, linesWidth, null, false, true, 0.05f, false, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Measurements.Reverse_defaultColors(); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + text = "dot product=
" + vector1_magnitude + " * " + vector2_magnitude + " * cos(" + angleRad + ")=
" + vector1_magnitude + " * " + vector2_magnitude + " * " + Mathf.Cos(angleRad) + "=
" + Vector3.Dot(vector1_lhs, vector2_rhs) + ""; + } + + Vector3 vector1_normalizedOrZero = (UtilitiesDXXL_Math.ApproximatelyZero(vector1_magnitude)) ? Vector3.zero : (vector1_lhs / vector1_magnitude); + Vector3 vector2_normalizedOrZero = (UtilitiesDXXL_Math.ApproximatelyZero(vector2_magnitude)) ? Vector3.zero : (vector2_rhs / vector2_magnitude); + Vector3 textDir = vector1_normalizedOrZero + vector2_normalizedOrZero; + //Vector3 textUp = perpVector_normalized; + Vector3 textUp = Vector3.up; + UtilitiesDXXL_Text.WriteFramed(text, posWhereToDraw, DrawEngineBasics.colorOfResult_forDotProduct, 0.03f, textDir, textUp, DrawText.TextAnchorDXXL.LowerRight, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + + float radius_ofTurnCenterDot = 1.5f * linesWidth; + radius_ofTurnCenterDot = Mathf.Max(radius_ofTurnCenterDot, 0.0025f); + DrawShapes.Sphere(posWhereToDraw, radius_ofTurnCenterDot, color_ofAngle, Vector3.up, Vector3.forward, 0.0f, null, 8, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + } + + static Color colorOfVector1_forCrossProduct_before; + public static void Set_colorOfVector1_forCrossProduct_reversible(Color new_colorOfVector1_forCrossProduct) + { + colorOfVector1_forCrossProduct_before = DrawEngineBasics.colorOfVector1_forCrossProduct; + DrawEngineBasics.colorOfVector1_forCrossProduct = new_colorOfVector1_forCrossProduct; + } + public static void Reverse_colorOfVector1_forCrossProduct() + { + DrawEngineBasics.colorOfVector1_forCrossProduct = colorOfVector1_forCrossProduct_before; + } + + static Color colorOfVector2_forCrossProduct_before; + public static void Set_colorOfVector2_forCrossProduct_reversible(Color new_colorOfVector2_forCrossProduct) + { + colorOfVector2_forCrossProduct_before = DrawEngineBasics.colorOfVector2_forCrossProduct; + DrawEngineBasics.colorOfVector2_forCrossProduct = new_colorOfVector2_forCrossProduct; + } + public static void Reverse_colorOfVector2_forCrossProduct() + { + DrawEngineBasics.colorOfVector2_forCrossProduct = colorOfVector2_forCrossProduct_before; + } + + static Color colorOfAngle_forCrossProduct_before; + public static void Set_colorOfAngle_forCrossProduct_reversible(Color new_colorOfAngle_forCrossProduct) + { + colorOfAngle_forCrossProduct_before = DrawEngineBasics.colorOfAngle_forCrossProduct; + DrawEngineBasics.colorOfAngle_forCrossProduct = new_colorOfAngle_forCrossProduct; + } + public static void Reverse_colorOfAngle_forCrossProduct() + { + DrawEngineBasics.colorOfAngle_forCrossProduct = colorOfAngle_forCrossProduct_before; + } + + static Color colorOfResultVector_forCrossProduct_before; + public static void Set_colorOfResultVector_forCrossProduct_reversible(Color new_colorOfResultVector_forCrossProduct) + { + colorOfResultVector_forCrossProduct_before = DrawEngineBasics.colorOfResultVector_forCrossProduct; + DrawEngineBasics.colorOfResultVector_forCrossProduct = new_colorOfResultVector_forCrossProduct; + } + public static void Reverse_colorOfResultVector_forCrossProduct() + { + DrawEngineBasics.colorOfResultVector_forCrossProduct = colorOfResultVector_forCrossProduct_before; + } + + static Color colorOfResultText_forCrossProduct_before; + public static void Set_colorOfResultText_forCrossProduct_reversible(Color new_colorOfResultText_forCrossProduct) + { + colorOfResultText_forCrossProduct_before = DrawEngineBasics.colorOfResultText_forCrossProduct; + DrawEngineBasics.colorOfResultText_forCrossProduct = new_colorOfResultText_forCrossProduct; + } + public static void Reverse_colorOfResultText_forCrossProduct() + { + DrawEngineBasics.colorOfResultText_forCrossProduct = colorOfResultText_forCrossProduct_before; + } + + static Color colorOfResultPlane_forCrossProduct_before; + public static void Set_colorOfResultPlane_forCrossProduct_reversible(Color new_colorOfResultPlane_forCrossProduct) + { + colorOfResultPlane_forCrossProduct_before = DrawEngineBasics.colorOfResultPlane_forCrossProduct; + DrawEngineBasics.colorOfResultPlane_forCrossProduct = new_colorOfResultPlane_forCrossProduct; + } + public static void Reverse_colorOfResultPlane_forCrossProduct() + { + DrawEngineBasics.colorOfResultPlane_forCrossProduct = colorOfResultPlane_forCrossProduct_before; + } + + static Color overwriteColorForFrustumsHighlightedPlane_before; + public static void Set_overwriteColorForFrustumsHighlightedPlane_reversible(Color new_overwriteColorForFrustumsHighlightedPlane) + { + overwriteColorForFrustumsHighlightedPlane_before = DrawEngineBasics.overwriteColorForFrustumsHighlightedPlane; + DrawEngineBasics.overwriteColorForFrustumsHighlightedPlane = new_overwriteColorForFrustumsHighlightedPlane; + } + public static void Reverse_overwriteColorForFrustumsHighlightedPlane() + { + DrawEngineBasics.overwriteColorForFrustumsHighlightedPlane = overwriteColorForFrustumsHighlightedPlane_before; + } + + static float distanceOfFrustumsHighlightedPlane_before; + public static void Set_distanceOfFrustumsHighlightedPlane_reversible(float new_distanceOfFrustumsHighlightedPlane) + { + distanceOfFrustumsHighlightedPlane_before = DrawEngineBasics.distanceOfFrustumsHighlightedPlane; + DrawEngineBasics.distanceOfFrustumsHighlightedPlane = new_distanceOfFrustumsHighlightedPlane; + } + public static void Reverse_distanceOfFrustumsHighlightedPlane() + { + DrawEngineBasics.distanceOfFrustumsHighlightedPlane = distanceOfFrustumsHighlightedPlane_before; + } + + static bool drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane_before; + public static void Set_drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane_reversible(bool new_drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane) + { + drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane_before = DrawEngineBasics.drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane; + DrawEngineBasics.drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane = new_drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane; + } + public static void Reverse_drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane() + { + DrawEngineBasics.drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane = drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane_before; + } + + public static void CrossProduct(Vector3 vector1_lhs_leftThumb, Vector3 vector2_rhs_leftIndexFinger, Vector3 posWhereToDraw = default(Vector3), float linesWidth = 0.0025f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + //"lhs" = "left hand side (of equation)" + //"rhs" = "right hand side (of equation)" + //cross product result is "left middle finger" according to the left hand rule + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector1_lhs_leftThumb, "vector1_lhs_leftThumb")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(vector2_rhs_leftIndexFinger, "vector2_rhs_leftIndexFinger")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(posWhereToDraw, "posWhereToDraw")) { return; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + + float vector1_magnitude = vector1_lhs_leftThumb.magnitude; + float vector2_magnitude = vector2_rhs_leftIndexFinger.magnitude; + + Vector3 vector1_scaledIntoRegionOfFloatPrecision = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(vector1_lhs_leftThumb); + Vector3 vector2_scaledIntoRegionOfFloatPrecision = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(vector2_rhs_leftIndexFinger); + + float angleDeg = Vector3.Angle(vector1_scaledIntoRegionOfFloatPrecision, vector2_scaledIntoRegionOfFloatPrecision); + bool angleIsTooSmallForStableDrawing = angleDeg < 0.1f; + + Color color_ofVector1 = DrawEngineBasics.colorOfVector1_forCrossProduct; + Color color_ofVector2 = DrawEngineBasics.colorOfVector2_forCrossProduct; + Color color_ofAngle = DrawEngineBasics.colorOfAngle_forCrossProduct; + Color color_ofCrossProduct = DrawEngineBasics.colorOfResultVector_forCrossProduct; + + Vector3 crossProduct = Vector3.Cross(vector1_lhs_leftThumb, vector2_rhs_leftIndexFinger); + if (UtilitiesDXXL_Math.ApproximatelyZero(crossProduct) == false) + { + DrawShapes.Rhombus(posWhereToDraw, vector1_lhs_leftThumb, vector2_rhs_leftIndexFinger, DrawEngineBasics.colorOfResultPlane_forCrossProduct, 0.0f, null, 10, DrawBasics.LineStyle.solid, 1.0f, durationInSec, hiddenByNearerObjects); + } + + Vector3 perpVector = crossProduct; + + if (perpVector.y < 0.0f) { perpVector = -perpVector; } + Vector3 perpVector_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(perpVector); + bool perpVectorIsTooShortForNormalizing = UtilitiesDXXL_Math.GetBiggestAbsComponent(perpVector_normalized) < 0.001f; + if (perpVectorIsTooShortForNormalizing) { perpVector_normalized = Vector3.up; } + + bool vector1_isTooShortForStableDrawing = UtilitiesDXXL_Math.GetBiggestAbsComponent(vector1_lhs_leftThumb) < 0.00001f; + bool vector2_isTooShortForStableDrawing = UtilitiesDXXL_Math.GetBiggestAbsComponent(vector2_rhs_leftIndexFinger) < 0.00001f; + + if (vector1_isTooShortForStableDrawing == false) + { + planePerpTo_vector1.Recreate(posWhereToDraw, posWhereToDraw + vector1_lhs_leftThumb, posWhereToDraw + perpVector_normalized); + } + + if (vector2_isTooShortForStableDrawing == false) + { + planePerpTo_vector2.Recreate(posWhereToDraw, posWhereToDraw + vector2_rhs_leftIndexFinger, posWhereToDraw + perpVector_normalized); + } + + float vectorLenghtThreshold_belowWhichToUseRelConeLengths = 0.45f; + if (vector1_isTooShortForStableDrawing == false) + { + bool setConeLengthToRelative_notToAbsolute = (vector1_magnitude < vectorLenghtThreshold_belowWhichToUseRelConeLengths); + float coneLength_ifSetToRelative = 0.1f / vectorLenghtThreshold_belowWhichToUseRelConeLengths; + float coneLength_ifSetToAbsolute = 0.1f; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + UtilitiesDXXL_DrawBasics.VectorFrom(posWhereToDraw, vector1_lhs_leftThumb, color_ofVector1, linesWidth, "length (lhs[=left]) = " + vector1_magnitude, coneLength, false, false, true, minTextSize_atVectorFrom_dotAndCrossProduct, false, durationInSec, hiddenByNearerObjects, vector1_isTooShortForStableDrawing ? null : planePerpTo_vector1, false, 0.0f); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + if (vector2_isTooShortForStableDrawing == false) + { + bool setConeLengthToRelative_notToAbsolute = (vector2_magnitude < vectorLenghtThreshold_belowWhichToUseRelConeLengths); + float coneLength_ifSetToRelative = 0.1f / vectorLenghtThreshold_belowWhichToUseRelConeLengths; + float coneLength_ifSetToAbsolute = 0.1f; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + UtilitiesDXXL_DrawBasics.VectorFrom(posWhereToDraw, vector2_rhs_leftIndexFinger, color_ofVector2, linesWidth, "length (rhs[=left]) = " + vector2_magnitude, coneLength, false, false, true, minTextSize_atVectorFrom_dotAndCrossProduct, false, durationInSec, hiddenByNearerObjects, vector2_isTooShortForStableDrawing ? null : planePerpTo_vector2, false, 0.0f); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + float crossProduct_magnitude = crossProduct.magnitude; + string text = "cross product=

Vector3(" + crossProduct.x + " , " + crossProduct.y + " , " + crossProduct.z + ")
direction:left middle finger (left-hand rule)
length (= area) = " + crossProduct_magnitude + ""; + if (crossProduct_magnitude < 0.002f) + { + UtilitiesDXXL_Text.WriteFramed(text, posWhereToDraw, color_ofCrossProduct, 0.03f, crossProduct, -(vector1_lhs_leftThumb + vector2_rhs_leftIndexFinger), DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + else + { + bool setConeLengthToRelative_notToAbsolute = (crossProduct_magnitude < vectorLenghtThreshold_belowWhichToUseRelConeLengths); + float coneLength_ifSetToRelative = 0.1f / vectorLenghtThreshold_belowWhichToUseRelConeLengths; + float coneLength_ifSetToAbsolute = 0.1f; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + UtilitiesDXXL_DrawBasics.VectorFrom(posWhereToDraw, crossProduct, color_ofCrossProduct, linesWidth, text, coneLength, false, false, true, 0.025f, false, durationInSec, hiddenByNearerObjects, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + if (vector1_isTooShortForStableDrawing == false && vector2_isTooShortForStableDrawing == false && angleIsTooSmallForStableDrawing == false) + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + UtilitiesDXXL_Measurements.Set_defaultColors_reversible(color_ofAngle); + DrawMeasurements.AngleSpan(vector1_lhs_leftThumb, vector2_rhs_leftIndexFinger, posWhereToDraw, color_ofAngle, 0.8f, linesWidth, null, false, true, 0.05f, false, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Measurements.Reverse_defaultColors(); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + } + + float radius_ofTurnCenterDot = 1.5f * linesWidth; + radius_ofTurnCenterDot = Mathf.Max(radius_ofTurnCenterDot, 0.0025f); + DrawShapes.Sphere(posWhereToDraw, radius_ofTurnCenterDot, color_ofAngle, Vector3.up, Vector3.forward, 0.0f, null, 8, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + } + + + static InternalDXXL_Line rayline = new InternalDXXL_Line(); + public static void RayLineExtended(bool is2D, Vector3 rayOrigin, Vector3 rayDirection, Color color = default(Color), float width = 0.0f, string text = null, float forceFixedConeLength = 0.0f, bool addNormalizedMarkingText = true, float enlargeSmallTextToThisMinTextSize = 0.005f, float extentionLength = 1000.0f, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(extentionLength, "extentionLength")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(rayOrigin, "rayOrigin")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(rayDirection, "rayDirection")) { return; } + + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + if (UtilitiesDXXL_Math.ApproximatelyZero(rayDirection)) + { + UtilitiesDXXL_DrawBasics.PointFallback(rayOrigin, "[ RayLineExtended with length of 0]
" + text, color, width, durationInSec, hiddenByNearerObjects); + return; + } + width = Mathf.Max(width, 0.006f); + + Color colorOfProlongedLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.55f); + + rayline.Recreate(rayOrigin, rayDirection, false); + if (rayline.originHasBeenRelocated) + { + text = "[ RayOrigin (" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(rayOrigin) + ") was too far off
(float world positions get uncertain in this high region)
-> auto-relocate to " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(rayline.origin) + "
to prevent undefined behaviour]
" + text; + } + + bool setConeLengthToRelative_notToAbsolute = UtilitiesDXXL_Math.ApproximatelyZero(forceFixedConeLength); + float coneLength_ifSetToRelative = 0.17f; + float coneLength_ifSetToAbsolute = forceFixedConeLength; + float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute); + if (is2D) + { + DrawBasics2D.VectorFrom(rayline.origin, rayline.direction, color, width, text, coneLength, false, rayline.origin.z, addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, false, 0.0f, durationInSec, hiddenByNearerObjects); + } + else + { + DrawBasics.VectorFrom(rayline.origin, rayline.direction, color, width, text, coneLength, false, false, default(Vector3), addNormalizedMarkingText, enlargeSmallTextToThisMinTextSize, false, 0.0f, durationInSec, hiddenByNearerObjects); + } + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + + Vector3 extentionVector = rayline.direction_normalized * extentionLength; + Line_fadeableAnimSpeed.InternalDraw(rayline.origin - extentionVector, rayline.origin + extentionVector, colorOfProlongedLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, false, false); + float originSphere_radius = Mathf.Min(1.1f * width, 0.1f * rayline.length); + if (is2D) + { + DrawShapes.Circle(rayOrigin, originSphere_radius, color, Vector3.forward, Vector3.up, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, true, false, durationInSec, hiddenByNearerObjects); + } + else + { + DrawShapes.Sphere(rayOrigin, originSphere_radius, color, rayline.direction_normalized, default, 0.0f, null, 8, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + } + + } + + + static InternalDXXL_Line2D rayLineViewportSpace = new InternalDXXL_Line2D(); + public static void RayLineExtendedScreenspace(Camera camera, Vector2 rayOrigin, Vector2 rayDirection, Color color = default(Color), float width_relToViewportHeight = 0.0f, string text = null, bool interpretDirectionAsUnwarped = false, float coneLength_relToViewportHeight = 0.05f, bool displayDistanceOutsideScreenBorder = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(camera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_relToViewportHeight, "width_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(coneLength_relToViewportHeight, "coneLength_relToViewportHeight")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(rayOrigin, "rayOrigin")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(rayDirection, "rayDirection")) { return; } + + width_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(width_relToViewportHeight); + + if (UtilitiesDXXL_Math.ApproximatelyZero(rayDirection)) + { + UtilitiesDXXL_Screenspace.PointFallback(camera, InternalDXXL_BoundsCamViewportSpace.ClampIntoViewport(rayOrigin), "[ RayLineExtendedScreenspace with length of 0]
" + text, color, width_relToViewportHeight, durationInSec); + return; + } + + float minWidth_relTViewportHeight = 0.003f; + width_relToViewportHeight = Mathf.Max(width_relToViewportHeight, minWidth_relTViewportHeight); + + Color colorOfProlongedLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.55f); + + Vector2 rayDirection_inNonSquareViewportSpace = interpretDirectionAsUnwarped ? DrawScreenspace.DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(rayDirection, camera) : rayDirection; + DrawScreenspace.VectorFrom(camera, rayOrigin, rayDirection_inNonSquareViewportSpace, color, width_relToViewportHeight, text, false, coneLength_relToViewportHeight, false, false, 0.0f, durationInSec); + + Vector2 rayPeak_inNonSquareViewportSpace = rayOrigin + rayDirection_inNonSquareViewportSpace; + if (InternalDXXL_BoundsCamViewportSpace.IsInsideViewportExclBorder(rayOrigin) == false && InternalDXXL_BoundsCamViewportSpace.IsInsideViewportExclBorder(rayPeak_inNonSquareViewportSpace) == false) + { + rayLineViewportSpace.Recalc_line_throughTwoPoints_returnSteepForVertLines(rayOrigin, rayPeak_inNonSquareViewportSpace); + Vector2 viewportCenterProjectionOntoLine_inNonSquareViewportSpace = rayLineViewportSpace.GetProjectionOfPointOntoLine(InternalDXXL_BoundsCamViewportSpace.viewportCenter); + Vector2 nearestViewportCorner = InternalDXXL_BoundsCamViewportSpace.wholeViewportAsBounds.GetNearestCorner(viewportCenterProjectionOntoLine_inNonSquareViewportSpace); + nearestViewportCorner.y = UtilitiesDXXL_Math.ApproximatelyZero(rayDirection.x) ? 0.0f : nearestViewportCorner.y; //->prevents flickering + Vector2 projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace = rayLineViewportSpace.GetProjectionOfPointOntoLine(nearestViewportCorner); + projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace.y = UtilitiesDXXL_Math.ApproximatelyZero(rayDirection.x) ? 0.0f : projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace.y; //->prevents flickering + bool preventFlickerOfHorizLinesThroughViewport = (Mathf.Abs(rayDirection.y) < 0.0001f) && (projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace.y > 0.0f && projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace.y < 1.0f); + bool isVertLineThroughViewport = UtilitiesDXXL_Math.ApproximatelyZero(rayDirection.x) && (projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace.x > 0.0f && projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace.x < 1.0f); + if (isVertLineThroughViewport || preventFlickerOfHorizLinesThroughViewport || InternalDXXL_BoundsCamViewportSpace.IsInsideViewportExclBorder(projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace)) + { + if (text != null && text != "") + { + DrawText.TextAnchorDXXL textAnchor = (nearestViewportCorner.y < 0.5f) ? DrawText.TextAnchorDXXL.LowerCenter : DrawText.TextAnchorDXXL.UpperCenter; + float textSize_relToViewportHeight = 0.02f; + float half_textSize_relToViewportHeight = 0.5f * textSize_relToViewportHeight; + Vector2 textPos = new Vector2(Mathf.Clamp(projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace.x, half_textSize_relToViewportHeight, 1.0f - half_textSize_relToViewportHeight), Mathf.Clamp(projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace.y, half_textSize_relToViewportHeight, 1.0f - half_textSize_relToViewportHeight)); //clamping due to: prevent flickering of "autoLineBreakWidth_relToViewportWidth" + Vector2 rayDirection_inAspectCorrected1by1SquareViewportSpace = DrawScreenspace.DirectionInUnitsOfWarpedSpace_to_sameLookingDirectionInUnitsOfUnwarpedSpace(rayDirection_inNonSquareViewportSpace, camera); + UtilitiesDXXL_Text.WriteScreenSpace(camera, text, textPos, color, textSize_relToViewportHeight, rayDirection_inAspectCorrected1by1SquareViewportSpace, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, true, durationInSec, false); + } + } + else + { + DrawScreenspace.PointTag(camera, projectionOfNearestViewportCornerOntoLine_inNonSquareViewportSpace, text, null, color, true, 0.0f, 0.2f, default(Vector2), 1.0f, false, displayDistanceOutsideScreenBorder, durationInSec, default(Vector2)); + } + } + + float extentionLength = 1.0f + (rayOrigin - InternalDXXL_BoundsCamViewportSpace.viewportCenter).magnitude; + Vector2 rayDirection_inNonSquareViewportSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(rayDirection_inNonSquareViewportSpace); + Vector2 extentionVector = rayDirection_inNonSquareViewportSpace_normalized * extentionLength; + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, rayOrigin - extentionVector, rayOrigin + extentionVector, colorOfProlongedLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, DrawScreenspace.minTextSize_relToViewportHeight, durationInSec); + + float originDot_size_relToViewportHeight = 1.6f * width_relToViewportHeight; + originDot_size_relToViewportHeight = Mathf.Max(originDot_size_relToViewportHeight, 2.6f * minWidth_relTViewportHeight); + float originDot_size_relToViewportHeight_075 = 0.75f * originDot_size_relToViewportHeight; + float originDot_size_relToViewportHeight_05 = 0.5f * originDot_size_relToViewportHeight; + DrawScreenspace.Shape(camera, rayOrigin, DrawShapes.Shape2DType.circle, color, originDot_size_relToViewportHeight_075, originDot_size_relToViewportHeight_075, 0.0f, originDot_size_relToViewportHeight_05, null, false, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, true, durationInSec); + } + + public static void Camera(Vector3 position, Vector3 forward, Vector3 up, bool isOrthographic, float orthographicSize, float fieldOfView, float nearClipPlane, float aspect, Color color, string text, float linesWidth, float durationInSec, bool hiddenByNearerObjects) + { + //"fieldOfView" can be vertical or horizontal. UnityEngine.Camera.fieldOfView" always returns the vertical fieldOfView, also if the camera inspector component has set the "FOV Axis"-dropdown to "horizontal" + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + + float tanOfHalfFieldOfView = Mathf.Tan(0.5f * fieldOfView * Mathf.Deg2Rad); + float heightOfCamsNearPlane; + Vector3 offsetForOrthograficCams = Vector3.zero; + if (isOrthographic) + { + heightOfCamsNearPlane = 2.0f * orthographicSize; + } + else + { + heightOfCamsNearPlane = 2.0f * nearClipPlane * tanOfHalfFieldOfView; + } + + float heightOfDrawnFrustumsNearPlane = 0.5f * heightOfCamsNearPlane; + float widthOfCamsNearPlane = heightOfCamsNearPlane * aspect; + float widthOfDrawnFrustumsNearPlane = 0.5f * widthOfCamsNearPlane; + float distanceToNearClipPlaneOfCamFrustum = 0.5f * heightOfCamsNearPlane / tanOfHalfFieldOfView; + float distanceToNearClipPlaneOfDrawnFrustum = 0.5f * distanceToNearClipPlaneOfCamFrustum; + + if (isOrthographic) + { + offsetForOrthograficCams = -forward * (distanceToNearClipPlaneOfCamFrustum - nearClipPlane); + } + + DrawShapes.Frustum(position + offsetForOrthograficCams, forward, up, fieldOfView, aspect, distanceToNearClipPlaneOfDrawnFrustum, distanceToNearClipPlaneOfCamFrustum, color, DrawShapes.Shape2DType.square, linesWidth, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + if (isOrthographic == false) + { + float angleDeg_horiz = 2.0f * Mathf.Rad2Deg * Mathf.Atan(0.5f * (widthOfCamsNearPlane / nearClipPlane)); + DrawShapes.Pyramid(position + offsetForOrthograficCams, distanceToNearClipPlaneOfDrawnFrustum, forward, up, fieldOfView, angleDeg_horiz, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.25f), DrawShapes.Shape2DType.square, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + + float cubeHeight = 1.2f * heightOfDrawnFrustumsNearPlane; + float cubeWidth = 1.2f * widthOfDrawnFrustumsNearPlane; + DrawShapes.Cylinder(position - forward * 0.0f * distanceToNearClipPlaneOfCamFrustum + offsetForOrthograficCams, 1.0f * distanceToNearClipPlaneOfCamFrustum, cubeWidth, cubeHeight, color, forward, up, DrawShapes.Shape2DType.square, linesWidth, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + Vector3 cameraLeftNormalized = Vector3.Cross(forward, up); + Vector3 cameraRightNormalized = -cameraLeftNormalized; + float cylSize = 0.9f * distanceToNearClipPlaneOfDrawnFrustum; + Vector3 cyl1_position = position + up * (0.5f * cubeHeight + 0.5f * cylSize) + forward * (0.25f * cylSize); + + DrawShapes.Cylinder(cyl1_position + offsetForOrthograficCams, 0.25f * cubeWidth, cylSize, cylSize, color, cameraLeftNormalized, up, DrawShapes.Shape2DType.circle, linesWidth, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Cylinder(cyl1_position - forward * cylSize + offsetForOrthograficCams, 0.25f * cubeWidth, cylSize, cylSize, color, cameraLeftNormalized, up, DrawShapes.Shape2DType.circle, linesWidth, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + if (text != null && text != "") + { + float lineHeight = 0.08f * heightOfCamsNearPlane; + Vector3 centerOfCamsNearPlane = position + forward * nearClipPlane; + Vector3 topLeftCorner_ofCamsNearPlane = centerOfCamsNearPlane + cameraLeftNormalized * (0.5f * widthOfCamsNearPlane) + up * (0.5f * heightOfCamsNearPlane); + Vector3 textPosition = topLeftCorner_ofCamsNearPlane + (0.02f * widthOfCamsNearPlane) * cameraRightNormalized - (1.7f * lineHeight) * up; + UtilitiesDXXL_Text.WriteFramed(text, textPosition + forward * 0.0001f, color, lineHeight, cameraRightNormalized, up, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.96f * widthOfCamsNearPlane, 0.0f, false, durationInSec, false); + } + } + + static InternalDXXL_Plane frustums_farPlane = new InternalDXXL_Plane(); + static InternalDXXL_Plane frustums_highightedPlane = new InternalDXXL_Plane(); + static InternalDXXL_Plane camPlane_throughCamPos = new InternalDXXL_Plane(); + static InternalDXXL_Line frustums_lowLeftEdge = new InternalDXXL_Line(); + static InternalDXXL_Line frustums_topLeftEdge = new InternalDXXL_Line(); + static InternalDXXL_Line frustums_lowRightEdge = new InternalDXXL_Line(); + static InternalDXXL_Line frustums_topRightEdge = new InternalDXXL_Line(); + public static void CameraFrustum(Vector3 position, Vector3 forward, Vector3 up, bool isOrthographic, float orthographicSize, float fieldOfView, float nearClipPlane, float farClipPlane, float aspect, Color color, string text, bool forceTextOnNearPlaneUnmirroredTowardsCam, float linesWidth_ofEdges, float alphaFactor_forBoundarySurfaceLines, int linesPerBoundarySurface, Vector3 positionOnHighlightedPlane, float durationInSec, bool hiddenByNearerObjects) + { + //"fieldOfView" can be vertical or horizontal. UnityEngine.Camera.fieldOfView" always returns the vertical fieldOfView, also if the camera inspector component has set the "FOV Axis"-dropdown to "horizontal" + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth_ofEdges, "linesWidth_ofEdges")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(alphaFactor_forBoundarySurfaceLines, "alphaFactor_forBoundarySurfaceLines")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(positionOnHighlightedPlane, "positionOnHighlightedPlane")) { return; } + + Color color_ofEdgeLines = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + Color color_ofBoundarySurfaceLines = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofEdgeLines, alphaFactor_forBoundarySurfaceLines); + + Vector3 forward_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(forward); + Vector3 up_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(up); + Vector3 right_normalized = Vector3.Cross(up_normalized, forward_normalized); + + Vector3 center_ofNearPlane = position + forward_normalized * nearClipPlane; + Vector3 center_ofFarPlane = position + forward_normalized * farClipPlane; + + float tanOfHalfFieldOfView = Mathf.Tan(0.5f * fieldOfView * Mathf.Deg2Rad); + float heightOfCamsNearPlane; + if (isOrthographic) + { + heightOfCamsNearPlane = 2.0f * orthographicSize; + } + else + { + heightOfCamsNearPlane = 2.0f * nearClipPlane * tanOfHalfFieldOfView; + } + float widthOfCamsNearPlane = heightOfCamsNearPlane * aspect; + + float half_heightOfCamsNearPlane = 0.5f * heightOfCamsNearPlane; + float half_widthOfCamsNearPlane = 0.5f * widthOfCamsNearPlane; + + Vector3 nearPlanes_lowLeftVertex = center_ofNearPlane - up_normalized * half_heightOfCamsNearPlane - right_normalized * half_widthOfCamsNearPlane; + Vector3 nearPlanes_topLeftVertex = center_ofNearPlane + up_normalized * half_heightOfCamsNearPlane - right_normalized * half_widthOfCamsNearPlane; + Vector3 nearPlanes_lowRightVertex = center_ofNearPlane - up_normalized * half_heightOfCamsNearPlane + right_normalized * half_widthOfCamsNearPlane; + Vector3 nearPlanes_topRightVertex = center_ofNearPlane + up_normalized * half_heightOfCamsNearPlane + right_normalized * half_widthOfCamsNearPlane; + + if (isOrthographic) + { + frustums_lowLeftEdge.Recreate(nearPlanes_lowLeftVertex, forward_normalized, true); + frustums_topLeftEdge.Recreate(nearPlanes_topLeftVertex, forward_normalized, true); + frustums_lowRightEdge.Recreate(nearPlanes_lowRightVertex, forward_normalized, true); + frustums_topRightEdge.Recreate(nearPlanes_topRightVertex, forward_normalized, true); + } + else + { + frustums_lowLeftEdge.Recreate(position, nearPlanes_lowLeftVertex - position, false); + frustums_topLeftEdge.Recreate(position, nearPlanes_topLeftVertex - position, false); + frustums_lowRightEdge.Recreate(position, nearPlanes_lowRightVertex - position, false); + frustums_topRightEdge.Recreate(position, nearPlanes_topRightVertex - position, false); + } + + frustums_farPlane.Recreate(center_ofFarPlane, forward); + Vector3 farPlanes_lowLeftVertex = frustums_farPlane.GetIntersectionWithLine(frustums_lowLeftEdge); + Vector3 farPlanes_topLeftVertex = frustums_farPlane.GetIntersectionWithLine(frustums_topLeftEdge); + Vector3 farPlanes_lowRightVertex = frustums_farPlane.GetIntersectionWithLine(frustums_lowRightEdge); + Vector3 farPlanes_topRightVertex = frustums_farPlane.GetIntersectionWithLine(frustums_topRightEdge); + + Line_fadeableAnimSpeed.InternalDraw(nearPlanes_lowLeftVertex, nearPlanes_topLeftVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(nearPlanes_topLeftVertex, nearPlanes_topRightVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(nearPlanes_topRightVertex, nearPlanes_lowRightVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(nearPlanes_lowRightVertex, nearPlanes_lowLeftVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(farPlanes_lowLeftVertex, farPlanes_topLeftVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(farPlanes_topLeftVertex, farPlanes_topRightVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(farPlanes_topRightVertex, farPlanes_lowRightVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(farPlanes_lowRightVertex, farPlanes_lowLeftVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(nearPlanes_lowLeftVertex, farPlanes_lowLeftVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(nearPlanes_topLeftVertex, farPlanes_topLeftVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(nearPlanes_lowRightVertex, farPlanes_lowRightVertex, color_ofEdgeLines, linesWidth_ofEdges, 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(nearPlanes_topRightVertex, farPlanes_topRightVertex, color_ofEdgeLines, linesWidth_ofEdges, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + DrawFrustumsBoundarySurfaces(nearPlanes_lowLeftVertex, nearPlanes_topLeftVertex, farPlanes_lowLeftVertex, farPlanes_topLeftVertex, color_ofBoundarySurfaceLines, linesPerBoundarySurface, durationInSec, hiddenByNearerObjects); + DrawFrustumsBoundarySurfaces(nearPlanes_topLeftVertex, nearPlanes_topRightVertex, farPlanes_topLeftVertex, farPlanes_topRightVertex, color_ofBoundarySurfaceLines, linesPerBoundarySurface, durationInSec, hiddenByNearerObjects); + DrawFrustumsBoundarySurfaces(nearPlanes_topRightVertex, nearPlanes_lowRightVertex, farPlanes_topRightVertex, farPlanes_lowRightVertex, color_ofBoundarySurfaceLines, linesPerBoundarySurface, durationInSec, hiddenByNearerObjects); + DrawFrustumsBoundarySurfaces(nearPlanes_lowRightVertex, nearPlanes_lowLeftVertex, farPlanes_lowRightVertex, farPlanes_lowLeftVertex, color_ofBoundarySurfaceLines, linesPerBoundarySurface, durationInSec, hiddenByNearerObjects); + + TryDrawHighlightedPlane(position, forward_normalized, positionOnHighlightedPlane, nearClipPlane, farClipPlane, color, durationInSec, hiddenByNearerObjects); + + if (text != null && text != "") + { + DrawTextAtCameraFrustum(position, forward_normalized, nearClipPlane, farClipPlane, widthOfCamsNearPlane, text, forceTextOnNearPlaneUnmirroredTowardsCam, color_ofEdgeLines, up_normalized, right_normalized, farPlanes_lowRightVertex, farPlanes_lowLeftVertex, durationInSec, hiddenByNearerObjects); + } + } + + static void TryDrawHighlightedPlane(Vector3 position, Vector3 forward_normalized, Vector3 positionOnHighlightedPlane, float nearClipPlane, float farClipPlane, Color colorOfFrustumItself, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.IsDefaultVector(positionOnHighlightedPlane)) + { + if (DrawEngineBasics.distanceOfFrustumsHighlightedPlane >= nearClipPlane) + { + DrawHighlightedPlane(position, forward_normalized, DrawEngineBasics.distanceOfFrustumsHighlightedPlane, farClipPlane, colorOfFrustumItself, durationInSec, hiddenByNearerObjects); + } + } + else + { + Vector3 cam_to_highlightedPlaneAnchor = positionOnHighlightedPlane - position; + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(cam_to_highlightedPlaneAnchor, forward_normalized)) + { + camPlane_throughCamPos.Recreate(position, forward_normalized); + Vector3 positionOnHighlightedPlane_projectedOntoCamPlaneThroughCamPos = camPlane_throughCamPos.Get_perpProjectionOfPointOnPlane(positionOnHighlightedPlane); + float perpDistance_fromHighlightedPlanePos_toCamPlaneThroughCamPos = (positionOnHighlightedPlane - positionOnHighlightedPlane_projectedOntoCamPlaneThroughCamPos).magnitude; + if (perpDistance_fromHighlightedPlanePos_toCamPlaneThroughCamPos >= nearClipPlane) + { + DrawHighlightedPlane(position, forward_normalized, perpDistance_fromHighlightedPlanePos_toCamPlaneThroughCamPos, farClipPlane, colorOfFrustumItself, durationInSec, hiddenByNearerObjects); + } + } + } + } + + static void DrawHighlightedPlane(Vector3 position, Vector3 forward_normalized, float distanceOfHighlightedPlane, float farClipPlane, Color colorOfFrustumItself, float durationInSec, bool hiddenByNearerObjects) + { + if ((distanceOfHighlightedPlane <= farClipPlane) || DrawEngineBasics.drawFrustumsHighlightedPlaneAlsoIfFarerThanFarClipPlane) + { + Color colorOfHighlightedPlane = UtilitiesDXXL_Colors.IsDefaultColor(DrawEngineBasics.overwriteColorForFrustumsHighlightedPlane) ? Get_defaultColor_ofFrustumsHighlightedPlane(colorOfFrustumItself) : DrawEngineBasics.overwriteColorForFrustumsHighlightedPlane; + Color colorFor01 = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorOfHighlightedPlane, 0.5f); + Color colorFor001 = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorOfHighlightedPlane, 0.15f); + + Vector3 center_ofHighlightedPlane = position + forward_normalized * distanceOfHighlightedPlane; + frustums_highightedPlane.Recreate(center_ofHighlightedPlane, forward_normalized); + Vector3 highlightedPlanes_lowLeftVertex = frustums_highightedPlane.GetIntersectionWithLine(frustums_lowLeftEdge); + Vector3 highlightedPlanes_topLeftVertex = frustums_highightedPlane.GetIntersectionWithLine(frustums_topLeftEdge); + Vector3 highlightedPlanes_lowRightVertex = frustums_highightedPlane.GetIntersectionWithLine(frustums_lowRightEdge); + Vector3 highlightedPlanes_topRightVertex = frustums_highightedPlane.GetIntersectionWithLine(frustums_topRightEdge); + + //three main horiz lines: + UtilitiesDXXL_DrawBasics.Line(highlightedPlanes_lowLeftVertex, highlightedPlanes_lowRightVertex, colorOfHighlightedPlane, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + UtilitiesDXXL_DrawBasics.Line(0.5f * (highlightedPlanes_lowLeftVertex + highlightedPlanes_topLeftVertex), 0.5f * (highlightedPlanes_lowRightVertex + highlightedPlanes_topRightVertex), colorOfHighlightedPlane, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + UtilitiesDXXL_DrawBasics.Line(highlightedPlanes_topLeftVertex, highlightedPlanes_topRightVertex, colorOfHighlightedPlane, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + + //three main vert lines: + UtilitiesDXXL_DrawBasics.Line(highlightedPlanes_lowLeftVertex, highlightedPlanes_topLeftVertex, colorOfHighlightedPlane, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + UtilitiesDXXL_DrawBasics.Line(0.5f * (highlightedPlanes_lowLeftVertex + highlightedPlanes_lowRightVertex), 0.5f * (highlightedPlanes_topLeftVertex + highlightedPlanes_topRightVertex), colorOfHighlightedPlane, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + UtilitiesDXXL_DrawBasics.Line(highlightedPlanes_lowRightVertex, highlightedPlanes_topRightVertex, colorOfHighlightedPlane, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + + Vector3 lowerEndToUpperEndOnHighlightedPlane_inWorldSpace = highlightedPlanes_topLeftVertex - highlightedPlanes_lowLeftVertex; + Vector3 leftEndToRightEndOnHighlightedPlane_inWorldSpace = highlightedPlanes_lowRightVertex - highlightedPlanes_lowLeftVertex; + + for (int i = 1; i < 10; i++) + { + float currentProgress = (0.1f * i); + + Vector3 currentRightShiftVector = leftEndToRightEndOnHighlightedPlane_inWorldSpace * currentProgress; + UtilitiesDXXL_DrawBasics.Line(highlightedPlanes_lowLeftVertex + currentRightShiftVector, highlightedPlanes_topLeftVertex + currentRightShiftVector, colorFor01, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + + Vector3 currentUpwardShiftVector = lowerEndToUpperEndOnHighlightedPlane_inWorldSpace * currentProgress; + UtilitiesDXXL_DrawBasics.Line(highlightedPlanes_lowLeftVertex + currentUpwardShiftVector, highlightedPlanes_lowRightVertex + currentUpwardShiftVector, colorFor01, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + } + + for (int i = 1; i < 100; i++) + { + float currentProgress = (0.01f * i); + + Vector3 currentRightShiftVector = leftEndToRightEndOnHighlightedPlane_inWorldSpace * currentProgress; + UtilitiesDXXL_DrawBasics.Line(highlightedPlanes_lowLeftVertex + currentRightShiftVector, highlightedPlanes_topLeftVertex + currentRightShiftVector, colorFor001, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + + Vector3 currentUpwardShiftVector = lowerEndToUpperEndOnHighlightedPlane_inWorldSpace * currentProgress; + UtilitiesDXXL_DrawBasics.Line(highlightedPlanes_lowLeftVertex + currentUpwardShiftVector, highlightedPlanes_lowRightVertex + currentUpwardShiftVector, colorFor001, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + } + } + } + + public static Color Get_defaultColor_ofFrustumsHighlightedPlane(Color colorOfFrustumItself) + { + return ((colorOfFrustumItself.grayscale < 0.175f) ? Color.Lerp(colorOfFrustumItself, Color.white, 0.7f) : Color.Lerp(colorOfFrustumItself, Color.black, 0.7f)); + } + + static void DrawTextAtCameraFrustum(Vector3 position, Vector3 forward_normalized, float nearClipPlane, float farClipPlane, float widthOfCamsNearPlane, string text, bool forceTextOnNearPlaneUnmirroredTowardsCam, Color color_ofEdgeLines, Vector3 up_normalized, Vector3 right_normalized, Vector3 farPlanes_lowRightVertex, Vector3 farPlanes_lowLeftVertex, float durationInSec, bool hiddenByNearerObjects) + { + //on nearPlane: + //(slightly inside frustum = readable in cameras generated image) + bool autoFlipToPreventMirrorInverted = !forceTextOnNearPlaneUnmirroredTowardsCam; + Vector3 textPosition = position + forward_normalized * nearClipPlane * 1.01f; + float textSize = widthOfCamsNearPlane * 0.05f; + float autoLineBreakWidth = widthOfCamsNearPlane * 0.9f; + UtilitiesDXXL_Text.Write(text, textPosition, color_ofEdgeLines, textSize, right_normalized, up_normalized, DrawText.TextAnchorDXXL.MiddleCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, false, false, true); + + //on farPlane: + //(slightly outside frustum = not readable in cameras generated image) + float widthOfCamsFarPlane = (farPlanes_lowRightVertex - farPlanes_lowLeftVertex).magnitude; + autoFlipToPreventMirrorInverted = true; + textPosition = position + forward_normalized * farClipPlane * 1.001f; + textSize = widthOfCamsFarPlane * 0.05f; + autoLineBreakWidth = widthOfCamsFarPlane * 0.9f; + UtilitiesDXXL_Text.Write(text, textPosition, color_ofEdgeLines, textSize, right_normalized, up_normalized, DrawText.TextAnchorDXXL.MiddleCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, false, false, true); + } + + static void DrawFrustumsBoundarySurfaces(Vector3 nearPlanes_anchor1, Vector3 nearPlanes_anchor2, Vector3 farPlanes_anchor1, Vector3 farPlanes_anchor2, Color color_ofBoundarySurfaceLines, int linesPerBoundarySurface, float durationInSec, bool hiddenByNearerObjects) + { + if (linesPerBoundarySurface > 0) + { + Vector3 nearPlane_fromAnchor1_toAnchor2 = nearPlanes_anchor2 - nearPlanes_anchor1; + Vector3 farPlane_fromAnchor1_toAnchor2 = farPlanes_anchor2 - farPlanes_anchor1; + + Vector3 nearPlane_fromSubLineAnchorToSubLineAnchor = nearPlane_fromAnchor1_toAnchor2 / (float)(linesPerBoundarySurface + 1); + Vector3 farPlane_fromSubLineAnchorToSubLineAnchor = farPlane_fromAnchor1_toAnchor2 / (float)(linesPerBoundarySurface + 1); + + for (int i = 1; i <= linesPerBoundarySurface; i++) + { + Line_fadeableAnimSpeed.InternalDraw(nearPlanes_anchor1 + nearPlane_fromSubLineAnchorToSubLineAnchor * i, farPlanes_anchor1 + farPlane_fromSubLineAnchorToSubLineAnchor * i, color_ofBoundarySurfaceLines, 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 InternalDXXL_Plane drawPlane = new InternalDXXL_Plane(); + public static void TagGameObjectScreenspace(Camera camera, GameObject gameObject, string text = null, Color colorForText = default(Color), Color colorForTagBox = default(Color), float linesWidth_relToViewportHeight = 0.0f, bool drawPointerIfOffscreen = true, float relTextSizeScaling = 1.0f, bool encapsulateChildren = true, float durationInSec = 0.0f) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(camera)) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(gameObject, "gameObject")) { return; } + + FillBounds(gameObject, encapsulateChildren, out Vector3 globalExtents, out Vector3 globalCenter, out bool rotateBoundingBox); + FillTagBoxOrientationVectors(gameObject, rotateBoundingBox, out Vector3 tagBoxUp, out Vector3 tagBoxForward); + + if (UtilitiesDXXL_Colors.IsDefaultColor(colorForText)) + { + colorForText = UtilitiesDXXL_Colors.Get_randomColorSeeded(gameObject.GetInstanceID()); + } + + if (UtilitiesDXXL_Colors.IsDefaultColor(colorForTagBox)) + { + colorForTagBox = UtilitiesDXXL_Colors.Get_randomColorSeeded(gameObject.GetInstanceID()); + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(globalExtents)) + { + UtilitiesDXXL_Screenspace.PointFallback(camera, gameObject.transform.position, "[ GameObject with extent of zero]
" + text, colorForTagBox, linesWidth_relToViewportHeight, durationInSec); + return; + } + + int usedSlotsIn_verticesGlobal = UtilitiesDXXL_Shapes.Cube(globalCenter, 2.0f * globalExtents, colorForTagBox, colorForTagBox, tagBoxUp, tagBoxForward, 0.0f, null, DrawBasics.LineStyle.disconnectedAnchors, 1.0f, false, durationInSec, false, true, null); + drawPlane.Recreate(camera.transform.position + camera.transform.forward * (camera.nearClipPlane + DrawScreenspace.drawOffsetBehindCamsNearPlane), camera.transform.forward); + + InternalDXXL_BoundsCamViewportSpace boundsViewportSpace_ofFrontOfCamVertices = null; + InternalDXXL_BoundsCamViewportSpace boundsViewportSpace_ofBackOfCamAndOutsideOrthoScreenCorridorVertices = null; + InternalDXXL_BoundsCamViewportSpace boundsViewportSpace_ofBackOfCamAndInsideOrthoScreenCorridorVertices = null; + + for (int i = 0; i < usedSlotsIn_verticesGlobal; i++) + { + if (drawPlane.CheckIf_twoPoints_lieOnDifferentSidesOfThePlane_returnsFalseIfAGivenPointIsONplane(camera.transform.position, UtilitiesDXXL_Shapes.verticesGlobal[i])) + { + //vertex in front of cam: + Vector2 vertex_viewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(camera, UtilitiesDXXL_Shapes.verticesGlobal[i], false); + InternalDXXL_BoundsCamViewportSpace.ConstructAndOrEncapsulate(ref boundsViewportSpace_ofFrontOfCamVertices, vertex_viewportSpace, false); + } + else + { + //vertex behind cam: + Vector3 vertex_perpProjectedOntoDrawPlane = drawPlane.Get_perpProjectionOfPointOnPlane(UtilitiesDXXL_Shapes.verticesGlobal[i]); + Vector2 vertex_viewportSpace = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(camera, vertex_perpProjectedOntoDrawPlane, false); + if (InternalDXXL_BoundsCamViewportSpace.IsInsideViewportInclBorder(vertex_viewportSpace)) + { + InternalDXXL_BoundsCamViewportSpace.ConstructAndOrEncapsulate(ref boundsViewportSpace_ofBackOfCamAndInsideOrthoScreenCorridorVertices, vertex_viewportSpace, false); + } + else + { + InternalDXXL_BoundsCamViewportSpace.ConstructAndOrEncapsulate(ref boundsViewportSpace_ofBackOfCamAndOutsideOrthoScreenCorridorVertices, vertex_viewportSpace, false); + } + } + } + + if (boundsViewportSpace_ofFrontOfCamVertices != null) + { + InternalDXXL_BoundsCamViewportSpace.ConstructAndOrEncapsulate(ref boundsViewportSpace_ofFrontOfCamVertices, boundsViewportSpace_ofBackOfCamAndOutsideOrthoScreenCorridorVertices, true); + InternalDXXL_BoundsCamViewportSpace.ConstructAndOrEncapsulate(ref boundsViewportSpace_ofFrontOfCamVertices, boundsViewportSpace_ofBackOfCamAndInsideOrthoScreenCorridorVertices, true); + } + else + { + if (boundsViewportSpace_ofBackOfCamAndOutsideOrthoScreenCorridorVertices != null) + { + Vector2 startPosOfOutsideCamBounds = InternalDXXL_BoundsCamViewportSpace.IsInsideViewportInclBorder(boundsViewportSpace_ofBackOfCamAndOutsideOrthoScreenCorridorVertices.center) ? InternalDXXL_BoundsCamViewportSpace.GetViewportCenterPlumbIntersectionWithViewportBorderShifted(boundsViewportSpace_ofBackOfCamAndOutsideOrthoScreenCorridorVertices.center, 0.01f) : boundsViewportSpace_ofBackOfCamAndOutsideOrthoScreenCorridorVertices.center; + boundsViewportSpace_ofFrontOfCamVertices = new InternalDXXL_BoundsCamViewportSpace(startPosOfOutsideCamBounds, Vector2.zero); + InternalDXXL_BoundsCamViewportSpace.ConstructAndOrEncapsulate(ref boundsViewportSpace_ofFrontOfCamVertices, boundsViewportSpace_ofBackOfCamAndOutsideOrthoScreenCorridorVertices, true); + InternalDXXL_BoundsCamViewportSpace.ConstructAndOrEncapsulate(ref boundsViewportSpace_ofFrontOfCamVertices, boundsViewportSpace_ofBackOfCamAndInsideOrthoScreenCorridorVertices, true); + } + else + { + boundsViewportSpace_ofFrontOfCamVertices = new InternalDXXL_BoundsCamViewportSpace(InternalDXXL_BoundsCamViewportSpace.GetViewportCenterPlumbIntersectionWithViewportBorderShifted(boundsViewportSpace_ofBackOfCamAndInsideOrthoScreenCorridorVertices.center, 0.01f), Vector2.zero); + } + } + + float height_relToViewportHeight = boundsViewportSpace_ofFrontOfCamVertices.yMax - boundsViewportSpace_ofFrontOfCamVertices.yMin; + float width_relToViewportWidth = (boundsViewportSpace_ofFrontOfCamVertices.xMax - boundsViewportSpace_ofFrontOfCamVertices.xMin); + float width_relToViewportHeight = width_relToViewportWidth * camera.aspect; + Vector2 boxCenterPos = boundsViewportSpace_ofFrontOfCamVertices.center; + if (boundsViewportSpace_ofFrontOfCamVertices.IsCompletelyOutsideViewport()) + { + if (drawPointerIfOffscreen == false) + { + return; + } + + height_relToViewportHeight = 0.001f; + width_relToViewportHeight = 0.001f; + boxCenterPos = InternalDXXL_BoundsCamViewportSpace.GetViewportCenterPlumbIntersectionWithViewportBorderShifted(boxCenterPos, 0.01f); + } + else + { + if (UtilitiesDXXL_Math.ApproximatelyZero(height_relToViewportHeight) && UtilitiesDXXL_Math.ApproximatelyZero(width_relToViewportWidth)) + { + UtilitiesDXXL_Screenspace.PointFallback(camera, boxCenterPos, "[ TagGameObjectScreenspace: Extent of gameobjects projection onto screen is zero]
" + text, colorForTagBox, linesWidth_relToViewportHeight, durationInSec); + return; + } + } + + bool addTextForOutsideDistance_toOffscreenPointer = false; //questionable if activating this would make sense, since this would display the 2D distance inside the camera plane. So gameObject that are far away (in 3D worldspace) could be displayed with the same small distance than GameOjects right beside the camera. + UtilitiesDXXL_Screenspace.DrawShape(camera, boxCenterPos, DrawShapes.Shape2DType.square, colorForTagBox, colorForText, width_relToViewportHeight, height_relToViewportHeight, 0.0f, linesWidth_relToViewportHeight, text, DrawBasics.LineStyle.disconnectedAnchors, 1.0f, DrawBasics.LineStyle.invisible, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, durationInSec, relTextSizeScaling, gameObject.name, true); + } + + public static void FillBounds(GameObject gameObject, bool encapsulateChildren, out Vector3 globalExtents, out Vector3 globalCenter, out bool rotateBoundingBox) + { + globalCenter = gameObject.transform.position; + rotateBoundingBox = true; + + Vector3 localExtents = 0.5f * Vector3.one; + MeshFilter meshfilter = gameObject.GetComponent(); + if (meshfilter != null) + { + if (Application.isPlaying) + { + if (meshfilter.mesh != null) + { + if (meshfilter.mesh.bounds != null) + { + localExtents = meshfilter.mesh.bounds.extents; + } + } + } + else + { + if (meshfilter.sharedMesh != null) + { + if (meshfilter.sharedMesh.bounds != null) + { + localExtents = meshfilter.sharedMesh.bounds.extents; + } + } + } + } + + SkinnedMeshRenderer skinnedMeshRenderer = gameObject.GetComponent(); + if (skinnedMeshRenderer != null) + { + if (skinnedMeshRenderer.localBounds != null) + { + //-> acts only as a fallback for the unexpected (or impossible?) case where a SkinnedMeshRenderer has ".localBounds", but no ".bounds". If it has ".bounds" this will get overwritten below + localExtents = skinnedMeshRenderer.localBounds.extents; + } + } + + globalExtents = Vector3.Scale(localExtents, gameObject.transform.lossyScale); + + if ((encapsulateChildren == false) || gameObject.transform.childCount == 0) + { + MeshRenderer meshRenderer = gameObject.GetComponent(); + if (meshRenderer != null) + { + if (meshRenderer.bounds != null) + { + globalCenter = meshRenderer.bounds.center; + } + } + + if (skinnedMeshRenderer != null) + { + if (skinnedMeshRenderer.bounds != null) + { + //-> if you want to see the local bounds box of a SkinnedMeshRenderer: Use "EngineBasics.LocalBounds()" instead + rotateBoundingBox = false; + globalCenter = skinnedMeshRenderer.bounds.center; + globalExtents = skinnedMeshRenderer.bounds.extents; + } + } + } + else + { + rotateBoundingBox = false; + Bounds boundsOfWholeChildHierarchyGlobal = new Bounds(gameObject.transform.position, gameObject.transform.lossyScale); + foreach (Transform childTransform in gameObject.GetComponentsInChildren()) + { + Bounds childTranformBoundsGlobal = new Bounds(childTransform.position, childTransform.lossyScale); + boundsOfWholeChildHierarchyGlobal.Encapsulate(childTranformBoundsGlobal); + + MeshRenderer childsMeshRenderer = childTransform.GetComponent(); + if (childsMeshRenderer != null) + { + if (childsMeshRenderer.bounds != null) + { + boundsOfWholeChildHierarchyGlobal.Encapsulate(childsMeshRenderer.bounds); //"MeshRenderer" delivers GLOBAL bounds + } + } + + SkinnedMeshRenderer childsSkinnedMeshRenderer = childTransform.GetComponent(); + if (childsSkinnedMeshRenderer != null) + { + if (childsSkinnedMeshRenderer.bounds != null) + { + boundsOfWholeChildHierarchyGlobal.Encapsulate(childsSkinnedMeshRenderer.bounds); //"skinnedMeshRenderer.bounds" delivers GLOBAL bounds + } + } + } + globalExtents = boundsOfWholeChildHierarchyGlobal.extents; + globalCenter = boundsOfWholeChildHierarchyGlobal.center; + } + } + + public static void FillTagBoxOrientationVectors(GameObject gameObject, bool rotateBoundingBox, out Vector3 tagBoxUp, out Vector3 tagBoxForward) + { + if (rotateBoundingBox) + { + tagBoxUp = gameObject.transform.up; + tagBoxForward = gameObject.transform.forward; + } + else + { + tagBoxUp = Vector3.up; + tagBoxForward = Vector3.forward; + } + } + + public static void BoolDisplayer(bool boolValueToDisplay, Vector3 position = default(Vector3), string boolName = null, float size = 1.0f, Quaternion rotation = default(Quaternion), Color color_forTextAndFrame = default(Color), Color overwriteColor_forTrue = default(Color), Color overwriteColor_forFalse = default(Color), float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size, "size")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + + + if (UtilitiesDXXL_Math.ApproximatelyZero(size)) + { + Color color_forTrue = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forTrue, UtilitiesDXXL_Colors.green_boolTrue); + Color color_forFalse = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forFalse, UtilitiesDXXL_Colors.red_boolFalse); + UtilitiesDXXL_DrawBasics.PointFallback(position, "[ BoolDisplayer with extent of 0]
" + boolName, boolValueToDisplay ? color_forTrue : color_forFalse, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + rotation = UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetQuaternion(rotation, position); + color_forTextAndFrame = UtilitiesDXXL_Colors.OverwriteDefaultColor(color_forTextAndFrame); + size = Mathf.Abs(size); + + string boolTrafficLightAsText = GetBoolTrafficLightAsText(boolValueToDisplay, overwriteColor_forTrue, overwriteColor_forFalse); + string headlineText = "unnamed bool:"; + if (boolName != null && boolName != "") + { + headlineText = "" + boolName + ":"; + } + + float autoLineBreakWidth = 0.86f * size; + float halfSize = 0.5f * size; + Vector3 textDir_normalized = rotation * Vector3.right; + Vector3 up_normalized = rotation * Vector3.up; + + UtilitiesDXXL_Text.Write(headlineText, position, color_forTextAndFrame, 0.0859f * size, textDir_normalized, up_normalized, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, autoLineBreakWidth, 0.0f, autoLineBreakWidth, true, durationInSec, hiddenByNearerObjects, false, false, true); + float height_wholeTextBlock_ofHeadlineText = DrawText.parsedTextSpecs.height_wholeTextBlock; + UtilitiesDXXL_Text.Write(boolTrafficLightAsText, position - up_normalized * halfSize, color_forTextAndFrame, size, textDir_normalized, up_normalized, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + + float rectHeight = halfSize + height_wholeTextBlock_ofHeadlineText; + float rectWidth = size; + Vector3 rectCenter = position + up_normalized * (-halfSize + 0.5f * rectHeight); + Vector3 forward_normalized = rotation * Vector3.forward; + DrawShapes.FlatShape(rectCenter, DrawShapes.Shape2DType.square, rectWidth, rectHeight, color_forTextAndFrame, forward_normalized, up_normalized, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, true, DrawBasics.LineStyle.invisible, false, durationInSec, hiddenByNearerObjects); + } + + static List screenspaceBoolDisplayNames = new List(); + public static void BoolDisplayerScreenspace(Camera camera, bool boolValueToDisplay, string boolName = null, Vector2 position = default(Vector2), float size_relToViewportHeight = 0.175f, Color color_forTextAndFrame = default(Color), Color overwriteColor_forTrue = default(Color), Color overwriteColor_forFalse = default(Color), float durationInSec = 0.0f) + { + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(camera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size_relToViewportHeight, "size_relToViewportHeight")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + + + if (UtilitiesDXXL_Math.ApproximatelyZero(size_relToViewportHeight)) + { + Color color_forTrue = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forTrue, UtilitiesDXXL_Colors.green_boolTrue); + Color color_forFalse = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forFalse, UtilitiesDXXL_Colors.red_boolFalse); + UtilitiesDXXL_Screenspace.PointFallback(camera, position, "[ BoolDisplayerScreenspace with extent of 0]
" + boolName, boolValueToDisplay ? color_forTrue : color_forFalse, 0.0f, durationInSec); + return; + } + + color_forTextAndFrame = UtilitiesDXXL_Colors.OverwriteDefaultColor(color_forTextAndFrame); + size_relToViewportHeight = Mathf.Abs(size_relToViewportHeight); + float halfSize_relToViewportHeight = 0.5f * size_relToViewportHeight; + float size_relToViewportWidth = size_relToViewportHeight / camera.aspect; + + string headlineText; + if (boolName != null && boolName != "") + { + if (UtilitiesDXXL_Math.IsDefaultVector(position)) + { + float initialXPos = 0.7f * size_relToViewportWidth; + float initialYPos = 0.888f; + float xDistance = size_relToViewportWidth * 1.25f; + float yDistance = 0.195f; + float halfYDistance = 0.5f * yDistance; + + position = new Vector2(initialXPos, initialYPos); + bool nameIsAlreadyRegistered = false; + for (int i = 0; i < screenspaceBoolDisplayNames.Count; i++) + { + if (boolName == screenspaceBoolDisplayNames[i]) + { + nameIsAlreadyRegistered = true; + break; + } + else + { + position.y = position.y - yDistance; + if (position.y < halfYDistance) + { + position.x = position.x + xDistance; + position.y = initialYPos; + } + } + } + + if (nameIsAlreadyRegistered == false) + { + screenspaceBoolDisplayNames.Add(boolName); + } + + } + headlineText = "" + boolName + ":"; + } + else + { + if (UtilitiesDXXL_Math.IsDefaultVector(position)) + { + headlineText = "bool without name or pos*
*no auto positioning
*danger of overlay"; + position = new Vector2(1.0f - 0.7f * size_relToViewportWidth, 0.125f); + } + else + { + headlineText = "unnamed bool:"; + } + } + + string boolTrafficLightAsText = GetBoolTrafficLightAsText(boolValueToDisplay, overwriteColor_forTrue, overwriteColor_forFalse); + float autoLineBreakWidth_relToViewportWidth = 0.86f * size_relToViewportWidth; + UtilitiesDXXL_Text.WriteScreenspace(camera, headlineText, position, color_forTextAndFrame, 0.0859f * size_relToViewportHeight, 0.0f, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, autoLineBreakWidth_relToViewportWidth, 0.0f, false, autoLineBreakWidth_relToViewportWidth, true, durationInSec, false); + float height_wholeTextBlock_ofHeadlineText = DrawText.parsedTextSpecs.height_wholeTextBlock; + UtilitiesDXXL_Text.WriteScreenspace(camera, boolTrafficLightAsText, position - Vector2.up * halfSize_relToViewportHeight, color_forTextAndFrame, size_relToViewportHeight, 0.0f, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, false, 0.0f, true, durationInSec, false); + + float rectHeight_relToViewportHeight = halfSize_relToViewportHeight + height_wholeTextBlock_ofHeadlineText; + Vector2 rectCenter = position + Vector2.up * (-halfSize_relToViewportHeight + 0.5f * rectHeight_relToViewportHeight); + DrawScreenspace.Shape(camera, rectCenter, DrawShapes.Shape2DType.square, color_forTextAndFrame, size_relToViewportHeight, rectHeight_relToViewportHeight, 0.0f, 0.0f, null, false, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, durationInSec); + } + + static string GetBoolTrafficLightAsText(bool boolValueToDisplay, Color overwriteColor_forTrue, Color overwriteColor_forFalse) + { + if (UtilitiesDXXL_Colors.IsDefaultColor(overwriteColor_forTrue) && UtilitiesDXXL_Colors.IsDefaultColor(overwriteColor_forFalse)) + { + if (boolValueToDisplay) + { + return ""; + } + else + { + return ""; + } + } + else + { + if (boolValueToDisplay) + { + return ""; + } + else + { + return ""; + } + } + } + + public static void CoordinateAxesGizmoLocal(Vector3 position_OfLocalCoordinateSystem, Quaternion rotation_OfLocalCoordinateSystem, Vector3 scale_OfLocalCoordinateSystem, float forceAllAxesLength, float lineWidth_inGlobalUnits, string text, bool drawXYZchars, bool skipConeDrawing, float durationInSec, bool hiddenByNearerObjects, bool aParentHasANonUniformScale) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position_OfLocalCoordinateSystem, "position_OfLocalCoordinateSystem")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(scale_OfLocalCoordinateSystem, "scale_OfLocalCoordinateSystem")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(forceAllAxesLength, "forceAllAxesLength")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth_inGlobalUnits, "linesWidth")) { return; } + + rotation_OfLocalCoordinateSystem = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotation_OfLocalCoordinateSystem); + + if (UtilitiesDXXL_Math.IsDefaultVector(scale_OfLocalCoordinateSystem)) { scale_OfLocalCoordinateSystem = Vector3.one; } + if (UtilitiesDXXL_Math.ApproximatelyZero(forceAllAxesLength) == false) { scale_OfLocalCoordinateSystem = new Vector3(forceAllAxesLength, forceAllAxesLength, forceAllAxesLength); } + + float enlargeSmallTextToThisMinTextSize_x = 0.25f * scale_OfLocalCoordinateSystem.x; + float enlargeSmallTextToThisMinTextSize_y = 0.25f * scale_OfLocalCoordinateSystem.y; + float enlargeSmallTextToThisMinTextSize_z = 0.25f * scale_OfLocalCoordinateSystem.z; + string text_x; + string text_y; + string text_z; + float lineWidth_x = lineWidth_inGlobalUnits; + float lineWidth_y = lineWidth_inGlobalUnits; + float lineWidth_z = lineWidth_inGlobalUnits; + bool skipsPointer_x = skipConeDrawing; + bool skipsPointer_y = skipConeDrawing; + bool skipsPointer_z = skipConeDrawing; + + if (UtilitiesDXXL_Math.ApproximatelyZero(scale_OfLocalCoordinateSystem.x)) + { + text_x = " X axis has

zero length"; + lineWidth_x = 0.0f; + scale_OfLocalCoordinateSystem.x = 1.0f; + skipsPointer_x = true; + enlargeSmallTextToThisMinTextSize_x = 0.0f; + } + else + { + text_x = drawXYZchars ? "X" : null; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(scale_OfLocalCoordinateSystem.y)) + { + text_y = " Y axis has

zero length"; + lineWidth_y = 0.0f; + scale_OfLocalCoordinateSystem.y = 1.0f; + skipsPointer_y = true; + enlargeSmallTextToThisMinTextSize_y = 0.0f; + } + else + { + text_y = drawXYZchars ? "Y" : null; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(scale_OfLocalCoordinateSystem.z)) + { + text_z = " Z axis has

zero length"; + lineWidth_z = 0.0f; + scale_OfLocalCoordinateSystem.z = 1.0f; + skipsPointer_z = true; + enlargeSmallTextToThisMinTextSize_z = 0.0f; + } + else + { + text_z = drawXYZchars ? "Z" : null; + } + + Vector3 vector_xAxis_normalized = rotation_OfLocalCoordinateSystem * Vector3.right; + Vector3 vector_yAxis_normalized = rotation_OfLocalCoordinateSystem * Vector3.up; + Vector3 vector_zAxis_normalized = rotation_OfLocalCoordinateSystem * Vector3.forward; + Vector3 vector_xAxis = vector_xAxis_normalized * scale_OfLocalCoordinateSystem.x; + Vector3 vector_yAxis = vector_yAxis_normalized * scale_OfLocalCoordinateSystem.y; + Vector3 vector_zAxis = vector_zAxis_normalized * scale_OfLocalCoordinateSystem.z; + + Vector3 customAmplitudeAndTextDir_x = vector_yAxis_normalized; + Vector3 customAmplitudeAndTextDir_y = (-vector_xAxis_normalized); + Vector3 customAmplitudeAndTextDir_z = vector_yAxis_normalized; + + //-> y is drawn last, because there are probably more cases where the user looks at the gizmo from camPosHigherThanGizmo...and then the y axis shouldn't be hidden by the other axes (only significant for nonZero-lineWidthes) + //-> same reason: x is drawn after z, because the view dir may be mostly along positive z + //-> could be refactored similar to "UtilitiesDXXL_Euler.EulerRotation_local()" where the observer camera is taken into account + + if (skipsPointer_z) + { + Line_fadeableAnimSpeed.InternalDraw(position_OfLocalCoordinateSystem, position_OfLocalCoordinateSystem + vector_zAxis, UtilitiesDXXL_Colors.blue_zAxisAlpha1, lineWidth_z, text_z, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, customAmplitudeAndTextDir_z, false, 0.0f, 0.0f, enlargeSmallTextToThisMinTextSize_z, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorFrom(position_OfLocalCoordinateSystem, vector_zAxis, UtilitiesDXXL_Colors.blue_zAxisAlpha1, lineWidth_z, text_z, 0.17f, false, false, customAmplitudeAndTextDir_z, false, enlargeSmallTextToThisMinTextSize_z, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + if (skipsPointer_x) + { + Line_fadeableAnimSpeed.InternalDraw(position_OfLocalCoordinateSystem, position_OfLocalCoordinateSystem + vector_xAxis, UtilitiesDXXL_Colors.red_xAxisAlpha1, lineWidth_x, text_x, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, customAmplitudeAndTextDir_x, false, 0.0f, 0.0f, enlargeSmallTextToThisMinTextSize_x, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorFrom(position_OfLocalCoordinateSystem, vector_xAxis, UtilitiesDXXL_Colors.red_xAxisAlpha1, lineWidth_x, text_x, 0.17f, false, false, customAmplitudeAndTextDir_x, false, enlargeSmallTextToThisMinTextSize_x, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + if (skipsPointer_y) + { + Line_fadeableAnimSpeed.InternalDraw(position_OfLocalCoordinateSystem, position_OfLocalCoordinateSystem + vector_yAxis, UtilitiesDXXL_Colors.green_yAxisAlpha1, lineWidth_y, text_y, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, customAmplitudeAndTextDir_y, false, 0.0f, 0.0f, enlargeSmallTextToThisMinTextSize_y, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorFrom(position_OfLocalCoordinateSystem, vector_yAxis, UtilitiesDXXL_Colors.green_yAxisAlpha1, lineWidth_y, text_y, 0.17f, false, false, customAmplitudeAndTextDir_y, false, enlargeSmallTextToThisMinTextSize_y, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_inGlobalUnits) == false) + { + int struts = 8; + float radius = 0.5f * lineWidth_inGlobalUnits; + DrawShapes.Sphere(position_OfLocalCoordinateSystem, radius, Color.white, rotation_OfLocalCoordinateSystem, 0.0f, null, struts, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + } + + if (aParentHasANonUniformScale) + { + text = "[ A parent transform that defines the local space has a non-uniform scale
-> possibly weird results]
" + text; + } + + if (text != null && text != "") + { + float averageScale_ofLocalCoordinateSystem = 0.33333f * (scale_OfLocalCoordinateSystem.x + scale_OfLocalCoordinateSystem.y + scale_OfLocalCoordinateSystem.z); + float textSize = Mathf.Max(0.1f * averageScale_ofLocalCoordinateSystem, 0.01f); + UtilitiesDXXL_Text.WriteFramed(text, position_OfLocalCoordinateSystem, Color.white, textSize, default(Vector3), default(Vector3), DrawText.TextAnchorDXXL.UpperRight, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_EngineBasics.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_EngineBasics.cs.meta new file mode 100644 index 0000000..575a0f5 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_EngineBasics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7952804557b49c479cf1004a34e5174 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Euler.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Euler.cs new file mode 100644 index 0000000..4bda788 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Euler.cs @@ -0,0 +1,959 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_Euler + { + static float eulerAxes_relLineWidth = 0.03f; + static float eulerAxesTurnAngleVisualizer_relLineWidth = 0.006f; + static float relRadius_ofSpheres = 0.07f; + static float stripeSizeFactor_forGimbelLocksAlternatingColorLine = 0.08f; + static float relRadius_ofAxisTurnAngleVisualizer = 0.15f; + static InternalDXXL_Line rotatedXAxis_line_inGlobalSpaceUnits = new InternalDXXL_Line(); + static InternalDXXL_Line rotatedYAxis_line_inGlobalSpaceUnits = new InternalDXXL_Line(); + static InternalDXXL_Line rotatedZAxis_line_inGlobalSpaceUnits = new InternalDXXL_Line(); + static float angleDeg_betweenTurnedCircleSlice_visualizerLines = 2.912347f; + static float approxLength_ofShortestTurnedVectorThatIsDrawn = 0.01f; + + public static Vector3 GetEulerAnglesFromNonNullTransform(Transform transform, bool useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay, bool useLocalRotation_notGlobal) + { + if (useAnglesFromQuaternion_notFromEditorsTransformInspectorDisplay) + { + return GetEulerAnglesFromNonNullTransform_asReturnedByAPIcalls_notAsShownInInspector(transform, useLocalRotation_notGlobal); + } + else + { +#if UNITY_EDITOR + //"useLocalRotation_notGlobal": The caller has to handle the case where global angles are requested, because this always returns local angles. + return UnityEditor.TransformUtils.GetInspectorRotation(transform); //this returns the local eulerAngles. The angles that are displayed in the transform inspector are local angels. +#else + return GetEulerAnglesFromNonNullTransform_asReturnedByAPIcalls_notAsShownInInspector(transform, useLocalRotation_notGlobal); +#endif + } + } + + static Vector3 GetEulerAnglesFromNonNullTransform_asReturnedByAPIcalls_notAsShownInInspector(Transform transform, bool useLocalRotation_notGlobal) + { + if (useLocalRotation_notGlobal) + { + return transform.localEulerAngles; + } + else + { + return transform.eulerAngles; + } + } + + public static void EulerRotation_local(Vector3 eulerAnglesToDraw, Vector3 posWhereToDraw, Vector3 customVectorToRotate_local, float length_ofUpAndForwardVectors_local, float alpha_ofSquareSpannedByForwardAndUp, float alpha_ofUnrotatedGimbalAxes, float gimbalSize, string text, bool isLocal, float durationInSec, bool hiddenByNearerObjects, Transform parentTransform) + { + //-> The order of drawing of the individual elements inside this function has effect on the readability of the gimbal + //-> This is because the spacial state of the gimbal is comprehended by the question "which axis is in front?" + //-> The z-ordering of "Debug.DrawLine()" works like this: Later calls are in front + //-> So which axes are drawn "last(=on top of all others)" is dependent on the observer direction. That's why this function is dependent on "DrawBasics.cameraForAutomaticOrientation" + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(length_ofUpAndForwardVectors_local, "length_ofUpAndForwardVectors")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(alpha_ofSquareSpannedByForwardAndUp, "alpha_ofSquareSpannedByForwardAndUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(gimbalSize, "gimbalSize")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(alpha_ofUnrotatedGimbalAxes, "alpha_ofUnrotatedGimbalAxes")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(eulerAnglesToDraw, "eulerAnglesToDraw")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(posWhereToDraw, "posWhereToDraw")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(customVectorToRotate_local, "customVectorToRotate")) { return; } + + //"gimbalSize" of 1 means: gimbalAxes are 1 unit long to each side, so 2 units in total. + gimbalSize = Mathf.Max(gimbalSize, 0.01f); + + + Quaternion rotation_ofLocalSpace = (parentTransform == null) ? Quaternion.identity : parentTransform.rotation; + + + + //The following declaration blocks are sometimes ordered "x -> y -> z" (default) and sometimes "y -> x -> z" (main axis to most dependent axis): + + //Note that "normalized in local space" is the same as "normalized in global space", because scale_ofSpaces is not used here: + Vector3 yAxis_unrotated_inLocalSpace_normalized = Vector3.up; + Vector3 xAxis_unrotated_inLocalSpace_normalized = Vector3.right; + Vector3 zAxis_unrotated_inLocalSpace_normalized = Vector3.forward; + + Quaternion eulerRotationAroundYAxis = Quaternion.AngleAxis(eulerAnglesToDraw.y, yAxis_unrotated_inLocalSpace_normalized); + Quaternion eulerRotationAroundXAxis = Quaternion.AngleAxis(eulerAnglesToDraw.x, xAxis_unrotated_inLocalSpace_normalized); + Quaternion eulerRotationAroundZAxis = Quaternion.AngleAxis(eulerAnglesToDraw.z, zAxis_unrotated_inLocalSpace_normalized); + + Vector3 yAxis_rotated_inLocalSpace_normalized = yAxis_unrotated_inLocalSpace_normalized; + Vector3 xAxis_rotated_inLocalSpace_normalized = eulerRotationAroundYAxis * xAxis_unrotated_inLocalSpace_normalized; + Vector3 zAxis_rotated_inLocalSpace_normalized = eulerRotationAroundYAxis * eulerRotationAroundXAxis * zAxis_unrotated_inLocalSpace_normalized; + + Vector3 zAxis_rotatedOnlyAroundY_inLocalSpace_normalized = eulerRotationAroundYAxis * zAxis_unrotated_inLocalSpace_normalized; + + Vector3 yAxis_rotated_inGlobalSpace_normalized = rotation_ofLocalSpace * yAxis_rotated_inLocalSpace_normalized; + Vector3 xAxis_rotated_inGlobalSpace_normalized = rotation_ofLocalSpace * xAxis_rotated_inLocalSpace_normalized; + Vector3 zAxis_rotated_inGlobalSpace_normalized = rotation_ofLocalSpace * zAxis_rotated_inLocalSpace_normalized; + + Vector3 xAxis_unrotated_inGlobalSpace_normalized = rotation_ofLocalSpace * xAxis_unrotated_inLocalSpace_normalized; + Vector3 zAxis_unrotated_inGlobalSpace_normalized = rotation_ofLocalSpace * zAxis_unrotated_inLocalSpace_normalized; + + Vector3 zAxis_rotatedOnlyAroundY_inGlobalSpace_normalized = rotation_ofLocalSpace * zAxis_rotatedOnlyAroundY_inLocalSpace_normalized; + + Vector3 fromDrawCenterPos_toYAxisPeak_inGlobalSpace = gimbalSize * yAxis_rotated_inGlobalSpace_normalized; + Vector3 fromDrawCenterPos_toXAxisPeak_inGlobalSpace = gimbalSize * xAxis_rotated_inGlobalSpace_normalized; + Vector3 fromDrawCenterPos_toZAxisPeak_inGlobalSpace = gimbalSize * zAxis_rotated_inGlobalSpace_normalized; + + Vector3 fromDrawCenterPos_toXAxisUnrotatedPeak_inGlobalSpace = gimbalSize * xAxis_unrotated_inGlobalSpace_normalized; + Vector3 fromDrawCenterPos_toZAxisUnrotatedPeak_inGlobalSpace = gimbalSize * zAxis_unrotated_inGlobalSpace_normalized; + + Vector3 fromDrawCenterPos_toZAxisRotatedOnlyAroundYPeak_inGlobalSpace = gimbalSize * zAxis_rotatedOnlyAroundY_inGlobalSpace_normalized; + + Vector3 xAxis_startPos_inGlobalSpace = posWhereToDraw - fromDrawCenterPos_toXAxisPeak_inGlobalSpace; + Vector3 xAxis_endPos_inGlobalSpace = posWhereToDraw + fromDrawCenterPos_toXAxisPeak_inGlobalSpace; + + Vector3 yAxis_startPos_inGlobalSpace = posWhereToDraw - fromDrawCenterPos_toYAxisPeak_inGlobalSpace; + Vector3 yAxis_endPos_inGlobalSpace = posWhereToDraw + fromDrawCenterPos_toYAxisPeak_inGlobalSpace; + + Vector3 zAxis_startPos_inGlobalSpace = posWhereToDraw - fromDrawCenterPos_toZAxisPeak_inGlobalSpace; + Vector3 zAxis_endPos_inGlobalSpace = posWhereToDraw + fromDrawCenterPos_toZAxisPeak_inGlobalSpace; + + Vector3 xAxisUnrotated_startPos_inGlobalSpace = posWhereToDraw - fromDrawCenterPos_toXAxisUnrotatedPeak_inGlobalSpace; + Vector3 xAxisUnrotated_endPos_inGlobalSpace = posWhereToDraw + fromDrawCenterPos_toXAxisUnrotatedPeak_inGlobalSpace; + Vector3 xAxisUnrotatedShortened_endPos_inGlobalSpace = posWhereToDraw + fromDrawCenterPos_toXAxisUnrotatedPeak_inGlobalSpace * 0.328f; + + Vector3 zAxisUnrotated_startPos_inGlobalSpace = posWhereToDraw - fromDrawCenterPos_toZAxisUnrotatedPeak_inGlobalSpace; + Vector3 zAxisUnrotated_endPos_inGlobalSpace = posWhereToDraw + fromDrawCenterPos_toZAxisUnrotatedPeak_inGlobalSpace; + Vector3 zAxisUnrotatedShortened_endPos_inGlobalSpace = posWhereToDraw + fromDrawCenterPos_toZAxisUnrotatedPeak_inGlobalSpace * 0.355f; + + Vector3 zAxisRotatedOnlyAroundYShortened_endPos_inGlobalSpace = posWhereToDraw + fromDrawCenterPos_toZAxisRotatedOnlyAroundYPeak_inGlobalSpace * 0.3575f; + + Vector3 perpToYAxis_markingYAxisZeroTurnAngle_unrotated_inLocalSpace_normalized = Vector3.forward; + Vector3 perpToXAxis_markingXAxisZeroTurnAngle_unrotated_inLocalSpace_normalized = Vector3.up; + Vector3 perpToZAxis_markingZAxisZeroTurnAngle_unrotated_inLocalSpace_normalized = Vector3.up; + + Vector3 perpToYAxis_markingYAxisEndTurnAngle_unrotated_inLocalSpace_normalized = eulerRotationAroundYAxis * perpToYAxis_markingYAxisZeroTurnAngle_unrotated_inLocalSpace_normalized; + Vector3 perpToXAxis_markingXAxisEndTurnAngle_unrotated_inLocalSpace_normalized = eulerRotationAroundXAxis * perpToXAxis_markingXAxisZeroTurnAngle_unrotated_inLocalSpace_normalized; + Vector3 perpToZAxis_markingZAxisEndTurnAngle_unrotated_inLocalSpace_normalized = eulerRotationAroundZAxis * perpToZAxis_markingZAxisZeroTurnAngle_unrotated_inLocalSpace_normalized; + + Vector3 perpToYAxis_markingYAxisZeroTurnAngle_rotated_inLocalSpace_normalized = perpToYAxis_markingYAxisZeroTurnAngle_unrotated_inLocalSpace_normalized; + Vector3 perpToXAxis_markingXAxisZeroTurnAngle_rotated_inLocalSpace_normalized = eulerRotationAroundYAxis * perpToXAxis_markingXAxisZeroTurnAngle_unrotated_inLocalSpace_normalized; + Vector3 perpToZAxis_markingZAxisZeroTurnAngle_rotated_inLocalSpace_normalized = eulerRotationAroundYAxis * eulerRotationAroundXAxis * perpToZAxis_markingZAxisZeroTurnAngle_unrotated_inLocalSpace_normalized; + + Vector3 perpToYAxis_markingYAxisEndTurnAngle_rotated_inLocalSpace_normalized = perpToYAxis_markingYAxisEndTurnAngle_unrotated_inLocalSpace_normalized; + Vector3 perpToXAxis_markingXAxisEndTurnAngle_rotated_inLocalSpace_normalized = eulerRotationAroundYAxis * perpToXAxis_markingXAxisEndTurnAngle_unrotated_inLocalSpace_normalized; + Vector3 perpToZAxis_markingZAxisEndTurnAngle_rotated_inLocalSpace_normalized = eulerRotationAroundYAxis * eulerRotationAroundXAxis * perpToZAxis_markingZAxisEndTurnAngle_unrotated_inLocalSpace_normalized; + + Vector3 perpToYAxis_markingYAxisZeroTurnAngle_rotated_inGlobalSpace_normalized = rotation_ofLocalSpace * perpToYAxis_markingYAxisZeroTurnAngle_rotated_inLocalSpace_normalized; + Vector3 perpToXAxis_markingXAxisZeroTurnAngle_rotated_inGlobalSpace_normalized = rotation_ofLocalSpace * perpToXAxis_markingXAxisZeroTurnAngle_rotated_inLocalSpace_normalized; + Vector3 perpToZAxis_markingZAxisZeroTurnAngle_rotated_inGlobalSpace_normalized = rotation_ofLocalSpace * perpToZAxis_markingZAxisZeroTurnAngle_rotated_inLocalSpace_normalized; + + Vector3 perpToYAxis_markingYAxisEndTurnAngle_rotated_inGlobalSpace_normalized = rotation_ofLocalSpace * perpToYAxis_markingYAxisEndTurnAngle_rotated_inLocalSpace_normalized; + Vector3 perpToXAxis_markingXAxisEndTurnAngle_rotated_inGlobalSpace_normalized = rotation_ofLocalSpace * perpToXAxis_markingXAxisEndTurnAngle_rotated_inLocalSpace_normalized; + Vector3 perpToZAxis_markingZAxisEndTurnAngle_rotated_inGlobalSpace_normalized = rotation_ofLocalSpace * perpToZAxis_markingZAxisEndTurnAngle_rotated_inLocalSpace_normalized; + + float lineWidth_ofAxes = eulerAxes_relLineWidth * gimbalSize; + float radius_ofSpheres = relRadius_ofSpheres * gimbalSize; + float diameter_ofSpheres = 2.0f * radius_ofSpheres; + float radius_ofYAxisHolderRing = diameter_ofSpheres; + float absConeLength = 0.20f * gimbalSize; + Vector3 normalOfYAxisHolderRing = Vector3.Cross(yAxis_rotated_inGlobalSpace_normalized, xAxis_rotated_inGlobalSpace_normalized); + float angleDeg_ofHalfYAxisHolderRingSegment = 64.0f; + + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_posWhereToDraw, posWhereToDraw, Vector3.zero, null); + + bool isInGimbalLock = UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(yAxis_rotated_inGlobalSpace_normalized, zAxis_rotated_inGlobalSpace_normalized); + + bool xAxis_pointsAwayFromObserverCam = UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(observerCamForward_normalized, xAxis_rotated_inGlobalSpace_normalized); + bool yAxis_pointsAwayFromObserverCam = UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(observerCamForward_normalized, yAxis_rotated_inGlobalSpace_normalized); + bool zAxis_pointsAwayFromObserverCam = UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(observerCamForward_normalized, zAxis_rotated_inGlobalSpace_normalized); + + Vector3 vector_parallelToTurnedYAxis_dirIsTowardsObserverCam_normalized = yAxis_pointsAwayFromObserverCam ? (-yAxis_rotated_inGlobalSpace_normalized) : yAxis_rotated_inGlobalSpace_normalized; + Vector3 vector_parallelToTurnedZAxis_dirIsTowardsObserverCam_normalized = zAxis_pointsAwayFromObserverCam ? (-zAxis_rotated_inGlobalSpace_normalized) : zAxis_rotated_inGlobalSpace_normalized; + + Vector3 aRefVector_perpToXAxis_perpToObserverViewDir = Vector3.Cross(xAxis_rotated_inGlobalSpace_normalized, cam_to_posWhereToDraw); + aRefVector_perpToXAxis_perpToObserverViewDir = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(aRefVector_perpToXAxis_perpToObserverViewDir); + + float dotProduct_ofYAxisFlippedTowardsCam_and_refVectorPerpToXAxisAndCamViewDir = Vector3.Dot(vector_parallelToTurnedYAxis_dirIsTowardsObserverCam_normalized, aRefVector_perpToXAxis_perpToObserverViewDir); + float dotProduct_ofZAxisFlippedTowardsCam_and_refVectorPerpToXAxisAndCamViewDir = Vector3.Dot(vector_parallelToTurnedZAxis_dirIsTowardsObserverCam_normalized, aRefVector_perpToXAxis_perpToObserverViewDir); + + bool theTowardsCamPointingPartOf_YAndZAxis_appearOnTheSameSideOfTheXAxis = Mathf.Sign(dotProduct_ofYAxisFlippedTowardsCam_and_refVectorPerpToXAxisAndCamViewDir) == Mathf.Sign(dotProduct_ofZAxisFlippedTowardsCam_and_refVectorPerpToXAxisAndCamViewDir); + bool theTowardsCamPointingPartOf_yAxis_isNearerToObserverCam_thanTheTowardsCamPointingPartOf_zAxis; + bool theAwayFromCamPointingPartOf_yAxis_isNearerToObserverCam_thanTheAwayFromCamPointingPartOf_zAxis; + + if (theTowardsCamPointingPartOf_YAndZAxis_appearOnTheSameSideOfTheXAxis) + { + float dotProduct_ofYAxisFlippedTowardsCam_and_inverseCamViewDir = Vector3.Dot(vector_parallelToTurnedYAxis_dirIsTowardsObserverCam_normalized, (-cam_to_posWhereToDraw)); + float dotProduct_ofZAxisFlippedTowardsCam_and_inverseCamViewDir = Vector3.Dot(vector_parallelToTurnedZAxis_dirIsTowardsObserverCam_normalized, (-cam_to_posWhereToDraw)); + if (dotProduct_ofYAxisFlippedTowardsCam_and_inverseCamViewDir > dotProduct_ofZAxisFlippedTowardsCam_and_inverseCamViewDir) + { + theTowardsCamPointingPartOf_yAxis_isNearerToObserverCam_thanTheTowardsCamPointingPartOf_zAxis = true; + theAwayFromCamPointingPartOf_yAxis_isNearerToObserverCam_thanTheAwayFromCamPointingPartOf_zAxis = false; + } + else + { + theTowardsCamPointingPartOf_yAxis_isNearerToObserverCam_thanTheTowardsCamPointingPartOf_zAxis = false; + theAwayFromCamPointingPartOf_yAxis_isNearerToObserverCam_thanTheAwayFromCamPointingPartOf_zAxis = true; + } + } + else + { + //theTowardsCamPointingPartOf_YAndZAxis_appearOn-DIFFERENT-sidesOfTheXAxis: + //-> the "towardsCamPointing"-parts and also the "awayPointing"-parts of y and z both cannot overlap each other + //-> no z-fighting + //-> no correction neccessary + + //will not get used: + theTowardsCamPointingPartOf_yAxis_isNearerToObserverCam_thanTheTowardsCamPointingPartOf_zAxis = true; + theAwayFromCamPointingPartOf_yAxis_isNearerToObserverCam_thanTheAwayFromCamPointingPartOf_zAxis = false; + } + + TryDrawUnrotatedXAndZAxis(alpha_ofUnrotatedGimbalAxes, posWhereToDraw, xAxisUnrotated_startPos_inGlobalSpace, xAxisUnrotated_endPos_inGlobalSpace, zAxisUnrotated_startPos_inGlobalSpace, zAxisUnrotated_endPos_inGlobalSpace, xAxis_rotated_inGlobalSpace_normalized, yAxis_rotated_inGlobalSpace_normalized, xAxisUnrotatedShortened_endPos_inGlobalSpace, zAxisUnrotatedShortened_endPos_inGlobalSpace, zAxisRotatedOnlyAroundYShortened_endPos_inGlobalSpace, eulerAnglesToDraw.x, eulerAnglesToDraw.y, lineWidth_ofAxes, absConeLength, gimbalSize, durationInSec, hiddenByNearerObjects); + if (theAwayFromCamPointingPartOf_yAxis_isNearerToObserverCam_thanTheAwayFromCamPointingPartOf_zAxis) + { + //drawing y AFTER z and x: + DrawFirstPassOfZAxis(zAxis_pointsAwayFromObserverCam, zAxis_rotated_inGlobalSpace_normalized, zAxis_startPos_inGlobalSpace, zAxis_endPos_inGlobalSpace, perpToZAxis_markingZAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToZAxis_markingZAxisEndTurnAngle_rotated_inGlobalSpace_normalized, eulerAnglesToDraw.z, lineWidth_ofAxes, absConeLength, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + DrawFirstPassOfXAxis(xAxis_pointsAwayFromObserverCam, xAxis_rotated_inGlobalSpace_normalized, xAxis_startPos_inGlobalSpace, xAxis_endPos_inGlobalSpace, perpToXAxis_markingXAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToXAxis_markingXAxisEndTurnAngle_rotated_inGlobalSpace_normalized, eulerAnglesToDraw.x, lineWidth_ofAxes, absConeLength, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + DrawAwayFacingPartofYAxis(yAxis_pointsAwayFromObserverCam, posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, yAxis_startPos_inGlobalSpace, yAxis_endPos_inGlobalSpace, normalOfYAxisHolderRing, perpToYAxis_markingYAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToYAxis_markingYAxisEndTurnAngle_rotated_inGlobalSpace_normalized, angleDeg_ofHalfYAxisHolderRingSegment, radius_ofYAxisHolderRing, eulerAnglesToDraw.y, lineWidth_ofAxes, absConeLength, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + else + { + //drawing y BEFORE z and x: + DrawAwayFacingPartofYAxis(yAxis_pointsAwayFromObserverCam, posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, yAxis_startPos_inGlobalSpace, yAxis_endPos_inGlobalSpace, normalOfYAxisHolderRing, perpToYAxis_markingYAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToYAxis_markingYAxisEndTurnAngle_rotated_inGlobalSpace_normalized, angleDeg_ofHalfYAxisHolderRingSegment, radius_ofYAxisHolderRing, eulerAnglesToDraw.y, lineWidth_ofAxes, absConeLength, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + DrawFirstPassOfZAxis(zAxis_pointsAwayFromObserverCam, zAxis_rotated_inGlobalSpace_normalized, zAxis_startPos_inGlobalSpace, zAxis_endPos_inGlobalSpace, perpToZAxis_markingZAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToZAxis_markingZAxisEndTurnAngle_rotated_inGlobalSpace_normalized, eulerAnglesToDraw.z, lineWidth_ofAxes, absConeLength, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + DrawFirstPassOfXAxis(xAxis_pointsAwayFromObserverCam, xAxis_rotated_inGlobalSpace_normalized, xAxis_startPos_inGlobalSpace, xAxis_endPos_inGlobalSpace, perpToXAxis_markingXAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToXAxis_markingXAxisEndTurnAngle_rotated_inGlobalSpace_normalized, eulerAnglesToDraw.x, lineWidth_ofAxes, absConeLength, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + + if (isInGimbalLock) + { + DrawAwayPointingPartOfYAxis_asGimbalLockHybrid(yAxis_pointsAwayFromObserverCam, posWhereToDraw, yAxis_startPos_inGlobalSpace, yAxis_rotated_inGlobalSpace_normalized, fromDrawCenterPos_toYAxisPeak_inGlobalSpace, radius_ofYAxisHolderRing, lineWidth_ofAxes, gimbalSize, durationInSec, hiddenByNearerObjects); + } + + int struts_ofSpheres = 24; + Vector3 offset_ofGreenSpheres_alongXAxis = diameter_ofSpheres * xAxis_rotated_inGlobalSpace_normalized; + Vector3 offset_ofFarerBetweenSpheresFlange_alongXAxis = 0.6f * diameter_ofSpheres * xAxis_rotated_inGlobalSpace_normalized; + Vector3 offset_ofNearerBetweenSpheresFlange_alongXAxis = 0.4f * diameter_ofSpheres * xAxis_rotated_inGlobalSpace_normalized; + Color color_ofRedXFlange = Color.Lerp(UtilitiesDXXL_Colors.red_xAxisAlpha1, Color.black, 0.35f); + Color color_ofGreenYFlange = Color.Lerp(UtilitiesDXXL_Colors.green_yAxisAlpha1, Color.black, 0.4f); + Color color_ofBlueZFlange = Color.Lerp(UtilitiesDXXL_Colors.blue_zAxisAlpha1, Color.black, 0.4f); + float distance_centerToFarFlanges = 1.4f * diameter_ofSpheres; + + if (xAxis_pointsAwayFromObserverCam) + { + DrawShapes.Sphere(posWhereToDraw + offset_ofGreenSpheres_alongXAxis, radius_ofSpheres, UtilitiesDXXL_Colors.green_yAxisAlpha1, fromDrawCenterPos_toXAxisPeak_inGlobalSpace, default(Vector3), 0.0f, null, struts_ofSpheres, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + DrawDoubleFlange_closedHole(posWhereToDraw + offset_ofFarerBetweenSpheresFlange_alongXAxis, xAxis_rotated_inGlobalSpace_normalized, radius_ofSpheres, color_ofRedXFlange, color_ofGreenYFlange, durationInSec, hiddenByNearerObjects); + DrawShapes.Sphere(posWhereToDraw, radius_ofSpheres, UtilitiesDXXL_Colors.red_xAxisAlpha1, fromDrawCenterPos_toZAxisPeak_inGlobalSpace, default(Vector3), 0.0f, null, struts_ofSpheres, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + DrawSingleFlange(posWhereToDraw - offset_ofNearerBetweenSpheresFlange_alongXAxis, xAxis_rotated_inGlobalSpace_normalized, radius_ofSpheres, color_ofRedXFlange, durationInSec, hiddenByNearerObjects); + DrawShapes.Sphere(posWhereToDraw - offset_ofGreenSpheres_alongXAxis, radius_ofSpheres, UtilitiesDXXL_Colors.green_yAxisAlpha1, fromDrawCenterPos_toXAxisPeak_inGlobalSpace, default(Vector3), 0.0f, null, struts_ofSpheres, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + + DrawCamPointingSecondPassOfXAxis(xAxis_pointsAwayFromObserverCam, posWhereToDraw, xAxis_rotated_inGlobalSpace_normalized, xAxis_startPos_inGlobalSpace, xAxis_endPos_inGlobalSpace, perpToXAxis_markingXAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToXAxis_markingXAxisEndTurnAngle_rotated_inGlobalSpace_normalized, color_ofRedXFlange, color_ofGreenYFlange, eulerAnglesToDraw.x, lineWidth_ofAxes, radius_ofSpheres, distance_centerToFarFlanges, absConeLength, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + else + { + DrawShapes.Sphere(posWhereToDraw - offset_ofGreenSpheres_alongXAxis, radius_ofSpheres, UtilitiesDXXL_Colors.green_yAxisAlpha1, fromDrawCenterPos_toXAxisPeak_inGlobalSpace, default(Vector3), 0.0f, null, struts_ofSpheres, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + DrawDoubleFlange_closedHole(posWhereToDraw - offset_ofFarerBetweenSpheresFlange_alongXAxis, xAxis_rotated_inGlobalSpace_normalized, radius_ofSpheres, color_ofRedXFlange, color_ofGreenYFlange, durationInSec, hiddenByNearerObjects); + DrawShapes.Sphere(posWhereToDraw, radius_ofSpheres, UtilitiesDXXL_Colors.red_xAxisAlpha1, fromDrawCenterPos_toZAxisPeak_inGlobalSpace, default(Vector3), 0.0f, null, struts_ofSpheres, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + DrawSingleFlange(posWhereToDraw + offset_ofNearerBetweenSpheresFlange_alongXAxis, xAxis_rotated_inGlobalSpace_normalized, radius_ofSpheres, color_ofRedXFlange, durationInSec, hiddenByNearerObjects); + DrawShapes.Sphere(posWhereToDraw + offset_ofGreenSpheres_alongXAxis, radius_ofSpheres, UtilitiesDXXL_Colors.green_yAxisAlpha1, fromDrawCenterPos_toXAxisPeak_inGlobalSpace, default(Vector3), 0.0f, null, struts_ofSpheres, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + + DrawCamPointingSecondPassOfXAxis(xAxis_pointsAwayFromObserverCam, posWhereToDraw, xAxis_rotated_inGlobalSpace_normalized, xAxis_startPos_inGlobalSpace, xAxis_endPos_inGlobalSpace, perpToXAxis_markingXAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToXAxis_markingXAxisEndTurnAngle_rotated_inGlobalSpace_normalized, color_ofRedXFlange, color_ofGreenYFlange, eulerAnglesToDraw.x, lineWidth_ofAxes, radius_ofSpheres, distance_centerToFarFlanges, absConeLength, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + + if (theTowardsCamPointingPartOf_yAxis_isNearerToObserverCam_thanTheTowardsCamPointingPartOf_zAxis) + { + DrawCamPointingSecondPassOfZAxis(zAxis_pointsAwayFromObserverCam, posWhereToDraw, zAxis_rotated_inGlobalSpace_normalized, zAxis_startPos_inGlobalSpace, zAxis_endPos_inGlobalSpace, perpToZAxis_markingZAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToZAxis_markingZAxisEndTurnAngle_rotated_inGlobalSpace_normalized, radius_ofSpheres, diameter_ofSpheres, eulerAnglesToDraw.z, lineWidth_ofAxes, absConeLength, gimbalSize, color_ofRedXFlange, color_ofBlueZFlange, isLocal, durationInSec, hiddenByNearerObjects); + DrawCamPointingSecondPassOfYAxis(yAxis_pointsAwayFromObserverCam, posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, yAxis_startPos_inGlobalSpace, yAxis_endPos_inGlobalSpace, normalOfYAxisHolderRing, perpToYAxis_markingYAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToYAxis_markingYAxisEndTurnAngle_rotated_inGlobalSpace_normalized, angleDeg_ofHalfYAxisHolderRingSegment, radius_ofYAxisHolderRing, eulerAnglesToDraw.y, lineWidth_ofAxes, absConeLength, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + else + { + DrawCamPointingSecondPassOfYAxis(yAxis_pointsAwayFromObserverCam, posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, yAxis_startPos_inGlobalSpace, yAxis_endPos_inGlobalSpace, normalOfYAxisHolderRing, perpToYAxis_markingYAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToYAxis_markingYAxisEndTurnAngle_rotated_inGlobalSpace_normalized, angleDeg_ofHalfYAxisHolderRingSegment, radius_ofYAxisHolderRing, eulerAnglesToDraw.y, lineWidth_ofAxes, absConeLength, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + DrawCamPointingSecondPassOfZAxis(zAxis_pointsAwayFromObserverCam, posWhereToDraw, zAxis_rotated_inGlobalSpace_normalized, zAxis_startPos_inGlobalSpace, zAxis_endPos_inGlobalSpace, perpToZAxis_markingZAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToZAxis_markingZAxisEndTurnAngle_rotated_inGlobalSpace_normalized, radius_ofSpheres, diameter_ofSpheres, eulerAnglesToDraw.z, lineWidth_ofAxes, absConeLength, gimbalSize, color_ofRedXFlange, color_ofBlueZFlange, isLocal, durationInSec, hiddenByNearerObjects); + } + + float size_ofGimbalLockText = 0.10f * gimbalSize; + if (isInGimbalLock) + { + DrawCamPointingPartOfYAxis_asGimbalLockHybrid(yAxis_pointsAwayFromObserverCam, posWhereToDraw, yAxis_startPos_inGlobalSpace, yAxis_rotated_inGlobalSpace_normalized, fromDrawCenterPos_toYAxisPeak_inGlobalSpace, radius_ofYAxisHolderRing, lineWidth_ofAxes, gimbalSize, durationInSec, hiddenByNearerObjects); + Color color_ofGimbalLockText = new Color(1.0f, 0.6473441f, 0.5707547f); + UtilitiesDXXL_Text.WriteFramed("GIMBAL LOCK

", posWhereToDraw, color_ofGimbalLockText, size_ofGimbalLockText, yAxis_rotated_inGlobalSpace_normalized, default(Vector3), DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + else + { + bool isNearGimbalLock = UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(yAxis_rotated_inGlobalSpace_normalized, zAxis_rotated_inGlobalSpace_normalized, 0.02f); + if (isNearGimbalLock) + { + Color color_ofNearGimbalLockText = new Color(1.0f, 0.6473441f, 0.5707547f); + UtilitiesDXXL_Text.WriteFramed("NEAR GIMBAL LOCK

", posWhereToDraw, color_ofNearGimbalLockText, size_ofGimbalLockText, yAxis_rotated_inGlobalSpace_normalized, default(Vector3), DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + } + + float maxAbsDistance_ofAnyPlumbPos_toTurnCenter = DrawTurnedVectors(customVectorToRotate_local, length_ofUpAndForwardVectors_local, parentTransform, alpha_ofSquareSpannedByForwardAndUp, posWhereToDraw, eulerAnglesToDraw, rotation_ofLocalSpace, yAxis_unrotated_inLocalSpace_normalized, xAxis_rotated_inLocalSpace_normalized, zAxis_rotated_inLocalSpace_normalized, xAxis_rotated_inGlobalSpace_normalized, yAxis_rotated_inGlobalSpace_normalized, zAxis_rotated_inGlobalSpace_normalized, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + + if (maxAbsDistance_ofAnyPlumbPos_toTurnCenter > (gimbalSize * 1.001f)) //-> factor prevents on/off-flicker due to float calculation imprecision + { + DrawThinDashedAxesProlongations(xAxis_startPos_inGlobalSpace, xAxis_endPos_inGlobalSpace, yAxis_startPos_inGlobalSpace, yAxis_endPos_inGlobalSpace, zAxis_startPos_inGlobalSpace, zAxis_endPos_inGlobalSpace, xAxis_rotated_inGlobalSpace_normalized, yAxis_rotated_inGlobalSpace_normalized, zAxis_rotated_inGlobalSpace_normalized, gimbalSize, maxAbsDistance_ofAnyPlumbPos_toTurnCenter, durationInSec, hiddenByNearerObjects); + } + + if (text != null && text != "") + { + Vector3 position_ofText = posWhereToDraw + yAxis_rotated_inGlobalSpace_normalized * 1.13f * gimbalSize; + float size_ofText = 0.05f * gimbalSize; + UtilitiesDXXL_Text.WriteFramed(text, position_ofText, Color.white, size_ofText, default(Vector3), Vector3.up, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.solid, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + } + + static void TryDrawUnrotatedXAndZAxis(float alpha_ofUnrotatedGimbalAxes, Vector3 posWhereToDraw, Vector3 xAxisUnrotated_startPos_inGlobalSpace, Vector3 xAxisUnrotated_endPos_inGlobalSpace, Vector3 zAxisUnrotated_startPos_inGlobalSpace, Vector3 zAxisUnrotated_endPos_inGlobalSpace, Vector3 xAxis_rotated_inGlobalSpace_normalized, Vector3 yAxis_rotated_inGlobalSpace_normalized, Vector3 xAxisUnrotatedShortened_endPos_inGlobalSpace, Vector3 zAxisUnrotatedShortened_endPos_inGlobalSpace, Vector3 zAxisRotatedOnlyAroundYShortened_endPos_inGlobalSpace, float eulerAnglesToDraw_x, float eulerAnglesToDraw_y, float lineWidth_ofAxes, float absConeLength, float gimbalSize, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(alpha_ofUnrotatedGimbalAxes) == false) + { + float angleDeg_forDrawnCircledArrowOfXAxis = Loop360degProtrudingAngle_toDrawableNon360_isIntoSpan_fromExclM360_toExclP360(eulerAnglesToDraw_x); + float angleDeg_forDrawnCircledArrowOfYAxis = Loop360degProtrudingAngle_toDrawableNon360_isIntoSpan_fromExclM360_toExclP360(eulerAnglesToDraw_y); + bool loopedXTurnAngleIsApproxZero = CheckIfLoopedTurnAngleIsApproxZero(angleDeg_forDrawnCircledArrowOfXAxis); + bool loopedYTurnAngleIsApproxZero = CheckIfLoopedTurnAngleIsApproxZero(angleDeg_forDrawnCircledArrowOfYAxis); + bool xAxisIsUnturned = loopedYTurnAngleIsApproxZero; + bool zAxisIsUnturned = loopedXTurnAngleIsApproxZero && loopedYTurnAngleIsApproxZero; + + if (zAxisIsUnturned == false) + { + Color color_ofUnturnedZAxis = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.blue_zAxisAlpha1, alpha_ofUnrotatedGimbalAxes); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.Vector(zAxisUnrotated_startPos_inGlobalSpace, zAxisUnrotated_endPos_inGlobalSpace, color_ofUnturnedZAxis, lineWidth_ofAxes, null, absConeLength, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + if (xAxisIsUnturned == false) + { + Color color_ofUnturnedXAxis = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.red_xAxisAlpha1, alpha_ofUnrotatedGimbalAxes); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.Vector(xAxisUnrotated_startPos_inGlobalSpace, xAxisUnrotated_endPos_inGlobalSpace, color_ofUnturnedXAxis, lineWidth_ofAxes, null, absConeLength, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + float coneLength_relToCircledLineRadius = 0.25f; + float lineWidth_ofCircledLine = 0.005f * gimbalSize; + float customAlphaFactor_forCircledLinePointers = 2.5f; + + if (zAxisIsUnturned == false) + { + Color color_ofCircledVectorForZAxis = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.blue_zAxisAlpha1, 0.5f * alpha_ofUnrotatedGimbalAxes); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + UtilitiesDXXL_LineCircled.VectorCircled(zAxisUnrotatedShortened_endPos_inGlobalSpace, posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, angleDeg_forDrawnCircledArrowOfYAxis, color_ofCircledVectorForZAxis, lineWidth_ofCircledLine, null, coneLength_relToCircledLineRadius, false, false, false, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects, customAlphaFactor_forCircledLinePointers); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + UtilitiesDXXL_LineCircled.VectorCircled(zAxisRotatedOnlyAroundYShortened_endPos_inGlobalSpace, posWhereToDraw, xAxis_rotated_inGlobalSpace_normalized, angleDeg_forDrawnCircledArrowOfXAxis, color_ofCircledVectorForZAxis, lineWidth_ofCircledLine, null, coneLength_relToCircledLineRadius, false, false, false, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects, customAlphaFactor_forCircledLinePointers); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + } + + if (xAxisIsUnturned == false) + { + Color color_ofCircledVectorForXAxis = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.red_xAxisAlpha1, 0.5f * alpha_ofUnrotatedGimbalAxes); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + UtilitiesDXXL_LineCircled.VectorCircled(xAxisUnrotatedShortened_endPos_inGlobalSpace, posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, angleDeg_forDrawnCircledArrowOfYAxis, color_ofCircledVectorForXAxis, lineWidth_ofCircledLine, null, coneLength_relToCircledLineRadius, false, false, false, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects, customAlphaFactor_forCircledLinePointers); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + } + } + } + + static void DrawFirstPassOfZAxis(bool zAxis_pointsAwayFromObserverCam, Vector3 zAxis_rotated_inGlobalSpace_normalized, Vector3 zAxis_startPos_inGlobalSpace, Vector3 zAxis_endPos_inGlobalSpace, Vector3 perpToZAxis_markingZAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, Vector3 perpToZAxis_markingZAxisEndTurnAngle_rotated_inGlobalSpace_normalized, float eulerAnglesToDraw_z, float lineWidth_ofAxes, float absConeLength, float gimbalSize, bool isLocal, float durationInSec, bool hiddenByNearerObjects) + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.Vector(zAxis_startPos_inGlobalSpace, zAxis_endPos_inGlobalSpace, UtilitiesDXXL_Colors.blue_zAxisAlpha1, lineWidth_ofAxes, null, absConeLength, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + + if (zAxis_pointsAwayFromObserverCam == false) + { + DrawAngleVisualizerAtAxis("Z", zAxis_startPos_inGlobalSpace, zAxis_rotated_inGlobalSpace_normalized, perpToZAxis_markingZAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToZAxis_markingZAxisEndTurnAngle_rotated_inGlobalSpace_normalized, UtilitiesDXXL_Colors.blue_zAxisAlpha1, 0.56f, Color.Lerp(UtilitiesDXXL_Colors.blue_zAxisAlpha1, Color.white, 0.2f), eulerAnglesToDraw_z, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawFirstPassOfXAxis(bool xAxis_pointsAwayFromObserverCam, Vector3 xAxis_rotated_inGlobalSpace_normalized, Vector3 xAxis_startPos_inGlobalSpace, Vector3 xAxis_endPos_inGlobalSpace, Vector3 perpToXAxis_markingXAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, Vector3 perpToXAxis_markingXAxisEndTurnAngle_rotated_inGlobalSpace_normalized, float eulerAnglesToDraw_x, float lineWidth_ofAxes, float absConeLength, float gimbalSize, bool isLocal, float durationInSec, bool hiddenByNearerObjects) + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.Vector(xAxis_startPos_inGlobalSpace, xAxis_endPos_inGlobalSpace, UtilitiesDXXL_Colors.red_xAxisAlpha1, lineWidth_ofAxes, null, absConeLength, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + + if (xAxis_pointsAwayFromObserverCam == false) + { + DrawAngleVisualizerAtAxis("X", xAxis_startPos_inGlobalSpace, xAxis_rotated_inGlobalSpace_normalized, perpToXAxis_markingXAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToXAxis_markingXAxisEndTurnAngle_rotated_inGlobalSpace_normalized, UtilitiesDXXL_Colors.red_xAxisAlpha1, 0.47f, UtilitiesDXXL_Colors.GetSimilarColorWithAdjustableOtherBrightnessValue(UtilitiesDXXL_Colors.red_xAxisAlpha1, 0.2f), eulerAnglesToDraw_x, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawAwayFacingPartofYAxis(bool yAxis_pointsAwayFromObserverCam, Vector3 posWhereToDraw, Vector3 yAxis_rotated_inGlobalSpace_normalized, Vector3 yAxis_startPos_inGlobalSpace, Vector3 yAxis_endPos_inGlobalSpace, Vector3 normalOfYAxisHolderRing, Vector3 perpToYAxis_markingYAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, Vector3 perpToYAxis_markingYAxisEndTurnAngle_rotated_inGlobalSpace_normalized, float angleDeg_ofHalfYAxisHolderRingSegment, float radius_ofYAxisHolderRing, float eulerAnglesToDraw_y, float lineWidth_ofAxes, float absConeLength, float gimbalSize, bool isLocal, float durationInSec, bool hiddenByNearerObjects) + { + if (yAxis_pointsAwayFromObserverCam) + { + DrawYAxis_halfSegmentThatContainsTheArrowPeak(false, posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, yAxis_endPos_inGlobalSpace, normalOfYAxisHolderRing, angleDeg_ofHalfYAxisHolderRingSegment, radius_ofYAxisHolderRing, lineWidth_ofAxes, absConeLength, durationInSec, hiddenByNearerObjects); + } + else + { + DrawYAxis_halfSegmentThatDoesNotContainTheArrowPeak(false, posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, yAxis_startPos_inGlobalSpace, normalOfYAxisHolderRing, angleDeg_ofHalfYAxisHolderRingSegment, radius_ofYAxisHolderRing, lineWidth_ofAxes, durationInSec, hiddenByNearerObjects); + DrawAngleVisualizerAtAxis("Y", yAxis_startPos_inGlobalSpace, yAxis_rotated_inGlobalSpace_normalized, perpToYAxis_markingYAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToYAxis_markingYAxisEndTurnAngle_rotated_inGlobalSpace_normalized, UtilitiesDXXL_Colors.green_yAxisAlpha1, 0.4f, UtilitiesDXXL_Colors.GetSimilarColorWithAdjustableOtherBrightnessValue(UtilitiesDXXL_Colors.green_yAxisAlpha1, 0.2f), eulerAnglesToDraw_y, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawAwayPointingPartOfYAxis_asGimbalLockHybrid(bool yAxis_pointsAwayFromObserverCam, Vector3 posWhereToDraw, Vector3 yAxis_startPos_inGlobalSpace, Vector3 yAxis_rotated_inGlobalSpace_normalized, Vector3 fromDrawCenterPos_toYAxisPeak_inGlobalSpace, float radius_ofYAxisHolderRing, float lineWidth_ofAxes, float gimbalSize, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 yAxisStartPos_onHolderRing; + Vector3 endPos; + + if (yAxis_pointsAwayFromObserverCam) + { + yAxisStartPos_onHolderRing = posWhereToDraw + yAxis_rotated_inGlobalSpace_normalized * radius_ofYAxisHolderRing; + endPos = posWhereToDraw + fromDrawCenterPos_toYAxisPeak_inGlobalSpace * 0.9f; + } + else + { + yAxisStartPos_onHolderRing = posWhereToDraw - yAxis_rotated_inGlobalSpace_normalized * radius_ofYAxisHolderRing; + endPos = yAxis_startPos_inGlobalSpace; + } + + float lengthOfStripes = stripeSizeFactor_forGimbelLocksAlternatingColorLine * gimbalSize; + LineWithAlternatingColors_fadeableAnimSpeed.InternalDraw(yAxisStartPos_onHolderRing, endPos, UtilitiesDXXL_Colors.green_yAxisAlpha1, UtilitiesDXXL_Colors.blue_zAxisAlpha1, lineWidth_ofAxes, lengthOfStripes, null, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true); + } + + static void DrawCamPointingSecondPassOfXAxis(bool xAxis_pointsAwayFromObserverCam, Vector3 posWhereToDraw, Vector3 xAxis_rotated_inGlobalSpace_normalized, Vector3 xAxis_startPos_inGlobalSpace, Vector3 xAxis_endPos_inGlobalSpace, Vector3 perpToXAxis_markingXAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, Vector3 perpToXAxis_markingXAxisEndTurnAngle_rotated_inGlobalSpace_normalized, Color color_ofRedXFlange, Color color_ofGreenYFlange, float eulerAnglesToDraw_x, float lineWidth_ofAxes, float radius_ofSpheres, float distance_centerToFarFlanges, float absConeLength, float gimbalSize, bool isLocal, float durationInSec, bool hiddenByNearerObjects) + { + if (xAxis_pointsAwayFromObserverCam) + { + Vector3 xAxisEntryPointIntoRedSphere = posWhereToDraw - xAxis_rotated_inGlobalSpace_normalized * distance_centerToFarFlanges; + DrawDoubleFlange_openHole(xAxisEntryPointIntoRedSphere, xAxis_rotated_inGlobalSpace_normalized, radius_ofSpheres, color_ofRedXFlange, color_ofGreenYFlange, durationInSec, hiddenByNearerObjects); + Line_fadeableAnimSpeed.InternalDraw(xAxisEntryPointIntoRedSphere, xAxis_startPos_inGlobalSpace, UtilitiesDXXL_Colors.red_xAxisAlpha1, lineWidth_ofAxes, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + DrawAngleVisualizerAtAxis("X", xAxis_startPos_inGlobalSpace, xAxis_rotated_inGlobalSpace_normalized, perpToXAxis_markingXAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToXAxis_markingXAxisEndTurnAngle_rotated_inGlobalSpace_normalized, UtilitiesDXXL_Colors.red_xAxisAlpha1, 0.47f, UtilitiesDXXL_Colors.GetSimilarColorWithAdjustableOtherBrightnessValue(UtilitiesDXXL_Colors.red_xAxisAlpha1, 0.2f), eulerAnglesToDraw_x, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + else + { + Vector3 xAxisEntryPointIntoRedSphere = posWhereToDraw + xAxis_rotated_inGlobalSpace_normalized * distance_centerToFarFlanges; + DrawDoubleFlange_openHole(xAxisEntryPointIntoRedSphere, xAxis_rotated_inGlobalSpace_normalized, radius_ofSpheres, color_ofRedXFlange, color_ofGreenYFlange, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.Vector(xAxisEntryPointIntoRedSphere, xAxis_endPos_inGlobalSpace, UtilitiesDXXL_Colors.red_xAxisAlpha1, lineWidth_ofAxes, null, absConeLength, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + + } + } + + static void DrawCamPointingSecondPassOfZAxis(bool zAxis_pointsAwayFromObserverCam, Vector3 posWhereToDraw, Vector3 zAxis_rotated_inGlobalSpace_normalized, Vector3 zAxis_startPos_inGlobalSpace, Vector3 zAxis_endPos_inGlobalSpace, Vector3 perpToZAxis_markingZAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, Vector3 perpToZAxis_markingZAxisEndTurnAngle_rotated_inGlobalSpace_normalized, float radius_ofSpheres, float diameter_ofSpheres, float eulerAnglesToDraw_z, float lineWidth_ofAxes, float absConeLength, float gimbalSize, Color color_ofRedXFlange, Color color_ofBlueZFlange, bool isLocal, float durationInSec, bool hiddenByNearerObjects) + { + float distance_centerToNearFlanges = 0.4f * diameter_ofSpheres; + if (zAxis_pointsAwayFromObserverCam) + { + Vector3 zAxisEntryPointIntoRedSphere = posWhereToDraw - zAxis_rotated_inGlobalSpace_normalized * distance_centerToNearFlanges; + DrawDoubleFlange_openHole(zAxisEntryPointIntoRedSphere, zAxis_rotated_inGlobalSpace_normalized, radius_ofSpheres, color_ofBlueZFlange, color_ofRedXFlange, durationInSec, hiddenByNearerObjects); + Line_fadeableAnimSpeed.InternalDraw(zAxisEntryPointIntoRedSphere, zAxis_startPos_inGlobalSpace, UtilitiesDXXL_Colors.blue_zAxisAlpha1, lineWidth_ofAxes, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + DrawAngleVisualizerAtAxis("Z", zAxis_startPos_inGlobalSpace, zAxis_rotated_inGlobalSpace_normalized, perpToZAxis_markingZAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToZAxis_markingZAxisEndTurnAngle_rotated_inGlobalSpace_normalized, UtilitiesDXXL_Colors.blue_zAxisAlpha1, 0.56f, Color.Lerp(UtilitiesDXXL_Colors.blue_zAxisAlpha1, Color.white, 0.2f), eulerAnglesToDraw_z, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + else + { + Vector3 zAxisEntryPointIntoRedSphere = posWhereToDraw + zAxis_rotated_inGlobalSpace_normalized * distance_centerToNearFlanges; + DrawDoubleFlange_openHole(zAxisEntryPointIntoRedSphere, zAxis_rotated_inGlobalSpace_normalized, radius_ofSpheres, color_ofBlueZFlange, color_ofRedXFlange, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.Vector(zAxisEntryPointIntoRedSphere, zAxis_endPos_inGlobalSpace, UtilitiesDXXL_Colors.blue_zAxisAlpha1, lineWidth_ofAxes, null, absConeLength, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + } + + static void DrawCamPointingSecondPassOfYAxis(bool yAxis_pointsAwayFromObserverCam, Vector3 posWhereToDraw, Vector3 yAxis_rotated_inGlobalSpace_normalized, Vector3 yAxis_startPos_inGlobalSpace, Vector3 yAxis_endPos_inGlobalSpace, Vector3 normalOfYAxisHolderRing, Vector3 perpToYAxis_markingYAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, Vector3 perpToYAxis_markingYAxisEndTurnAngle_rotated_inGlobalSpace_normalized, float angleDeg_ofHalfYAxisHolderRingSegment, float radius_ofYAxisHolderRing, float eulerAnglesToDraw_y, float lineWidth_ofAxes, float absConeLength, float gimbalSize, bool isLocal, float durationInSec, bool hiddenByNearerObjects) + { + if (yAxis_pointsAwayFromObserverCam) + { + DrawYAxis_halfSegmentThatDoesNotContainTheArrowPeak(true, posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, yAxis_startPos_inGlobalSpace, normalOfYAxisHolderRing, angleDeg_ofHalfYAxisHolderRingSegment, radius_ofYAxisHolderRing, lineWidth_ofAxes, durationInSec, hiddenByNearerObjects); + DrawAngleVisualizerAtAxis("Y", yAxis_startPos_inGlobalSpace, yAxis_rotated_inGlobalSpace_normalized, perpToYAxis_markingYAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, perpToYAxis_markingYAxisEndTurnAngle_rotated_inGlobalSpace_normalized, UtilitiesDXXL_Colors.green_yAxisAlpha1, 0.4f, UtilitiesDXXL_Colors.GetSimilarColorWithAdjustableOtherBrightnessValue(UtilitiesDXXL_Colors.green_yAxisAlpha1, 0.2f), eulerAnglesToDraw_y, gimbalSize, isLocal, durationInSec, hiddenByNearerObjects); + } + else + { + DrawYAxis_halfSegmentThatContainsTheArrowPeak(true, posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, yAxis_endPos_inGlobalSpace, normalOfYAxisHolderRing, angleDeg_ofHalfYAxisHolderRingSegment, radius_ofYAxisHolderRing, lineWidth_ofAxes, absConeLength, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawCamPointingPartOfYAxis_asGimbalLockHybrid(bool yAxis_pointsAwayFromObserverCam, Vector3 posWhereToDraw, Vector3 yAxis_startPos_inGlobalSpace, Vector3 yAxis_rotated_inGlobalSpace_normalized, Vector3 fromDrawCenterPos_toYAxisPeak_inGlobalSpace, float radius_ofYAxisHolderRing, float lineWidth_ofAxes, float gimbalSize, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 yAxisStartPos_onHolderRing; + Vector3 endPos; + + if (yAxis_pointsAwayFromObserverCam) + { + yAxisStartPos_onHolderRing = posWhereToDraw - yAxis_rotated_inGlobalSpace_normalized * radius_ofYAxisHolderRing; + endPos = yAxis_startPos_inGlobalSpace; + } + else + { + yAxisStartPos_onHolderRing = posWhereToDraw + yAxis_rotated_inGlobalSpace_normalized * radius_ofYAxisHolderRing; + endPos = posWhereToDraw + fromDrawCenterPos_toYAxisPeak_inGlobalSpace * 0.9f; + } + + float lengthOfStripes = stripeSizeFactor_forGimbelLocksAlternatingColorLine * gimbalSize; + LineWithAlternatingColors_fadeableAnimSpeed.InternalDraw(yAxisStartPos_onHolderRing, endPos, UtilitiesDXXL_Colors.green_yAxisAlpha1, UtilitiesDXXL_Colors.blue_zAxisAlpha1, lineWidth_ofAxes, lengthOfStripes, null, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true); + } + + static void DrawYAxis_halfSegmentThatContainsTheArrowPeak(bool containsFlanges, Vector3 posWhereToDraw, Vector3 yAxis_rotated_inGlobalSpace_normalized, Vector3 yAxis_endPos_inGlobalSpace, Vector3 normalOfYAxisHolderRing, float angleDeg_ofHalfYAxisHolderRingSegment, float radius_ofYAxisHolderRing, float lineWidth_ofAxes, float absConeLength, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 yAxisStartPos_onHolderRing = posWhereToDraw + yAxis_rotated_inGlobalSpace_normalized * radius_ofYAxisHolderRing; + if (containsFlanges) + { + DrawFlanges_atYAxisHolderCircle(posWhereToDraw, yAxisStartPos_onHolderRing, normalOfYAxisHolderRing, lineWidth_ofAxes, angleDeg_ofHalfYAxisHolderRingSegment, durationInSec, hiddenByNearerObjects); + } + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.Vector(yAxisStartPos_onHolderRing, yAxis_endPos_inGlobalSpace, UtilitiesDXXL_Colors.green_yAxisAlpha1, lineWidth_ofAxes, null, absConeLength, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + + DrawBasics.LineCircled(yAxisStartPos_onHolderRing, posWhereToDraw, normalOfYAxisHolderRing, angleDeg_ofHalfYAxisHolderRingSegment, UtilitiesDXXL_Colors.green_yAxisAlpha1, lineWidth_ofAxes, null, false, false, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); + DrawBasics.LineCircled(yAxisStartPos_onHolderRing, posWhereToDraw, normalOfYAxisHolderRing, -angleDeg_ofHalfYAxisHolderRingSegment, UtilitiesDXXL_Colors.green_yAxisAlpha1, lineWidth_ofAxes, null, false, false, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); + } + + static void DrawYAxis_halfSegmentThatDoesNotContainTheArrowPeak(bool containsFlanges, Vector3 posWhereToDraw, Vector3 yAxis_rotated_inGlobalSpace_normalized, Vector3 yAxis_startPos_inGlobalSpace, Vector3 normalOfYAxisHolderRing, float angleDeg_ofHalfYAxisHolderRingSegment, float radius_ofYAxisHolderRing, float lineWidth_ofAxes, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 yAxisStartPos_onHolderRing = posWhereToDraw - yAxis_rotated_inGlobalSpace_normalized * radius_ofYAxisHolderRing; + if (containsFlanges) + { + DrawFlanges_atYAxisHolderCircle(posWhereToDraw, yAxisStartPos_onHolderRing, normalOfYAxisHolderRing, lineWidth_ofAxes, angleDeg_ofHalfYAxisHolderRingSegment, durationInSec, hiddenByNearerObjects); + } + Line_fadeableAnimSpeed.InternalDraw(yAxisStartPos_onHolderRing, yAxis_startPos_inGlobalSpace, UtilitiesDXXL_Colors.green_yAxisAlpha1, lineWidth_ofAxes, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + DrawBasics.LineCircled(yAxisStartPos_onHolderRing, posWhereToDraw, normalOfYAxisHolderRing, angleDeg_ofHalfYAxisHolderRingSegment, UtilitiesDXXL_Colors.green_yAxisAlpha1, lineWidth_ofAxes, null, false, false, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); + DrawBasics.LineCircled(yAxisStartPos_onHolderRing, posWhereToDraw, normalOfYAxisHolderRing, -angleDeg_ofHalfYAxisHolderRingSegment, UtilitiesDXXL_Colors.green_yAxisAlpha1, lineWidth_ofAxes, null, false, false, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); + } + + static void DrawFlanges_atYAxisHolderCircle(Vector3 posWhereToDraw, Vector3 yAxisStartPos_onHolderRing, Vector3 normalOfYAxisHolderRing, float lineWidth_ofAxes, float angleDeg_ofHalfYAxisHolderRingSegment, float durationInSec, bool hiddenByNearerObjects) + { + Quaternion rotation_fromTriMountPoint_toFlange1 = Quaternion.AngleAxis(angleDeg_ofHalfYAxisHolderRingSegment, normalOfYAxisHolderRing); + Quaternion rotation_fromTriMountPoint_toFlange2 = Quaternion.Inverse(rotation_fromTriMountPoint_toFlange1); + + Vector3 fromCenterPos_toTriMountPoint = yAxisStartPos_onHolderRing - posWhereToDraw; + Vector3 fromCenterPos_toFlange1 = rotation_fromTriMountPoint_toFlange1 * fromCenterPos_toTriMountPoint; + Vector3 fromCenterPos_toFlange2 = rotation_fromTriMountPoint_toFlange2 * fromCenterPos_toTriMountPoint; + + Vector3 centerPos_ofFlange1 = posWhereToDraw + fromCenterPos_toFlange1; + Vector3 centerPos_ofFlange2 = posWhereToDraw + fromCenterPos_toFlange2; + + Quaternion rotation_aroundHolderCircle_by90deg = Quaternion.AngleAxis(90.0f, normalOfYAxisHolderRing); + Vector3 normal_ofFlange1 = rotation_aroundHolderCircle_by90deg * fromCenterPos_toFlange1; + Vector3 normal_ofFlange2 = rotation_aroundHolderCircle_by90deg * fromCenterPos_toFlange2; + + float radius = (0.5f * lineWidth_ofAxes) * 1.2f; + Color color = Color.Lerp(UtilitiesDXXL_Colors.green_yAxisAlpha1, Color.black, 0.6f); + + DrawShapes.Decagon(centerPos_ofFlange1, radius, color, normal_ofFlange1, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Decagon(centerPos_ofFlange2, radius, color, normal_ofFlange2, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + + static void DrawSingleFlange(Vector3 position, Vector3 innerAxis_rotated_inGlobalSpace_normalized, float radius_ofSpheres, Color color, float durationInSec, bool hiddenByNearerObjects) + { + float radius_ofOuterFlange = radius_ofSpheres * 0.3f; + float lineWidth_ofOuterFlange = radius_ofSpheres * 0.55f; + DrawShapes.Decagon(position, radius_ofOuterFlange, color, innerAxis_rotated_inGlobalSpace_normalized, default(Vector3), lineWidth_ofOuterFlange, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + + static void DrawDoubleFlange_openHole(Vector3 position, Vector3 innerAxis_rotated_inGlobalSpace_normalized, float radius_ofSpheres, Color color_ofInnerFlange, Color color_ofOuterFlange, float durationInSec, bool hiddenByNearerObjects) + { + float radius_ofOuterFlange = radius_ofSpheres * 0.55f; + float lineWidth_ofOuterFlange = radius_ofSpheres * 0.2f; + DrawShapes.Decagon(position, radius_ofOuterFlange, color_ofOuterFlange, innerAxis_rotated_inGlobalSpace_normalized, default(Vector3), lineWidth_ofOuterFlange, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + float radius_ofInnerFlange = radius_ofSpheres * 0.35f; + float lineWidth_ofInnerFlange = radius_ofSpheres * 0.2f; + DrawShapes.Decagon(position, radius_ofInnerFlange, color_ofInnerFlange, innerAxis_rotated_inGlobalSpace_normalized, default(Vector3), lineWidth_ofInnerFlange, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + + static void DrawDoubleFlange_closedHole(Vector3 position, Vector3 innerAxis_rotated_inGlobalSpace_normalized, float radius_ofSpheres, Color color_ofInnerFlange, Color color_ofOuterFlange, float durationInSec, bool hiddenByNearerObjects) + { + float radius_ofOuterFlange = radius_ofSpheres * 0.55f; + float lineWidth_ofOuterFlange = radius_ofSpheres * 0.2f; + DrawShapes.Decagon(position, radius_ofOuterFlange, color_ofOuterFlange, innerAxis_rotated_inGlobalSpace_normalized, default(Vector3), lineWidth_ofOuterFlange, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + float radius_ofInnerFlange = radius_ofSpheres * 0.25f; + float lineWidth_ofInnerFlange = radius_ofSpheres * 0.4f; + DrawShapes.Decagon(position, radius_ofInnerFlange, color_ofInnerFlange, innerAxis_rotated_inGlobalSpace_normalized, default(Vector3), lineWidth_ofInnerFlange, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + + static void DrawAngleVisualizerAtAxis(string axisName, Vector3 axis_startPos_inGlobalSpace, Vector3 axis_rotated_inGlobalSpace_normalized, Vector3 perpToAxis_markingAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, Vector3 perpToAxis_markingAxisEndTurnAngle_rotated_inGlobalSpace_normalized, Color color_ofAxis, float alphaFactor_forColorOfThinFullCircle, Color color_ofAngleText, float eulerAngles_withWhichAxisIsTurned, float gimbalSize, bool isLocal, float durationInSec, bool hiddenByNearerObjects) + { + float radius_ofTurnAngleAtAxes_visualizer = relRadius_ofAxisTurnAngleVisualizer * gimbalSize; + float radiusOfText_ofTurnAngleAtAxes_visualizer = radius_ofTurnAngleAtAxes_visualizer * 1.1f; + float size_ofTurnAngleVisualizerText = 0.28f * radius_ofTurnAngleAtAxes_visualizer; + float lineWidth_ofTurnAngleCircledArrow = eulerAxesTurnAngleVisualizer_relLineWidth * gimbalSize; + + Vector3 startPosOnTurnAngleVisualizerCircle = axis_startPos_inGlobalSpace + perpToAxis_markingAxisZeroTurnAngle_rotated_inGlobalSpace_normalized * radius_ofTurnAngleAtAxes_visualizer; + Vector3 endPosOnTurnAngleVisualizerCircle = axis_startPos_inGlobalSpace + perpToAxis_markingAxisEndTurnAngle_rotated_inGlobalSpace_normalized * radius_ofTurnAngleAtAxes_visualizer; + + Line_fadeableAnimSpeed.InternalDraw(axis_startPos_inGlobalSpace, startPosOnTurnAngleVisualizerCircle, color_ofAxis, 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(axis_startPos_inGlobalSpace, endPosOnTurnAngleVisualizerCircle, color_ofAxis, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + Color color_ofThinFullCircle = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofAxis, alphaFactor_forColorOfThinFullCircle); + DrawShapes.Circle(axis_startPos_inGlobalSpace, radius_ofTurnAngleAtAxes_visualizer, color_ofThinFullCircle, axis_rotated_inGlobalSpace_normalized, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + bool absAngle_isBiggerOrEqualThan360deg = Mathf.Abs(eulerAngles_withWhichAxisIsTurned) >= 360.0f; + if (absAngle_isBiggerOrEqualThan360deg) + { + DrawShapes.Circle(axis_startPos_inGlobalSpace, radius_ofTurnAngleAtAxes_visualizer, color_ofAxis, axis_rotated_inGlobalSpace_normalized, default(Vector3), lineWidth_ofTurnAngleCircledArrow, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + + float angleDeg_forDrawnCircledArrow = Loop360degProtrudingAngle_toDrawableNon360_isIntoSpan_fromExclM360_toExclP360(eulerAngles_withWhichAxisIsTurned); + if (UtilitiesDXXL_Math.ApproximatelyZero(angleDeg_forDrawnCircledArrow)) + { + //-> skip drawing circledArrow + } + else + { + DrawCircledArrow_atAxisTurnVisualizer(angleDeg_forDrawnCircledArrow, axis_startPos_inGlobalSpace, axis_rotated_inGlobalSpace_normalized, startPosOnTurnAngleVisualizerCircle, color_ofAxis, lineWidth_ofTurnAngleCircledArrow, durationInSec, hiddenByNearerObjects); + } + + Vector3 startPosOfTextOnTurnAngleVisualizerCircle = axis_startPos_inGlobalSpace + perpToAxis_markingAxisZeroTurnAngle_rotated_inGlobalSpace_normalized * radiusOfText_ofTurnAngleAtAxes_visualizer; + Vector3 turnAxis_ofText = (eulerAngles_withWhichAxisIsTurned < 0.0f) ? axis_rotated_inGlobalSpace_normalized : (-axis_rotated_inGlobalSpace_normalized); //-> prevent text from starting to away from circledArrow + UtilitiesDXXL_Text.WriteOnCircle("" + eulerAngles_withWhichAxisIsTurned + "°", startPosOfTextOnTurnAngleVisualizerCircle, axis_startPos_inGlobalSpace, turnAxis_ofText, color_ofAngleText, size_ofTurnAngleVisualizerText, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, 0.0f, true, durationInSec, hiddenByNearerObjects); + + Vector3 textDir_ofAxisIdentifierName_normalized = Vector3.Cross(perpToAxis_markingAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, axis_rotated_inGlobalSpace_normalized); + Vector3 pos_ofAxisIdentifierName = axis_startPos_inGlobalSpace + perpToAxis_markingAxisZeroTurnAngle_rotated_inGlobalSpace_normalized * radius_ofTurnAngleAtAxes_visualizer * 0.075f; //-> slightly shifted, so it ends up with homogenuous padding to upper and lower side. + + UtilitiesDXXL_Text.Write("" + axisName + "
axis", pos_ofAxisIdentifierName, color_ofAngleText, 1.9f * size_ofTurnAngleVisualizerText, textDir_ofAxisIdentifierName_normalized, perpToAxis_markingAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, DrawText.TextAnchorDXXL.UpperCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + if (isLocal) + { + Vector3 pos_ofLocalPrefix = axis_startPos_inGlobalSpace - perpToAxis_markingAxisZeroTurnAngle_rotated_inGlobalSpace_normalized * radius_ofTurnAngleAtAxes_visualizer * 0.22f; + UtilitiesDXXL_Text.Write(" local ", pos_ofLocalPrefix, color_ofAngleText, 0.35f * size_ofTurnAngleVisualizerText, textDir_ofAxisIdentifierName_normalized, perpToAxis_markingAxisZeroTurnAngle_rotated_inGlobalSpace_normalized, DrawText.TextAnchorDXXL.UpperRight, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + + static void DrawCircledArrow_atAxisTurnVisualizer(float eulerAnglesSpanOfDrawnCircledArrow, Vector3 axis_startPos_inGlobalSpace, Vector3 axis_rotated_inGlobalSpace_normalized, Vector3 startPosOnTurnAngleVisualizerCircle, Color color_ofAxis, float lineWidth_ofTurnAngleCircledArrow, float durationInSec, bool hiddenByNearerObjects) + { + float coneLength_relToRadius = 0.4f; + + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorCircled(startPosOnTurnAngleVisualizerCircle, axis_startPos_inGlobalSpace, axis_rotated_inGlobalSpace_normalized, eulerAnglesSpanOfDrawnCircledArrow, color_ofAxis, lineWidth_ofTurnAngleCircledArrow, null, coneLength_relToRadius, false, false, true, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + } + + static float Loop360degProtrudingAngle_toDrawableNon360_isIntoSpan_fromExclM360_toExclP360(float angleDeg_toLoop) + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(angleDeg_toLoop, 360.0f)) + { + return 359.9f; + } + else + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(angleDeg_toLoop, -360.0f)) + { + return (-359.9f); + } + else + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(angleDeg_toLoop, 720.0f)) + { + return 359.9f; + } + else + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(angleDeg_toLoop, -720.0f)) + { + return (-359.9f); + } + else + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(angleDeg_toLoop, 1080.0f)) + { + return 359.9f; + } + else + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(angleDeg_toLoop, -1080.0f)) + { + return (-359.9f); + } + else + { + float angleDeg_loopedToBetween_m360_and_p360 = UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_mX_to_pX(angleDeg_toLoop, 360.0f); + float abs_angleDeg_loopedToBetween_m360_and_p360 = Mathf.Abs(angleDeg_loopedToBetween_m360_and_p360); + if (abs_angleDeg_loopedToBetween_m360_and_p360 > 0.1f) + { + return angleDeg_toLoop; + } + else + { + return 0.0f; + } + } + } + } + } + } + } + } + + static bool CheckIfLoopedTurnAngleIsApproxZero(float loopedTurnAngleDeg) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(loopedTurnAngleDeg)) + { + return true; + } + else + { + if (loopedTurnAngleDeg >= 359.9f) + { + return true; + } + else + { + if (loopedTurnAngleDeg <= (-359.9f)) + { + return true; + } + } + } + return false; + } + + static float DrawTurnedVectors(Vector3 customVectorToRotate_local, float length_ofUpAndForwardVectors_local, Transform parentTransform, float alpha_ofSquareSpannedByForwardAndUp, Vector3 posWhereToDraw, Vector3 eulerAnglesToDraw, Quaternion rotation_ofLocalSpace, Vector3 yAxis_unrotated_inLocalSpace_normalized, Vector3 xAxis_rotated_inLocalSpace_normalized, Vector3 zAxis_rotated_inLocalSpace_normalized, Vector3 xAxis_rotated_inGlobalSpace_normalized, Vector3 yAxis_rotated_inGlobalSpace_normalized, Vector3 zAxis_rotated_inGlobalSpace_normalized, float gimbalSize, bool isLocal, float durationInSec, bool hiddenByNearerObjects) + { + float maxAbsDistance_ofAnyPlumbPos_toTurnCenter = 0.0f; + + Vector3 customVectorToTurn_unturned_inLocalSpaceUnits_butAlreadyScaledSoLengthFitsGlobalUnits = (parentTransform == null) ? customVectorToRotate_local : Vector3.Scale(parentTransform.lossyScale, customVectorToRotate_local); + float length_ofUpAndForwardVectors_global = (parentTransform == null) ? length_ofUpAndForwardVectors_local : (parentTransform.lossyScale.x * length_ofUpAndForwardVectors_local); + + bool drawCustomVector = CustomVectorIsDrawn(customVectorToTurn_unturned_inLocalSpaceUnits_butAlreadyScaledSoLengthFitsGlobalUnits); + bool drawForwardAndUpVectors = ForwardAndUpVectorsAreDrawn(length_ofUpAndForwardVectors_global); + if (drawCustomVector || drawForwardAndUpVectors) + { + Quaternion eulerAnglesToDraw_asQuaternion = Quaternion.Euler(eulerAnglesToDraw.x, eulerAnglesToDraw.y, eulerAnglesToDraw.z); + eulerAnglesToDraw_asQuaternion.ToAngleAxis(out float shortestTurnAngleDeg, out Vector3 quaternionTurnAxis); + if (shortestTurnAngleDeg > 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". + shortestTurnAngleDeg = shortestTurnAngleDeg - 360.0f; + } + float abs_shortestTurnAngleDeg = Mathf.Abs(shortestTurnAngleDeg); + bool rotationIsApproxIdentity = (abs_shortestTurnAngleDeg < 0.001f); + + Quaternion localEulerRotationAroundYAxis = Quaternion.AngleAxis(eulerAnglesToDraw.y, yAxis_unrotated_inLocalSpace_normalized); + Quaternion localEulerRotationAroundRotatedXAxis = Quaternion.AngleAxis(eulerAnglesToDraw.x, xAxis_rotated_inLocalSpace_normalized); + Quaternion localEulerRotationAroundRotatedZAxis = Quaternion.AngleAxis(eulerAnglesToDraw.z, zAxis_rotated_inLocalSpace_normalized); + + rotatedXAxis_line_inGlobalSpaceUnits.Recreate(posWhereToDraw, xAxis_rotated_inGlobalSpace_normalized, true); + rotatedYAxis_line_inGlobalSpaceUnits.Recreate(posWhereToDraw, yAxis_rotated_inGlobalSpace_normalized, true); + rotatedZAxis_line_inGlobalSpaceUnits.Recreate(posWhereToDraw, zAxis_rotated_inGlobalSpace_normalized, true); + + float maxAbsDistance_ofAnyPlumbPos_toTurnCenter_ofCurrTurnedVector; + if (drawCustomVector) + { + Color color_ofUnturnedCustomVector = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(0.105f, 0.1165f, 1.0f); + Color color_ofTurnedCustomVector = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(0.105f, 0.5f, 1.0f); + maxAbsDistance_ofAnyPlumbPos_toTurnCenter_ofCurrTurnedVector = DrawRotationOfCustomVector(customVectorToRotate_local, customVectorToTurn_unturned_inLocalSpaceUnits_butAlreadyScaledSoLengthFitsGlobalUnits, color_ofUnturnedCustomVector, color_ofTurnedCustomVector, "customVector", posWhereToDraw, eulerAnglesToDraw, rotation_ofLocalSpace, xAxis_rotated_inGlobalSpace_normalized, yAxis_rotated_inGlobalSpace_normalized, zAxis_rotated_inGlobalSpace_normalized, localEulerRotationAroundRotatedXAxis, localEulerRotationAroundYAxis, localEulerRotationAroundRotatedZAxis, gimbalSize, rotationIsApproxIdentity, isLocal, durationInSec, hiddenByNearerObjects); + maxAbsDistance_ofAnyPlumbPos_toTurnCenter = Mathf.Max(maxAbsDistance_ofAnyPlumbPos_toTurnCenter_ofCurrTurnedVector, maxAbsDistance_ofAnyPlumbPos_toTurnCenter); + } + + if (drawForwardAndUpVectors) + { + Color color_ofUnturnedForwardVector = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(0.6666f, 0.1625f, 1.0f); + Color color_ofTurnedForwardVector = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(0.6666f, 0.875f, 1.0f); + + Color color_ofUnturnedUpVector = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(0.28f, 0.125f, 1.0f); + Color color_ofTurnedUpVector = SeededColorGenerator.GetColorFromHueAndLuminance_tunedTransitionsSpectrum(0.27f, 0.85f, 1.0f); + + Vector3 localForwardVector_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits = Vector3.forward * length_ofUpAndForwardVectors_local; + Vector3 localUpVector_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits = Vector3.up * length_ofUpAndForwardVectors_local; + Vector3 localForwardVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits = Vector3.forward * length_ofUpAndForwardVectors_global; + Vector3 localUpVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits = Vector3.up * length_ofUpAndForwardVectors_global; + + if (UtilitiesDXXL_Math.ApproximatelyZero(alpha_ofSquareSpannedByForwardAndUp) == false) + { + DrawSquareSpannedByForwardAndUp(alpha_ofSquareSpannedByForwardAndUp, localForwardVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits, localUpVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits, posWhereToDraw, eulerAnglesToDraw_asQuaternion, rotation_ofLocalSpace, color_ofUnturnedForwardVector, color_ofTurnedForwardVector, color_ofUnturnedUpVector, color_ofTurnedUpVector, rotationIsApproxIdentity, durationInSec, hiddenByNearerObjects); + } + maxAbsDistance_ofAnyPlumbPos_toTurnCenter_ofCurrTurnedVector = DrawRotationOfCustomVector(localForwardVector_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits, localForwardVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits, color_ofUnturnedForwardVector, color_ofTurnedForwardVector, "Vector3.forward", posWhereToDraw, eulerAnglesToDraw, rotation_ofLocalSpace, xAxis_rotated_inGlobalSpace_normalized, yAxis_rotated_inGlobalSpace_normalized, zAxis_rotated_inGlobalSpace_normalized, localEulerRotationAroundRotatedXAxis, localEulerRotationAroundYAxis, localEulerRotationAroundRotatedZAxis, gimbalSize, rotationIsApproxIdentity, isLocal, durationInSec, hiddenByNearerObjects); + maxAbsDistance_ofAnyPlumbPos_toTurnCenter = Mathf.Max(maxAbsDistance_ofAnyPlumbPos_toTurnCenter_ofCurrTurnedVector, maxAbsDistance_ofAnyPlumbPos_toTurnCenter); + maxAbsDistance_ofAnyPlumbPos_toTurnCenter_ofCurrTurnedVector = DrawRotationOfCustomVector(localUpVector_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits, localUpVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits, color_ofUnturnedUpVector, color_ofTurnedUpVector, "Vector3.up", posWhereToDraw, eulerAnglesToDraw, rotation_ofLocalSpace, xAxis_rotated_inGlobalSpace_normalized, yAxis_rotated_inGlobalSpace_normalized, zAxis_rotated_inGlobalSpace_normalized, localEulerRotationAroundRotatedXAxis, localEulerRotationAroundYAxis, localEulerRotationAroundRotatedZAxis, gimbalSize, rotationIsApproxIdentity, isLocal, durationInSec, hiddenByNearerObjects); + maxAbsDistance_ofAnyPlumbPos_toTurnCenter = Mathf.Max(maxAbsDistance_ofAnyPlumbPos_toTurnCenter_ofCurrTurnedVector, maxAbsDistance_ofAnyPlumbPos_toTurnCenter); + } + } + return maxAbsDistance_ofAnyPlumbPos_toTurnCenter; + } + + static bool CustomVectorIsDrawn(Vector3 customVectorToRotate) + { + float biggestAbsComponent = UtilitiesDXXL_Math.GetBiggestAbsComponent(customVectorToRotate); + return (biggestAbsComponent > approxLength_ofShortestTurnedVectorThatIsDrawn); + } + + static bool ForwardAndUpVectorsAreDrawn(float length_ofUpAndForwardVectors) + { + float abs_length_ofUpAndForwardVectors = Mathf.Abs(length_ofUpAndForwardVectors); + return (abs_length_ofUpAndForwardVectors > approxLength_ofShortestTurnedVectorThatIsDrawn); + } + + static void DrawSquareSpannedByForwardAndUp(float alpha_ofSquareSpannedByForwardAndUp, Vector3 localForwardVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits, Vector3 localUpVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits, Vector3 posWhereToDraw, Quaternion eulerAnglesToDraw_asQuaternion, Quaternion rotation_ofLocalSpace, Color color_ofUnturnedForwardVector, Color color_ofTurnedForwardVector, Color color_ofUnturnedUpVector, Color color_ofTurnedUpVector, bool rotationIsApproxIdentity, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 localForwardVector_turned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits = eulerAnglesToDraw_asQuaternion * localForwardVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits; + Vector3 localUpVector_turned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits = eulerAnglesToDraw_asQuaternion * localUpVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits; + + Vector3 localForwardVectorScaled_unturned_inGlobalSpaceUnits = rotation_ofLocalSpace * localForwardVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits; + Vector3 localUpVectorScaled_unturned_inGlobalSpaceUnits = rotation_ofLocalSpace * localUpVector_unturned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits; + + Vector3 localForwardVectorScaled_turned_inGlobalSpaceUnits = rotation_ofLocalSpace * localForwardVector_turned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits; + Vector3 localUpVectorScaled_turned_inGlobalSpaceUnits = rotation_ofLocalSpace * localUpVector_turned_inLocalSpaceUnits_scaledSoItFitsGlobalUnits; + + Color color_of90DegSymbolBeforeRotation = Color.Lerp(color_ofUnturnedForwardVector, color_ofUnturnedUpVector, 0.5f); + UtilitiesDXXL_Quaternion.Draw90DegSymbolToQuaternionVectorPair(color_of90DegSymbolBeforeRotation, posWhereToDraw, localForwardVectorScaled_unturned_inGlobalSpaceUnits, localUpVectorScaled_unturned_inGlobalSpaceUnits, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Quaternion.DrawSquareArea_spannedByUpAndForward(false, posWhereToDraw, localForwardVectorScaled_unturned_inGlobalSpaceUnits, localUpVectorScaled_unturned_inGlobalSpaceUnits, color_ofUnturnedForwardVector, color_ofUnturnedUpVector, 1.3f * alpha_ofSquareSpannedByForwardAndUp, 0.1f, durationInSec, hiddenByNearerObjects); + + if (rotationIsApproxIdentity == false) + { + Color color_of90DegSymbolAfterRotation = Color.Lerp(color_ofTurnedForwardVector, color_ofTurnedUpVector, 0.5f); + UtilitiesDXXL_Quaternion.Draw90DegSymbolToQuaternionVectorPair(color_of90DegSymbolAfterRotation, posWhereToDraw, localForwardVectorScaled_turned_inGlobalSpaceUnits, localUpVectorScaled_turned_inGlobalSpaceUnits, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Quaternion.DrawSquareArea_spannedByUpAndForward(false, posWhereToDraw, localForwardVectorScaled_turned_inGlobalSpaceUnits, localUpVectorScaled_turned_inGlobalSpaceUnits, color_ofTurnedForwardVector, color_ofTurnedUpVector, alpha_ofSquareSpannedByForwardAndUp, 0.1f, durationInSec, hiddenByNearerObjects); + } + } + + static float DrawRotationOfCustomVector(Vector3 customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits, Vector3 customVectorToTurn_unturned_inLocalSpaceUnits_butAlreadyScaledSoLengthFitsGlobalUnits, Color color_darkVariant, Color color_brightVariant, string vectorName, Vector3 posWhereToDraw, Vector3 eulerAnglesToDraw, Quaternion rotation_ofLocalSpace, Vector3 xAxis_rotated_inGlobalSpace_normalized, Vector3 yAxis_rotated_inGlobalSpace_normalized, Vector3 zAxis_rotated_inGlobalSpace_normalized, Quaternion localEulerRotationAroundRotatedXAxis, Quaternion localEulerRotationAroundYAxis, Quaternion localEulerRotationAroundRotatedZAxis, float gimbalSize, bool rotationIsApproxIdentity, bool isLocal, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 vectorToTurn_rotatedOnlyAroundYAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits = localEulerRotationAroundYAxis * customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits; + Vector3 vectorToTurn_rotatedAroundYAxisThenXAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits = localEulerRotationAroundRotatedXAxis * vectorToTurn_rotatedOnlyAroundYAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits; + Vector3 vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits = localEulerRotationAroundRotatedZAxis * vectorToTurn_rotatedAroundYAxisThenXAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits; + + Vector3 vectorToTurn_rotatedOnlyAroundYAxis_inLocalSpaceUnits = localEulerRotationAroundYAxis * customVectorToTurn_unturned_inLocalSpaceUnits_butAlreadyScaledSoLengthFitsGlobalUnits; + Vector3 vectorToTurn_rotatedAroundYAxisThenXAxis_inLocalSpaceUnits = localEulerRotationAroundRotatedXAxis * vectorToTurn_rotatedOnlyAroundYAxis_inLocalSpaceUnits; + Vector3 vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inLocalSpaceUnits = localEulerRotationAroundRotatedZAxis * vectorToTurn_rotatedAroundYAxisThenXAxis_inLocalSpaceUnits; + + Vector3 aVector_unturned_inGlobalSpaceUnits = rotation_ofLocalSpace * customVectorToTurn_unturned_inLocalSpaceUnits_butAlreadyScaledSoLengthFitsGlobalUnits; + Vector3 vectorToTurn_rotatedOnlyAroundYAxis_inGlobalSpaceUnits = rotation_ofLocalSpace * vectorToTurn_rotatedOnlyAroundYAxis_inLocalSpaceUnits; + Vector3 vectorToTurn_rotatedAroundYAxisThenXAxis_inGlobalSpaceUnits = rotation_ofLocalSpace * vectorToTurn_rotatedAroundYAxisThenXAxis_inLocalSpaceUnits; + Vector3 vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inGlobalSpaceUnits = rotation_ofLocalSpace * vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inLocalSpaceUnits; + + Vector3 endPos_ofAVectorUnturned_inGlobalSpaceUnits = posWhereToDraw + aVector_unturned_inGlobalSpaceUnits; + Vector3 endPos_of_vectorToTurn_rotatedOnlyAroundYAxis_inGlobalSpaceUnits = posWhereToDraw + vectorToTurn_rotatedOnlyAroundYAxis_inGlobalSpaceUnits; + Vector3 endPos_of_vectorToTurn_rotatedAroundYAxisThenXAxis_inGlobalSpaceUnits = posWhereToDraw + vectorToTurn_rotatedAroundYAxisThenXAxis_inGlobalSpaceUnits; + + Color color_ofThinFullCircle_x = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.red_xAxisAlpha1, 0.33f); + Color color_ofThinFullCircle_y = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.green_yAxisAlpha1, 0.28f); + Color color_ofThinFullCircle_z = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.blue_zAxisAlpha1, 0.4f); + + Color color_forAccentuatedVector_x = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.red_xAxisAlpha1, 0.8f); + Color color_forAccentuatedVector_y = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.green_yAxisAlpha1, 0.68f); + Color color_forAccentuatedVector_z = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.blue_zAxisAlpha1, 0.9f); + + float maxAbsDistance_ofAnyPlumbPos_toTurnCenter = 0.0f; + float absDistance_ofPlumbPos_toTurnCenter; + absDistance_ofPlumbPos_toTurnCenter = DrawAVectorsTurningAroundOneAxis(posWhereToDraw, endPos_ofAVectorUnturned_inGlobalSpaceUnits, yAxis_rotated_inGlobalSpace_normalized, eulerAnglesToDraw.y, rotatedYAxis_line_inGlobalSpaceUnits, color_forAccentuatedVector_y, color_ofThinFullCircle_y, gimbalSize, durationInSec, hiddenByNearerObjects); + maxAbsDistance_ofAnyPlumbPos_toTurnCenter = Mathf.Max(absDistance_ofPlumbPos_toTurnCenter, maxAbsDistance_ofAnyPlumbPos_toTurnCenter); + absDistance_ofPlumbPos_toTurnCenter = DrawAVectorsTurningAroundOneAxis(posWhereToDraw, endPos_of_vectorToTurn_rotatedOnlyAroundYAxis_inGlobalSpaceUnits, xAxis_rotated_inGlobalSpace_normalized, eulerAnglesToDraw.x, rotatedXAxis_line_inGlobalSpaceUnits, color_forAccentuatedVector_x, color_ofThinFullCircle_x, gimbalSize, durationInSec, hiddenByNearerObjects); + maxAbsDistance_ofAnyPlumbPos_toTurnCenter = Mathf.Max(absDistance_ofPlumbPos_toTurnCenter, maxAbsDistance_ofAnyPlumbPos_toTurnCenter); + absDistance_ofPlumbPos_toTurnCenter = DrawAVectorsTurningAroundOneAxis(posWhereToDraw, endPos_of_vectorToTurn_rotatedAroundYAxisThenXAxis_inGlobalSpaceUnits, zAxis_rotated_inGlobalSpace_normalized, eulerAnglesToDraw.z, rotatedZAxis_line_inGlobalSpaceUnits, color_forAccentuatedVector_z, color_ofThinFullCircle_z, gimbalSize, durationInSec, hiddenByNearerObjects); + maxAbsDistance_ofAnyPlumbPos_toTurnCenter = Mathf.Max(absDistance_ofPlumbPos_toTurnCenter, maxAbsDistance_ofAnyPlumbPos_toTurnCenter); + + string text_atUnturnedCustomVector; + if (rotationIsApproxIdentity) + { + text_atUnturnedCustomVector = isLocal ? (vectorName + "

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

unrotated
=after rotation
x = " + customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.x + "
y = " + customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.y + "
z = " + customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.z + ""); + } + else + { + text_atUnturnedCustomVector = isLocal ? (vectorName + "

unrotated
localx = " + customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.x + "
localy = " + customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.y + "
localz = " + customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.z + "") : (vectorName + "

unrotated
x = " + customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.x + "
y = " + customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.y + "
z = " + customVectorToTurn_unturned_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.z + ""); + } + DrawBasics.VectorFrom(posWhereToDraw, aVector_unturned_inGlobalSpaceUnits, color_darkVariant, 0.0f, text_atUnturnedCustomVector, 0.17f, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + + if (rotationIsApproxIdentity == false) + { + string text_atTurnedCustomVector = isLocal ? (vectorName + "

after rotation
localx = " + vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.x + "
localy = " + vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.y + "
localz = " + vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.z + "") : (vectorName + "

after rotation
x = " + vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.x + "
y = " + vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.y + "
z = " + vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inLocalSpaceUnits_lengthStillFitsLocalSpaceUnits.z + ""); + DrawBasics.VectorFrom(posWhereToDraw, vectorToTurn_rotatedAroundYAxisThenXAxisThenZAxis_inGlobalSpaceUnits, color_brightVariant, 0.0f, text_atTurnedCustomVector, 0.17f, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + } + + return maxAbsDistance_ofAnyPlumbPos_toTurnCenter; + } + + static float DrawAVectorsTurningAroundOneAxis(Vector3 posWhereToDraw, Vector3 endPos_ofAVectorToTurn_preTurn_inGlobalSpaceUnits, Vector3 axisToTurnAround_rotated_inGlobalSpace_normalized, float eulerAnglesToDraw_ofConcernedAxis, InternalDXXL_Line line_describingTheTurnedGizmoAxis, Color color_forAccentuatedVector, Color color_ofThinFullCircle, float gimbalSize, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 plumbPos_ofUnturnedVectorOnTurnAxis = line_describingTheTurnedGizmoAxis.Get_perpProjectionOfPoint_ontoThisLine(endPos_ofAVectorToTurn_preTurn_inGlobalSpaceUnits); + Vector3 fromPlumbPos_toUnturnedVectorsPeak = endPos_ofAVectorToTurn_preTurn_inGlobalSpaceUnits - plumbPos_ofUnturnedVectorOnTurnAxis; + float absDistance_ofPlumbPos_toTurnCenter = (plumbPos_ofUnturnedVectorOnTurnAxis - posWhereToDraw).magnitude; + float radius = fromPlumbPos_toUnturnedVectorsPeak.magnitude; + if (radius > 0.01f) + { + DrawShapes.Circle(plumbPos_ofUnturnedVectorOnTurnAxis, radius, color_ofThinFullCircle, axisToTurnAround_rotated_inGlobalSpace_normalized, fromPlumbPos_toUnturnedVectorsPeak, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + float absTurnAngleDeg = Mathf.Abs(eulerAnglesToDraw_ofConcernedAxis); + float drawnTurnAngleDeg = Loop360degProtrudingAngle_toDrawableNon360_isIntoSpan_fromExclM360_toExclP360(eulerAnglesToDraw_ofConcernedAxis); + float absDrawnTurnAngleDeg = Mathf.Abs(drawnTurnAngleDeg); + float lineWidth_ofCircledArrow = gimbalSize * 0.0096f; + + bool absAngle_isBiggerOrEqualThan360deg = Mathf.Abs(absTurnAngleDeg) >= 360.0f; + if (absAngle_isBiggerOrEqualThan360deg) + { + //using "FlatShape()" instead of "Circle()" because it has a "flattenRoundLines_intoShapePlane"-parameter + float diameter = 2.0f * radius; + DrawShapes.FlatShape(plumbPos_ofUnturnedVectorOnTurnAxis, DrawShapes.Shape2DType.circle, diameter, diameter, color_forAccentuatedVector, axisToTurnAround_rotated_inGlobalSpace_normalized, default(Vector3), lineWidth_ofCircledArrow, null, DrawBasics.LineStyle.solid, 1.0f, false, DrawBasics.LineStyle.invisible, false, durationInSec, hiddenByNearerObjects); + } + + if (absDrawnTurnAngleDeg >= 0.5f) + { + float absConeLength_ofCircledVectors_thatDisplaysThePerAxisCustomVectorTurning = gimbalSize * 0.08f; + + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + DrawBasics.VectorCircled(endPos_ofAVectorToTurn_preTurn_inGlobalSpaceUnits, plumbPos_ofUnturnedVectorOnTurnAxis, axisToTurnAround_rotated_inGlobalSpace_normalized, drawnTurnAngleDeg, color_forAccentuatedVector, lineWidth_ofCircledArrow, null, absConeLength_ofCircledVectors_thatDisplaysThePerAxisCustomVectorTurning, false, false, false, 0.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); + } + + if (absTurnAngleDeg >= 0.5f) + { + if (absTurnAngleDeg < (2.0f * angleDeg_betweenTurnedCircleSlice_visualizerLines)) + { + Quaternion rotation_from_toStartDir_to_middleOfStartAndEndDir = Quaternion.AngleAxis(0.5f * absTurnAngleDeg, axisToTurnAround_rotated_inGlobalSpace_normalized); + Vector3 plumbPos_to_endPosOfSingleSliceVisualizerStrut = rotation_from_toStartDir_to_middleOfStartAndEndDir * fromPlumbPos_toUnturnedVectorsPeak; + Line_fadeableAnimSpeed.InternalDraw(plumbPos_ofUnturnedVectorOnTurnAxis, plumbPos_ofUnturnedVectorOnTurnAxis + plumbPos_to_endPosOfSingleSliceVisualizerStrut, color_ofThinFullCircle, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + float turnAngleDeg_ofCurrSliceVisualizerStrut = 0.0f; + int maxStruts_minus1 = 10000; + for (int i_strut = 0; i_strut <= maxStruts_minus1; i_strut++) + { + if (i_strut == maxStruts_minus1) + { + UtilitiesDXXL_Log.PrintErrorCode("28-" + eulerAnglesToDraw_ofConcernedAxis + "-" + angleDeg_betweenTurnedCircleSlice_visualizerLines); + } + + if (eulerAnglesToDraw_ofConcernedAxis > 0.0f) + { + turnAngleDeg_ofCurrSliceVisualizerStrut = turnAngleDeg_ofCurrSliceVisualizerStrut + angleDeg_betweenTurnedCircleSlice_visualizerLines; + if (turnAngleDeg_ofCurrSliceVisualizerStrut > eulerAnglesToDraw_ofConcernedAxis) + { + break; + } + } + else + { + turnAngleDeg_ofCurrSliceVisualizerStrut = turnAngleDeg_ofCurrSliceVisualizerStrut - angleDeg_betweenTurnedCircleSlice_visualizerLines; + if (turnAngleDeg_ofCurrSliceVisualizerStrut < eulerAnglesToDraw_ofConcernedAxis) + { + break; + } + } + Quaternion rotation_from_toStartDir_to_currSliceVisualizerStrut = Quaternion.AngleAxis(turnAngleDeg_ofCurrSliceVisualizerStrut, axisToTurnAround_rotated_inGlobalSpace_normalized); + Vector3 plumbPos_to_endPosOfCurrSliceVisualizerStrut = rotation_from_toStartDir_to_currSliceVisualizerStrut * fromPlumbPos_toUnturnedVectorsPeak; + Line_fadeableAnimSpeed.InternalDraw(plumbPos_ofUnturnedVectorOnTurnAxis, plumbPos_ofUnturnedVectorOnTurnAxis + plumbPos_to_endPosOfCurrSliceVisualizerStrut, color_ofThinFullCircle, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + + //accentuated straight border lines of pieSlices: + Quaternion rotation_from_toStartDir_to_toEndDir = Quaternion.AngleAxis(eulerAnglesToDraw_ofConcernedAxis, axisToTurnAround_rotated_inGlobalSpace_normalized); + Vector3 plumbPos_to_endPosOfWholeRotation = rotation_from_toStartDir_to_toEndDir * fromPlumbPos_toUnturnedVectorsPeak; + + Line_fadeableAnimSpeed.InternalDraw(plumbPos_ofUnturnedVectorOnTurnAxis, plumbPos_ofUnturnedVectorOnTurnAxis + fromPlumbPos_toUnturnedVectorsPeak, color_forAccentuatedVector, 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(plumbPos_ofUnturnedVectorOnTurnAxis, plumbPos_ofUnturnedVectorOnTurnAxis + plumbPos_to_endPosOfWholeRotation, color_forAccentuatedVector, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + return absDistance_ofPlumbPos_toTurnCenter; + } + + static void DrawThinDashedAxesProlongations(Vector3 xAxis_startPos_inGlobalSpace, Vector3 xAxis_endPos_inGlobalSpace, Vector3 yAxis_startPos_inGlobalSpace, Vector3 yAxis_endPos_inGlobalSpace, Vector3 zAxis_startPos_inGlobalSpace, Vector3 zAxis_endPos_inGlobalSpace, Vector3 xAxis_rotated_inGlobalSpace_normalized, Vector3 yAxis_rotated_inGlobalSpace_normalized, Vector3 zAxis_rotated_inGlobalSpace_normalized, float axesLength_toEachSideFromDrawCenter, float maxAbsDistance_ofAnyPlumbPos_toTurnCenter, float durationInSec, bool hiddenByNearerObjects) + { + float length_ofAxesInclProlongation_perSideFromDrawCenter = maxAbsDistance_ofAnyPlumbPos_toTurnCenter * 1.6f; + float length_ofAxesProlongations = length_ofAxesInclProlongation_perSideFromDrawCenter - axesLength_toEachSideFromDrawCenter; + float stylePatternScaleFactor = axesLength_toEachSideFromDrawCenter * 7.0f; + DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.dashed; + + Color color_ofXAxisProlongation = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.red_xAxisAlpha1, 0.55f); + Line_fadeableAnimSpeed.InternalDraw(xAxis_startPos_inGlobalSpace, xAxis_startPos_inGlobalSpace - xAxis_rotated_inGlobalSpace_normalized * length_ofAxesProlongations, color_ofXAxisProlongation, 0.0f, null, lineStyle, stylePatternScaleFactor, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true); + Line_fadeableAnimSpeed.InternalDraw(xAxis_endPos_inGlobalSpace, xAxis_endPos_inGlobalSpace + xAxis_rotated_inGlobalSpace_normalized * length_ofAxesProlongations, color_ofXAxisProlongation, 0.0f, null, lineStyle, stylePatternScaleFactor, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true); + + Color color_ofYAxisProlongation = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.green_yAxisAlpha1, 0.3f); + Line_fadeableAnimSpeed.InternalDraw(yAxis_startPos_inGlobalSpace, yAxis_startPos_inGlobalSpace - yAxis_rotated_inGlobalSpace_normalized * length_ofAxesProlongations, color_ofYAxisProlongation, 0.0f, null, lineStyle, stylePatternScaleFactor, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true); + Line_fadeableAnimSpeed.InternalDraw(yAxis_endPos_inGlobalSpace, yAxis_endPos_inGlobalSpace + yAxis_rotated_inGlobalSpace_normalized * length_ofAxesProlongations, color_ofYAxisProlongation, 0.0f, null, lineStyle, stylePatternScaleFactor, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true); + + Color color_ofZAxisProlongation = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.blue_zAxisAlpha1, 0.72f); + Line_fadeableAnimSpeed.InternalDraw(zAxis_startPos_inGlobalSpace, zAxis_startPos_inGlobalSpace - zAxis_rotated_inGlobalSpace_normalized * length_ofAxesProlongations, color_ofZAxisProlongation, 0.0f, null, lineStyle, stylePatternScaleFactor, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true); + Line_fadeableAnimSpeed.InternalDraw(zAxis_endPos_inGlobalSpace, zAxis_endPos_inGlobalSpace + zAxis_rotated_inGlobalSpace_normalized * length_ofAxesProlongations, color_ofZAxisProlongation, 0.0f, null, lineStyle, stylePatternScaleFactor, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Euler.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Euler.cs.meta new file mode 100644 index 0000000..02c2653 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Euler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da429c64dddc06144ad1fa180ab7d22a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_FlatShapesNormaAndUpCalculation.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_FlatShapesNormaAndUpCalculation.cs new file mode 100644 index 0000000..5ec65ea --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_FlatShapesNormaAndUpCalculation.cs @@ -0,0 +1,191 @@ +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; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_FlatShapesNormaAndUpCalculation.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_FlatShapesNormaAndUpCalculation.cs.meta new file mode 100644 index 0000000..aff0055 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_FlatShapesNormaAndUpCalculation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9018882579d4a74d9a3da6c10cb4332 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Grid.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Grid.cs new file mode 100644 index 0000000..d60279b --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Grid.cs @@ -0,0 +1,1853 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_Grid + { + public static bool forceSkip_drawingLocalOrigin = false; + public static bool forceSkip_drawAroundPosVisualizationLocal = false; + static float gridDensityDefaultScaleFactor = 0.148f; + static Color colorFor_skewedPosIndicatingCubes = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(Color.black, 0.5f); + static float alphaCascadingFactorForNextSmallerOrder = 0.8f; + static float alphaCascadingFactorForNextSmallerOrder_forPointsBlackOverdraw = 0.7f; + public static float min_distanceBetweenRepeatingCoordsTexts_relToGridDistance = 5.0f; + public static bool default_hide_distanceDisplay_forGrids = false; + public static float default_offsetForDistanceDisplays_inGrids = 0.65f; + public static float default_offsetForCoordinateTextDisplays_inGrids = -1.0f; + public static float default_coveredGridUnits_rel_forGridPlanes = 2.5f; + public static float default_sizeScalingForCoordinateTexts_inGrids = 0.25f; + public const float min_sizeScalingForCoordinateTexts_inGrids = 0.01f; + static float rel_spaceBetweenLineAndCoordsText = 0.035f; + + public static void GridPlanes(bool drawXDim, bool drawYDim, bool drawZDim, Vector3 positionAroundWhichToDraw, float extentOfEachGridPlane_rel, float drawDensity, bool draw1000grid, bool draw100grid, bool draw10grid, bool draw1grid, bool draw0p1grid, bool draw0p01grid, bool draw0p001grid, float distanceBetweenRepeatingCoordsTexts_relToGridDistance, Color overwriteColorForX, Color overwriteColorForY, Color overwriteColorForZ, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(extentOfEachGridPlane_rel, "extentOfEachGridPlane_rel")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(drawDensity, "drawDensity")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceBetweenRepeatingCoordsTexts_relToGridDistance, "distanceBetweenRepeatingCoordsTexts_relToGridDistance")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(positionAroundWhichToDraw, "positionAroundWhichToDraw")) { return; } + + float distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder = Get_distanceBetweenVisualizedGridPointsInVisualizedCoordSystemUnits_ofBiggestOrder(out int numberOfDrawnOrders, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid); + + Color colorForMainX = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForX, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.red_xAxis : UtilitiesDXXL_Colors.red_xAxisAlpha1); + Color colorForMainY = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForY, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.green_yAxis : UtilitiesDXXL_Colors.green_yAxisAlpha1); + Color colorForMainZ = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForZ, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.blue_zAxis : UtilitiesDXXL_Colors.blue_zAxisAlpha1); + + if (numberOfDrawnOrders == 0) + { + Color fallbackColor = GetFallbackColor(drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ); + UtilitiesDXXL_DrawBasics.PointFallback(positionAroundWhichToDraw, "[ GridPlanes with 0 numberOfDrawnMagnitudeOrders]", fallbackColor, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + extentOfEachGridPlane_rel = UtilitiesDXXL_Math.AbsNonZeroValue(extentOfEachGridPlane_rel); + extentOfEachGridPlane_rel = Mathf.Max(extentOfEachGridPlane_rel, 0.1f); + + float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits = 0.5f * extentOfEachGridPlane_rel; + float sizeOfDrawnGridArea = DrawEngineBasics.coveredGridUnits_rel_forGridPlanes * distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder; + float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits = 0.5f * (sizeOfDrawnGridArea / distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder); + float alphaForUpcomingOrderColors = 1.0f; + float alphaForUpcomingOrdersBlackPosMarker = 0.4f; + + //biggest order: + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude(distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + + //smaller orders: + if (draw1000grid) + { + //->is already biggest/cannot be a smaller order + } + if (draw100grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 100.0f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude(100.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + } + if (draw10grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 10.0f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude(10.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + } + if (draw1grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 1.0f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude(1.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + } + if (draw0p1grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 0.1f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude(0.1f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + } + if (draw0p01grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 0.01f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude(0.01f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + } + if (draw0p001grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 0.001f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude(0.001f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + } + + } + + public static void GridPlanesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, bool drawXDim, bool drawYDim, bool drawZDim, Vector3 localPositionAroundWhichToDraw, float extentOfEachGridPlane_rel_inLocalSpaceUnits, float drawDensity, bool draw1000grid, bool draw100grid, bool draw10grid, bool draw1grid, bool draw0p1grid, bool draw0p01grid, bool draw0p001grid, float distanceBetweenRepeatingCoordsTexts_relToGridDistance, Color overwriteColorForX, Color overwriteColorForY, Color overwriteColorForZ, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(extentOfEachGridPlane_rel_inLocalSpaceUnits, "extentOfEachGridPlane_rel_inLocalSpaceUnits")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(drawDensity, "drawDensity")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceBetweenRepeatingCoordsTexts_relToGridDistance, "distanceBetweenRepeatingCoordsTexts_relToGridDistance")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(originOfLocalSpace, "originOfLocalSpace")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(scaleOfLocalSpace, "scaleOfLocalSpace")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(localPositionAroundWhichToDraw, "localPositionAroundWhichToDraw")) { return; } + + rotationOfLocalSpace = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotationOfLocalSpace); + + float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder = Get_distanceBetweenVisualizedGridPointsInVisualizedCoordSystemUnits_ofBiggestOrder(out int numberOfDrawnOrders, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid); + + Color colorForMainX = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForX, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.red_xAxis : UtilitiesDXXL_Colors.red_xAxisAlpha1); + Color colorForMainY = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForY, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.green_yAxis : UtilitiesDXXL_Colors.green_yAxisAlpha1); + Color colorForMainZ = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForZ, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.blue_zAxis : UtilitiesDXXL_Colors.blue_zAxisAlpha1); + + if (numberOfDrawnOrders == 0) + { + Color fallbackColor = GetFallbackColor(drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ); + UtilitiesDXXL_DrawBasics.PointFallback(originOfLocalSpace, "[ GridPlanesLocal with 0 numberOfDrawnMagnitudeOrders]", fallbackColor, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + if (drawXDim) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(scaleOfLocalSpace.x)) + { + drawXDim = false; + UtilitiesDXXL_DrawBasics.PointFallback(originOfLocalSpace, "[ GridPlanesLocal x-dimension scale of 0]", colorForMainX, 0.0f, durationInSec, hiddenByNearerObjects); + } + } + if (drawYDim) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(scaleOfLocalSpace.y)) + { + drawYDim = false; + UtilitiesDXXL_DrawBasics.PointFallback(originOfLocalSpace, "[ GridPlanesLocal y-dimension scale of 0]", colorForMainY, 0.0f, durationInSec, hiddenByNearerObjects); + } + } + if (drawZDim) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(scaleOfLocalSpace.z)) + { + drawZDim = false; + UtilitiesDXXL_DrawBasics.PointFallback(originOfLocalSpace, "[ GridPlanesLocal z-dimension scale of 0]", colorForMainZ, 0.0f, durationInSec, hiddenByNearerObjects); + } + } + if ((drawXDim == false) && (drawYDim == false) && (drawZDim == false)) { return; } + + extentOfEachGridPlane_rel_inLocalSpaceUnits = UtilitiesDXXL_Math.AbsNonZeroValue(extentOfEachGridPlane_rel_inLocalSpaceUnits); + extentOfEachGridPlane_rel_inLocalSpaceUnits = Mathf.Max(extentOfEachGridPlane_rel_inLocalSpaceUnits, 0.1f); + + float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits = 0.5f * extentOfEachGridPlane_rel_inLocalSpaceUnits; + float sizeOfDrawnGridArea_inLocalSpaceUnits = DrawEngineBasics.coveredGridUnits_rel_forGridPlanes * distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder; + float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits = 0.5f * (sizeOfDrawnGridArea_inLocalSpaceUnits / distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder); + float alphaForUpcomingOrderColors = 1.0f; + float alphaForUpcomingOrdersBlackPosMarker = 0.4f; + + Vector3 localForward_normalizedInGlobalSpace = rotationOfLocalSpace * Vector3.forward; + Vector3 localUp_normalizedInGlobalSpace = rotationOfLocalSpace * Vector3.up; + Vector3 localRight_normalizedInGlobalSpace = rotationOfLocalSpace * Vector3.right; + Vector3 positionAroundWhichToDraw_global = originOfLocalSpace + localRight_normalizedInGlobalSpace * scaleOfLocalSpace.x * localPositionAroundWhichToDraw.x + localUp_normalizedInGlobalSpace * scaleOfLocalSpace.y * localPositionAroundWhichToDraw.y + localForward_normalizedInGlobalSpace * scaleOfLocalSpace.z * localPositionAroundWhichToDraw.z; + + //biggest order: + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance, true); + + //smaller orders: + if (draw1000grid) + { + //->is already biggest/cannot be a smaller order + } + if (draw100grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 100.0f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(100.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance, false); + } + } + if (draw10grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 10.0f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(10.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance, false); + } + } + if (draw1grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 1.0f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(1.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance, false); + } + } + if (draw0p1grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 0.1f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(0.1f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance, false); + } + } + if (draw0p01grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 0.01f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(0.01f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance, false); + } + } + if (draw0p001grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 0.001f) + { + DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(0.001f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance, false); + } + } + + } + + public static void GridLines(Vector3 positionAroundWhichToDraw, float coveredGridUnits_rel, float lengthOfEachGridLine_rel, float linesWidth_signFlipsPerp, bool drawXDim, bool drawYDim, bool drawZDim, bool draw1000grid, bool draw100grid, bool draw10grid, bool draw1grid, bool draw0p1grid, bool draw0p01grid, bool draw0p001grid, float distanceBetweenRepeatingCoordsTexts_relToGridDistance, Color overwriteColorForX, Color overwriteColorForY, Color overwriteColorForZ, float durationInSec, bool hiddenByNearerObjects, DrawEngineBasics.XGridLinesOrientation orientation_ofXLines, DrawEngineBasics.YGridLinesOrientation orientation_ofYLines, DrawEngineBasics.ZGridLinesOrientation orientation_ofZLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(coveredGridUnits_rel, "coveredGridUnits_rel")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lengthOfEachGridLine_rel, "lengthOfEachGridLine_rel")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth_signFlipsPerp, "linesWidth_signFlipsPerp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceBetweenRepeatingCoordsTexts_relToGridDistance, "distanceBetweenRepeatingCoordsTexts_relToGridDistance")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(positionAroundWhichToDraw, "positionAroundWhichToDraw")) { return; } + + float distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder = Get_distanceBetweenVisualizedGridPointsInVisualizedCoordSystemUnits_ofBiggestOrder(out int numberOfDrawnOrders, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid); + Color colorForMainX = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForX, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.red_xAxis : UtilitiesDXXL_Colors.red_xAxisAlpha1); + Color colorForMainY = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForY, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.green_yAxis : UtilitiesDXXL_Colors.green_yAxisAlpha1); + Color colorForMainZ = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForZ, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.blue_zAxis : UtilitiesDXXL_Colors.blue_zAxisAlpha1); + + if (numberOfDrawnOrders == 0) + { + Color fallbackColor = GetFallbackColor(drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ); + UtilitiesDXXL_DrawBasics.PointFallback(positionAroundWhichToDraw, "[ GridLines with 0 numberOfDrawnMagnitudeOrders]", fallbackColor, linesWidth_signFlipsPerp, durationInSec, hiddenByNearerObjects); + return; + } + + coveredGridUnits_rel = UtilitiesDXXL_Math.AbsNonZeroValue(coveredGridUnits_rel); + coveredGridUnits_rel = Mathf.Max(coveredGridUnits_rel, 2.5f); + + lengthOfEachGridLine_rel = UtilitiesDXXL_Math.AbsNonZeroValue(lengthOfEachGridLine_rel); + lengthOfEachGridLine_rel = Mathf.Max(lengthOfEachGridLine_rel, 0.1f); + + float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits = 0.5f * lengthOfEachGridLine_rel; + float alphaForUpcomingOrderColors = 1.0f; + float alphaForUpcomingOrdersBlackPosMarker = 0.4f; + + //biggest order: + float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits = 0.5f * coveredGridUnits_rel; + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude(distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + + //smaller orders: + //extentOfWholeCascadeAlongAxis_inOrdersOwnUnits = 6.5f; + if (draw1000grid) + { + //->is already biggest/cannot be a smaller order + } + if (draw100grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 100.0f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude(100.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + if (draw10grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 10.0f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude(10.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + if (draw1grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 1.0f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude(1.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + if (draw0p1grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 0.1f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude(0.1f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + if (draw0p01grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 0.01f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude(0.01f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + if (draw0p001grid) + { + if (distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder > 0.001f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude(0.001f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_signFlipsPerp, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + + } + + public static void GridLinesLocal(Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float coveredGridUnits_rel_inLocalSpaceUnits, float lengthOfDrawnLines_inLocalSpaceUnits, float linesWidth_inLocalSpaceUnits_signFlipsPerp, bool drawXDim, bool drawYDim, bool drawZDim, bool draw1000grid, bool draw100grid, bool draw10grid, bool draw1grid, bool draw0p1grid, bool draw0p01grid, bool draw0p001grid, float distanceBetweenRepeatingCoordsTexts_relToGridDistance, Color overwriteColorForX, Color overwriteColorForY, Color overwriteColorForZ, float durationInSec, bool hiddenByNearerObjects, DrawEngineBasics.XGridLinesOrientation orientation_ofXLines, DrawEngineBasics.YGridLinesOrientation orientation_ofYLines, DrawEngineBasics.ZGridLinesOrientation orientation_ofZLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(coveredGridUnits_rel_inLocalSpaceUnits, "coveredGridUnits_rel_inLocalSpaceUnits")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lengthOfDrawnLines_inLocalSpaceUnits, "lengthOfDrawnLines_inLocalSpaceUnits")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth_inLocalSpaceUnits_signFlipsPerp, "linesWidth_inLocalSpaceUnits_signFlipsPerp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceBetweenRepeatingCoordsTexts_relToGridDistance, "distanceBetweenRepeatingCoordsTexts_relToGridDistance")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(localPositionAroundWhichToDraw, "positionAroundWhichToDraw")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(scaleOfLocalSpace, "scaleOfLocalSpace")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(originOfLocalSpace, "originOfLocalSpace")) { return; } + + rotationOfLocalSpace = UtilitiesDXXL_Math.OverwriteDefaultQuaternionToIdentity(rotationOfLocalSpace); + + float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder = Get_distanceBetweenVisualizedGridPointsInVisualizedCoordSystemUnits_ofBiggestOrder(out int numberOfDrawnOrders, draw1000grid, draw100grid, draw10grid, draw1grid, draw0p1grid, draw0p01grid, draw0p001grid); + Color colorForMainX = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForX, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.red_xAxis : UtilitiesDXXL_Colors.red_xAxisAlpha1); + Color colorForMainY = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForY, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.green_yAxis : UtilitiesDXXL_Colors.green_yAxisAlpha1); + Color colorForMainZ = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColorForZ, (numberOfDrawnOrders == 1) ? UtilitiesDXXL_Colors.blue_zAxis : UtilitiesDXXL_Colors.blue_zAxisAlpha1); + + if (numberOfDrawnOrders == 0) + { + Color fallbackColor = GetFallbackColor(drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ); + UtilitiesDXXL_DrawBasics.PointFallback(originOfLocalSpace, "[ GridLinesLocal with 0 numberOfDrawnMagnitudeOrders]", fallbackColor, linesWidth_inLocalSpaceUnits_signFlipsPerp, durationInSec, hiddenByNearerObjects); + return; + } + + if (drawXDim) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(scaleOfLocalSpace.x)) + { + drawXDim = false; + UtilitiesDXXL_DrawBasics.PointFallback(originOfLocalSpace, "[ GridLinesLocal x-dimension scale of 0]", colorForMainX, linesWidth_inLocalSpaceUnits_signFlipsPerp, durationInSec, hiddenByNearerObjects); + } + } + if (drawYDim) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(scaleOfLocalSpace.y)) + { + drawYDim = false; + UtilitiesDXXL_DrawBasics.PointFallback(originOfLocalSpace, "[ GridLinesLocal y-dimension scale of 0]", colorForMainY, linesWidth_inLocalSpaceUnits_signFlipsPerp, durationInSec, hiddenByNearerObjects); + } + } + if (drawZDim) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(scaleOfLocalSpace.z)) + { + drawZDim = false; + UtilitiesDXXL_DrawBasics.PointFallback(originOfLocalSpace, "[ GridLinesLocal z-dimension scale of 0]", colorForMainZ, linesWidth_inLocalSpaceUnits_signFlipsPerp, durationInSec, hiddenByNearerObjects); + } + } + if ((drawXDim == false) && (drawYDim == false) && (drawZDim == false)) { return; } + + coveredGridUnits_rel_inLocalSpaceUnits = UtilitiesDXXL_Math.AbsNonZeroValue(coveredGridUnits_rel_inLocalSpaceUnits); + coveredGridUnits_rel_inLocalSpaceUnits = Mathf.Max(coveredGridUnits_rel_inLocalSpaceUnits, 2.5f); + + lengthOfDrawnLines_inLocalSpaceUnits = UtilitiesDXXL_Math.AbsNonZeroValue(lengthOfDrawnLines_inLocalSpaceUnits); + lengthOfDrawnLines_inLocalSpaceUnits = Mathf.Max(lengthOfDrawnLines_inLocalSpaceUnits, 0.1f); + + float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits = 0.5f * lengthOfDrawnLines_inLocalSpaceUnits; + float alphaForUpcomingOrderColors = 1.0f; + float alphaForUpcomingOrdersBlackPosMarker = 0.4f; + + Vector3 localForward_normalizedInGlobalSpace = rotationOfLocalSpace * Vector3.forward; + Vector3 localUp_normalizedInGlobalSpace = rotationOfLocalSpace * Vector3.up; + Vector3 localRight_normalizedInGlobalSpace = rotationOfLocalSpace * Vector3.right; + Vector3 positionAroundWhichToDraw_global = originOfLocalSpace + localRight_normalizedInGlobalSpace * scaleOfLocalSpace.x * localPositionAroundWhichToDraw.x + localUp_normalizedInGlobalSpace * scaleOfLocalSpace.y * localPositionAroundWhichToDraw.y + localForward_normalizedInGlobalSpace * scaleOfLocalSpace.z * localPositionAroundWhichToDraw.z; + + //biggest order: + float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits = 0.5f * coveredGridUnits_rel_inLocalSpaceUnits; + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_inLocalSpaceUnits_signFlipsPerp, true, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + + //smaller orders: + //extentOfWholeCascadeAlongAxis_inOrdersOwnUnits = 6.5f; + if (draw1000grid) + { + //->is already biggest/cannot be a smaller order + } + if (draw100grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 100.0f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(100.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + if (draw10grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 10.0f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(10.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + if (draw1grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 1.0f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(1.0f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + if (draw0p1grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 0.1f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(0.1f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + if (draw0p01grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 0.01f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(0.01f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + if (draw0p001grid) + { + if (distanceBetweenVisualizedGridPointsInLocalSpaceUnits_ofBiggestOrder > 0.001f) + { + DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(0.001f, ref alphaForUpcomingOrderColors, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, colorForMainX, colorForMainY, colorForMainZ, durationInSec, hiddenByNearerObjects, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_inLocalSpaceUnits_signFlipsPerp, false, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + } + } + + } + + + static float Get_distanceBetweenVisualizedGridPointsInVisualizedCoordSystemUnits_ofBiggestOrder(out int numberOfDrawnOrders, bool draw1000grid, bool draw100grid, bool draw10grid, bool draw1grid, bool draw0p1grid, bool draw0p01grid, bool draw0p001grid) + { + numberOfDrawnOrders = 0; + float distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder = 1.0f; + if (draw0p001grid) + { + distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder = 0.001f; + numberOfDrawnOrders++; + } + if (draw0p01grid) + { + distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder = 0.01f; + numberOfDrawnOrders++; + } + if (draw0p1grid) + { + distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder = 0.1f; + numberOfDrawnOrders++; + } + if (draw1grid) + { + distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder = 1.0f; + numberOfDrawnOrders++; + } + if (draw10grid) + { + distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder = 10.0f; + numberOfDrawnOrders++; + } + if (draw100grid) + { + distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder = 100.0f; + numberOfDrawnOrders++; + } + if (draw1000grid) + { + distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder = 1000.0f; + numberOfDrawnOrders++; + } + return distanceBetweenVisualizedGridPointsInWorldUnits_ofBiggestOrder; + } + + static void DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude(float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, ref float alphaForUpcomingOrderColors, ref float alphaForUpcomingOrdersBlackPosMarker, Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, bool drawXDim, bool drawYDim, bool drawZDim, Color colorForMainX, Color colorForMainY, Color colorForMainZ, float durationInSec, bool hiddenByNearerObjects, float drawDensity, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Color colorWithLoweredAlpha_x = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainX, alphaForUpcomingOrderColors); + Color colorWithLoweredAlpha_y = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainY, alphaForUpcomingOrderColors); + Color colorWithLoweredAlpha_z = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainZ, alphaForUpcomingOrderColors); + DrawGridPlanes_forAOrderOfMagnitude(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, durationInSec, hiddenByNearerObjects, colorWithLoweredAlpha_x, colorWithLoweredAlpha_y, colorWithLoweredAlpha_z, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + TryDrawGridOrdersDrawAroundPosVisualization(distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, durationInSec, hiddenByNearerObjects); + alphaForUpcomingOrderColors = alphaForUpcomingOrderColors * alphaCascadingFactorForNextSmallerOrder; + } + + static void DrawGridPlanesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, ref float alphaForUpcomingOrderColors, ref float alphaForUpcomingOrdersBlackPosMarker, Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, bool drawXDim, bool drawYDim, bool drawZDim, Color colorForMainX, Color colorForMainY, Color colorForMainZ, float durationInSec, bool hiddenByNearerObjects, float drawDensity, float distanceBetweenRepeatingCoordsTexts_relToGridDistance, bool drawALineToLocalOrigin) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Color colorWithLoweredAlpha_x = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainX, alphaForUpcomingOrderColors); + Color colorWithLoweredAlpha_y = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainY, alphaForUpcomingOrderColors); + Color colorWithLoweredAlpha_z = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainZ, alphaForUpcomingOrderColors); + float biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = DrawGridPlanes_forAOrderOfMagnitude_local(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, durationInSec, hiddenByNearerObjects, colorWithLoweredAlpha_x, colorWithLoweredAlpha_y, colorWithLoweredAlpha_z, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + TryDrawGridOrdersDrawAroundPosVisualization_local(biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, localPositionAroundWhichToDraw, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, durationInSec, hiddenByNearerObjects, drawALineToLocalOrigin, positionAroundWhichToDraw_global); + alphaForUpcomingOrderColors = alphaForUpcomingOrderColors * alphaCascadingFactorForNextSmallerOrder; + } + + static void DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude(float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, ref float alphaForUpcomingOrderColors, ref float alphaForUpcomingOrdersBlackPosMarker, Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, bool drawXDim, bool drawYDim, bool drawZDim, Color colorForMainX, Color colorForMainY, Color colorForMainZ, float durationInSec, bool hiddenByNearerObjects, float distanceBetweenRepeatingCoordsTexts_relToGridDistance, float linesWidth, DrawEngineBasics.XGridLinesOrientation orientation_ofXLines, DrawEngineBasics.YGridLinesOrientation orientation_ofYLines, DrawEngineBasics.ZGridLinesOrientation orientation_ofZLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Color colorWithLoweredAlpha_x = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainX, alphaForUpcomingOrderColors); + Color colorWithLoweredAlpha_y = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainY, alphaForUpcomingOrderColors); + Color colorWithLoweredAlpha_z = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainZ, alphaForUpcomingOrderColors); + DrawGridLines_forAOrderOfMagnitude(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, durationInSec, hiddenByNearerObjects, colorWithLoweredAlpha_x, colorWithLoweredAlpha_y, colorWithLoweredAlpha_z, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + TryDrawGridOrdersDrawAroundPosVisualization(distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, ref alphaForUpcomingOrdersBlackPosMarker, positionAroundWhichToDraw, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, durationInSec, hiddenByNearerObjects); + alphaForUpcomingOrderColors = alphaForUpcomingOrderColors * alphaCascadingFactorForNextSmallerOrder; + } + + static void DrawGridLinesAndDrawAroundPosVisualization_forAOrderOfMagnitude_local(float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, ref float alphaForUpcomingOrderColors, ref float alphaForUpcomingOrdersBlackPosMarker, Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, bool drawXDim, bool drawYDim, bool drawZDim, Color colorForMainX, Color colorForMainY, Color colorForMainZ, float durationInSec, bool hiddenByNearerObjects, float distanceBetweenRepeatingCoordsTexts_relToGridDistance, float linesWidth_inLocalSpaceUnits, bool drawALineToLocalOrigin, DrawEngineBasics.XGridLinesOrientation orientation_ofXLines, DrawEngineBasics.YGridLinesOrientation orientation_ofYLines, DrawEngineBasics.ZGridLinesOrientation orientation_ofZLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Color colorWithLoweredAlpha_x = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainX, alphaForUpcomingOrderColors); + Color colorWithLoweredAlpha_y = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainY, alphaForUpcomingOrderColors); + Color colorWithLoweredAlpha_z = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForMainZ, alphaForUpcomingOrderColors); + float biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = DrawGridLines_forAOrderOfMagnitude_local(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, durationInSec, hiddenByNearerObjects, colorWithLoweredAlpha_x, colorWithLoweredAlpha_y, colorWithLoweredAlpha_z, distanceBetweenRepeatingCoordsTexts_relToGridDistance, linesWidth_inLocalSpaceUnits, orientation_ofXLines, orientation_ofYLines, orientation_ofZLines); + TryDrawGridOrdersDrawAroundPosVisualization_local(biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, ref alphaForUpcomingOrdersBlackPosMarker, originOfLocalSpace, scaleOfLocalSpace, rotationOfLocalSpace, localPositionAroundWhichToDraw, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawXDim, drawYDim, drawZDim, durationInSec, hiddenByNearerObjects, drawALineToLocalOrigin, positionAroundWhichToDraw_global); + alphaForUpcomingOrderColors = alphaForUpcomingOrderColors * alphaCascadingFactorForNextSmallerOrder; + } + + static void DrawGridPlanes_forAOrderOfMagnitude(Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, bool drawXDim, bool drawYDim, bool drawZDim, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, float durationInSec, bool hiddenByNearerObjects, Color colorForX, Color colorForY, Color colorForZ, float drawDensity, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + if (drawXDim) + { + DrawXDimPlanesOfGrid(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, 0.0f, durationInSec, hiddenByNearerObjects, colorForX, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + + if (drawYDim) + { + DrawYDimPlanesOfGrid(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, 0.0f, durationInSec, hiddenByNearerObjects, colorForY, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + + if (drawZDim) + { + DrawZDimPlanesOfGrid(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, 0.0f, durationInSec, hiddenByNearerObjects, colorForZ, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + } + + static float DrawGridPlanes_forAOrderOfMagnitude_local(Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, bool drawXDim, bool drawYDim, bool drawZDim, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, float durationInSec, bool hiddenByNearerObjects, Color colorForX, Color colorForY, Color colorForZ, float drawDensity, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + float biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = 0.0f; + if (drawXDim) + { + float distanceBetweenVisualizedXGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.x; + biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = Mathf.Max(biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Mathf.Abs(distanceBetweenVisualizedXGridPointsInWorldUnits_forThisOrder)); + DrawXDimPlanesOfGrid_local(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, 0.0f, durationInSec, hiddenByNearerObjects, colorForX, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + + if (drawYDim) + { + float distanceBetweenVisualizedYGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.y; + biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = Mathf.Max(biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Mathf.Abs(distanceBetweenVisualizedYGridPointsInWorldUnits_forThisOrder)); + DrawYDimPlanesOfGrid_local(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, 0.0f, durationInSec, hiddenByNearerObjects, colorForY, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + + if (drawZDim) + { + float distanceBetweenVisualizedZGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.z; + biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = Mathf.Max(biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Mathf.Abs(distanceBetweenVisualizedZGridPointsInWorldUnits_forThisOrder)); + DrawZDimPlanesOfGrid_local(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, 0.0f, durationInSec, hiddenByNearerObjects, colorForZ, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, drawDensity, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + return biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + } + + static void DrawGridLines_forAOrderOfMagnitude(Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, bool drawXDim, bool drawYDim, bool drawZDim, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, float durationInSec, bool hiddenByNearerObjects, Color colorForX, Color colorForY, Color colorForZ, float distanceBetweenRepeatingCoordsTexts_relToGridDistance, float linesWidth, DrawEngineBasics.XGridLinesOrientation orientation_ofXLines, DrawEngineBasics.YGridLinesOrientation orientation_ofYLines, DrawEngineBasics.ZGridLinesOrientation orientation_ofZLines) + { + if (drawXDim) + { + bool turned90DegAroundHisAxis = (orientation_ofXLines == DrawEngineBasics.XGridLinesOrientation.alongZ); + DrawXDimLinesOfGrid(true, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, colorForX, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, turned90DegAroundHisAxis, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + + if (drawYDim) + { + bool turned90DegAroundHisAxis = (orientation_ofYLines == DrawEngineBasics.YGridLinesOrientation.alongZ); + DrawYDimLinesOfGrid(true, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, colorForY, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, turned90DegAroundHisAxis, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + + if (drawZDim) + { + bool turned90DegAroundHisAxis = (orientation_ofZLines == DrawEngineBasics.ZGridLinesOrientation.alongX); + DrawZDimLinesOfGrid(true, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, colorForZ, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, turned90DegAroundHisAxis, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + } + + static float DrawGridLines_forAOrderOfMagnitude_local(Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, bool drawXDim, bool drawYDim, bool drawZDim, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, float durationInSec, bool hiddenByNearerObjects, Color colorForX, Color colorForY, Color colorForZ, float distanceBetweenRepeatingCoordsTexts_relToGridDistance, float linesWidth_inLocalSpaceUnits, DrawEngineBasics.XGridLinesOrientation orientation_ofXLines, DrawEngineBasics.YGridLinesOrientation orientation_ofYLines, DrawEngineBasics.ZGridLinesOrientation orientation_ofZLines) + { + float biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = 0.0f; + if (drawXDim) + { + float distanceBetweenVisualizedXGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.x; + biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = Mathf.Max(biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Mathf.Abs(distanceBetweenVisualizedXGridPointsInWorldUnits_forThisOrder)); + bool turned90DegAroundHisAxis = (orientation_ofXLines == DrawEngineBasics.XGridLinesOrientation.alongZ); + DrawXDimLinesOfGridLocal(true, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth_inLocalSpaceUnits, durationInSec, hiddenByNearerObjects, colorForX, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, turned90DegAroundHisAxis, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + + if (drawYDim) + { + float distanceBetweenVisualizedYGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.y; + biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = Mathf.Max(biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Mathf.Abs(distanceBetweenVisualizedYGridPointsInWorldUnits_forThisOrder)); + bool turned90DegAroundHisAxis = (orientation_ofYLines == DrawEngineBasics.YGridLinesOrientation.alongZ); + DrawYDimLinesOfGridLocal(true, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth_inLocalSpaceUnits, durationInSec, hiddenByNearerObjects, colorForY, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, turned90DegAroundHisAxis, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + + if (drawZDim) + { + float distanceBetweenVisualizedZGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.z; + biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = Mathf.Max(biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Mathf.Abs(distanceBetweenVisualizedZGridPointsInWorldUnits_forThisOrder)); + bool turned90DegAroundHisAxis = (orientation_ofZLines == DrawEngineBasics.ZGridLinesOrientation.alongX); + DrawZDimLinesOfGridLocal(true, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth_inLocalSpaceUnits, durationInSec, hiddenByNearerObjects, colorForZ, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, turned90DegAroundHisAxis, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + } + return biggest_absDistanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + } + + static float relStrokeWidth_forDrawAroundPosCoordianteText = 68000.0f; + static void TryDrawGridOrdersDrawAroundPosVisualization(float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, ref float alphaForUpcomingOrdersBlackPosMarker, Vector3 positionAroundWhichToDraw, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, bool drawXDim, bool drawYDim, bool drawZDim, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawEngineBasics.hide_positionAroundWhichToDraw_forGrids == false) + { + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + UtilitiesDXXL_DrawBasics.Set_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_reversible(Mathf.CeilToInt(relStrokeWidth_forDrawAroundPosCoordianteText)); + DrawBasics.Point(positionAroundWhichToDraw, null, default(Color), extentOfWholeCascadeAlongAxis_inWorldUnits, 0.0f, default(Color), default(Quaternion), false, true, false, durationInSec, hiddenByNearerObjects); + //DrawBasics.Point(positionAroundWhichToDraw, null, default(Color), extentOfWholeCascadeAlongAxis_inWorldUnits, 0.0f, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(Color.black, alphaForUpcomingOrdersBlackPosMarker), default(Quaternion), false, true, false, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM(); + + alphaForUpcomingOrdersBlackPosMarker = alphaForUpcomingOrdersBlackPosMarker / alphaCascadingFactorForNextSmallerOrder_forPointsBlackOverdraw; + DrawSkewedPosIndicatingCubes(positionAroundWhichToDraw, colorFor_skewedPosIndicatingCubes, extentOfWholeCascadeAlongAxis_inWorldUnits, drawXDim, drawYDim, drawZDim, durationInSec, hiddenByNearerObjects); + } + } + + static void TryDrawGridOrdersDrawAroundPosVisualization_local(float biggest_distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, ref float alphaForUpcomingOrdersBlackPosMarker, Vector3 originOfLocalSpace, Vector3 scaleOfLocalSpace, Quaternion rotationOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, bool drawXDim, bool drawYDim, bool drawZDim, float durationInSec, bool hiddenByNearerObjects, bool drawALineToLocalOrigin, Vector3 positionAroundWhichToDraw_global) + { + if (DrawEngineBasics.hide_positionAroundWhichToDraw_forGrids == false) + { + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * biggest_distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + if (forceSkip_drawAroundPosVisualizationLocal == false) + { + bool used_drawALineToLocalOrigin = forceSkip_drawingLocalOrigin ? false : drawALineToLocalOrigin; + + UtilitiesDXXL_DrawBasics.Set_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_reversible(Mathf.CeilToInt(relStrokeWidth_forDrawAroundPosCoordianteText)); + DrawBasics.PointLocal(localPositionAroundWhichToDraw, originOfLocalSpace, rotationOfLocalSpace, scaleOfLocalSpace, null, default(Color), extentOfWholeCascadeAlongAxis_inWorldUnits, 0.0f, default(Color), default, false, true, false, used_drawALineToLocalOrigin, false, durationInSec, hiddenByNearerObjects); + //DrawBasics.PointLocal(localPositionAroundWhichToDraw, originOfLocalSpace, rotationOfLocalSpace, scaleOfLocalSpace, null, default(Color), extentOfWholeCascadeAlongAxis_inWorldUnits, 0.0f, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(Color.black, alphaForUpcomingOrdersBlackPosMarker), default, false, true, false, false, false, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM(); + + alphaForUpcomingOrdersBlackPosMarker = alphaForUpcomingOrdersBlackPosMarker / alphaCascadingFactorForNextSmallerOrder_forPointsBlackOverdraw; + } + DrawSkewedPosIndicatingCubes_local(rotationOfLocalSpace, positionAroundWhichToDraw_global, colorFor_skewedPosIndicatingCubes, extentOfWholeCascadeAlongAxis_inWorldUnits, drawXDim, drawYDim, drawZDim, durationInSec, hiddenByNearerObjects); //-> is outside of "forceSkip_drawAroundPosVisualzationLocal", so that the drawAroundPos of "GridVisualizer's" with strongly non-uniform dimension scales are still somehow visible, also if the coordinate texts have been scaled to unreadable small. + } + } + + static Vector3 GetDistanceTextPositionOffset_relToVectorLine_forDisanceDisplayABOVEtheVectorLine(float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Vector3 vectorAlongGridLine_normalized) + { + //slightly confusing naming: The text display ABOVE the vector line is for the Vector to the grid pos BELOW the drawAroundPos + return (0.07f * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * vectorAlongGridLine_normalized); + } + + static Vector3 GetDistanceTextPositionOffset_relToVectorLine_forDisanceDisplayBELOWtheVectorLine(float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Vector3 vectorAlongGridLine_normalized) + { + //slightly confusing naming: The text display BELOW the vector line is for the Vector to the grid pos ABOVE the drawAroundPos + return (-0.05f) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * vectorAlongGridLine_normalized; + } + + static void DrawXDimPlanesOfGrid(Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, float drawDensity, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + DrawXDimLinesOfGrid(false, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, false, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawXDimLinesOfGrid(false, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, true, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawXDimPlanesDenseWithoutText(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, false); + DrawXDimPlanesDenseWithoutText(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, true); + } + + static void DrawYDimPlanesOfGrid(Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, float drawDensity, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + DrawYDimLinesOfGrid(false, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, false, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawYDimLinesOfGrid(false, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, true, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawYDimPlanesDenseWithoutText(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, false); + DrawYDimPlanesDenseWithoutText(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, true); + } + + static void DrawZDimPlanesOfGrid(Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, float drawDensity, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + DrawZDimLinesOfGrid(false, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, false, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawZDimLinesOfGrid(false, positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, true, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawZDimPlanesDenseWithoutText(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, false); + DrawZDimPlanesDenseWithoutText(positionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, true); + } + + static void DrawXDimPlanesOfGrid_local(Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, float drawDensity, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + DrawXDimLinesOfGridLocal(false, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, false, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawXDimLinesOfGridLocal(false, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, true, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawXDimPlanesDenseWithoutTextLocal(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, false); + DrawXDimPlanesDenseWithoutTextLocal(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, true); + } + + static void DrawYDimPlanesOfGrid_local(Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, float drawDensity, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + DrawYDimLinesOfGridLocal(false, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, false, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawYDimLinesOfGridLocal(false, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, true, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawYDimPlanesDenseWithoutTextLocal(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, false); + DrawYDimPlanesDenseWithoutTextLocal(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, true); + } + + static void DrawZDimPlanesOfGrid_local(Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, float drawDensity, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + DrawZDimLinesOfGridLocal(false, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, false, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawZDimLinesOfGridLocal(false, positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, linesWidth, durationInSec, hiddenByNearerObjects, color, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, true, distanceBetweenRepeatingCoordsTexts_relToGridDistance); + DrawZDimPlanesDenseWithoutTextLocal(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, false); + DrawZDimPlanesDenseWithoutTextLocal(positionAroundWhichToDraw_global, localForward_normalizedInGlobalSpace, localUp_normalizedInGlobalSpace, localRight_normalizedInGlobalSpace, scaleOfLocalSpace, localPositionAroundWhichToDraw, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, drawDensity, distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, durationInSec, hiddenByNearerObjects, color, true); + } + + static void DrawXDimLinesOfGrid(bool forGridLINES_notForGridPLANES, Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, bool theXGridLines_areAlingedAlongZ_notAlongY, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textPosOffset = DrawEngineBasics.offsetForCoordinateTextDisplays_inGrids * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textSize = distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * DrawEngineBasics.SizeScalingForCoordinateTexts_inGrids; + float linesWidth_worldSpace = linesWidth * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float absHalfLinesWidth = Mathf.Abs(0.5f * linesWidth_worldSpace); + float spaceBetweenLineAndCoordsText = absHalfLinesWidth + rel_spaceBetweenLineAndCoordsText * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + float positionAroundWhichToDraw_expressedInUnitsOfThisOrder_x = positionAroundWhichToDraw.x / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float xPos_ofLowestGridPos = Mathf.Round(positionAroundWhichToDraw_expressedInUnitsOfThisOrder_x - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + bool lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt = (linesWidth >= 0.0f); + Vector3 vectorAlongGridLine_normalized = theXGridLines_areAlingedAlongZ_notAlongY ? Vector3.forward : Vector3.up; + Vector3 vectorAlongPerpGrowingLineWidth_normalized = theXGridLines_areAlingedAlongZ_notAlongY ? Vector3.up : Vector3.forward; + Vector3 vectorAlongGrowingLineWidth_normalized = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? Vector3.left : vectorAlongPerpGrowingLineWidth_normalized; + + Vector3 lineStart_ofLowestGridPos; + Vector3 lineEnd_ofLowestGridPos; + if (theXGridLines_areAlingedAlongZ_notAlongY) + { + lineStart_ofLowestGridPos = new Vector3(xPos_ofLowestGridPos, positionAroundWhichToDraw.y, positionAroundWhichToDraw.z - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + lineEnd_ofLowestGridPos = new Vector3(xPos_ofLowestGridPos, positionAroundWhichToDraw.y, positionAroundWhichToDraw.z + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + } + else + { + lineStart_ofLowestGridPos = new Vector3(xPos_ofLowestGridPos, positionAroundWhichToDraw.y - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, positionAroundWhichToDraw.z); + lineEnd_ofLowestGridPos = new Vector3(xPos_ofLowestGridPos, positionAroundWhichToDraw.y + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, positionAroundWhichToDraw.z); + } + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridPointsAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 1; + numberOfVisualizedGridPointsAlongAxis = Mathf.Max(numberOfVisualizedGridPointsAlongAxis, 3); + for (int i = 0; i < numberOfVisualizedGridPointsAlongAxis; i++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 shiftVector = Vector3.right * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i; + Vector3 lineStartPos = lineStart_ofLowestGridPos + shiftVector; + Vector3 lineEndPos = lineEnd_ofLowestGridPos + shiftVector; + float distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 = Mathf.Abs((lineStartPos.x - positionAroundWhichToDraw.x) / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + Color lineColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 1.0f - 0.9f * distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1); + Line_fadeableAnimSpeed.InternalDraw(lineStartPos, lineEndPos, lineColor, linesWidth_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, vectorAlongGrowingLineWidth_normalized, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + bool drawCoordsTextAtLeastOnce = (distanceBetweenRepeatingCoordsTexts_relToGridDistance >= 0.0f); + if (drawCoordsTextAtLeastOnce) + { + string coordsAsText = GetCoordsAsText_forXDimLines(lineStartPos.x, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder); + Vector3 textPos_ifTextIsInsideRepresentedGridAxis = theXGridLines_areAlingedAlongZ_notAlongY ? new Vector3(lineStartPos.x - spaceBetweenLineAndCoordsText, positionAroundWhichToDraw.y, positionAroundWhichToDraw.z + textPosOffset) : new Vector3(lineStartPos.x - spaceBetweenLineAndCoordsText, positionAroundWhichToDraw.y + textPosOffset, positionAroundWhichToDraw.z); + Vector3 textPos_ifTextIsPerpToRepresentedGridAxis = theXGridLines_areAlingedAlongZ_notAlongY ? new Vector3(lineStartPos.x, positionAroundWhichToDraw.y + spaceBetweenLineAndCoordsText, positionAroundWhichToDraw.z + textPosOffset) : new Vector3(lineStartPos.x, positionAroundWhichToDraw.y + textPosOffset, positionAroundWhichToDraw.z + spaceBetweenLineAndCoordsText); + Vector3 textPos = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? textPos_ifTextIsInsideRepresentedGridAxis : textPos_ifTextIsPerpToRepresentedGridAxis; + UtilitiesDXXL_Text.Write(coordsAsText, textPos, lineColor, textSize, vectorAlongGridLine_normalized, vectorAlongGrowingLineWidth_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + DrawAdditionalCoordsTexts(vectorAlongGridLine_normalized, vectorAlongGrowingLineWidth_normalized, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, distanceBetweenRepeatingCoordsTexts_relToGridDistance, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, lineColor, textPos, coordsAsText, textSize, durationInSec, hiddenByNearerObjects); + } + } + + TryDrawDistanceLines_fromDrawAroundPos_toNeighboringGridValue(forGridLINES_notForGridPLANES, 1.0f, Vector3.right, vectorAlongGridLine_normalized, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, positionAroundWhichToDraw, positionAroundWhichToDraw_expressedInUnitsOfThisOrder_x, color, durationInSec, hiddenByNearerObjects); + } + + static string GetCoordsAsText_forXDimLines(float lineStartPos_x, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder) + { + if (DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes) + { + return ("" + (Mathf.Round(lineStartPos_x / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder)); //-> fixing floatCalculationImprecisionErrors (like "0.099999999" -> "0.1") + } + else + { + return ("x = " + (Mathf.Round(lineStartPos_x / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder)); //-> fixing floatCalculationImprecisionErrors (like "0.099999999" -> "0.1") + } + } + + static void DrawYDimLinesOfGrid(bool forGridLINES_notForGridPLANES, Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, bool theYGridLines_areAlingedAlongZ_notAlongX, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textPosOffset = DrawEngineBasics.offsetForCoordinateTextDisplays_inGrids * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textSize = distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * DrawEngineBasics.SizeScalingForCoordinateTexts_inGrids; + float linesWidth_worldSpace = linesWidth * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float absHalfLinesWidth = Mathf.Abs(0.5f * linesWidth_worldSpace); + float spaceBetweenLineAndCoordsText = absHalfLinesWidth + rel_spaceBetweenLineAndCoordsText * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + float positionAroundWhichToDraw_expressedInUnitsOfThisOrder_y = positionAroundWhichToDraw.y / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float yPos_ofLowestGridPos = Mathf.Round(positionAroundWhichToDraw_expressedInUnitsOfThisOrder_y - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + bool lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt = (linesWidth >= 0.0f); + Vector3 vectorAlongGridLine_normalized = theYGridLines_areAlingedAlongZ_notAlongX ? Vector3.forward : Vector3.right; + Vector3 vectorAlongPerpGrowingLineWidth_normalized = theYGridLines_areAlingedAlongZ_notAlongX ? Vector3.left : Vector3.forward; + Vector3 vectorAlongGrowingLineWidth_normalized = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? Vector3.up : vectorAlongPerpGrowingLineWidth_normalized; + + Vector3 lineStart_ofLowestGridPos; + Vector3 lineEnd_ofLowestGridPos; + if (theYGridLines_areAlingedAlongZ_notAlongX) + { + lineStart_ofLowestGridPos = new Vector3(positionAroundWhichToDraw.x, yPos_ofLowestGridPos, positionAroundWhichToDraw.z - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + lineEnd_ofLowestGridPos = new Vector3(positionAroundWhichToDraw.x, yPos_ofLowestGridPos, positionAroundWhichToDraw.z + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + } + else + { + lineStart_ofLowestGridPos = new Vector3(positionAroundWhichToDraw.x - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, yPos_ofLowestGridPos, positionAroundWhichToDraw.z); + lineEnd_ofLowestGridPos = new Vector3(positionAroundWhichToDraw.x + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, yPos_ofLowestGridPos, positionAroundWhichToDraw.z); + } + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridPointsAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 1; + numberOfVisualizedGridPointsAlongAxis = Mathf.Max(numberOfVisualizedGridPointsAlongAxis, 3); + for (int i = 0; i < numberOfVisualizedGridPointsAlongAxis; i++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 shiftVector = Vector3.up * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i; + Vector3 lineStartPos = lineStart_ofLowestGridPos + shiftVector; + Vector3 lineEndPos = lineEnd_ofLowestGridPos + shiftVector; + float distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 = Mathf.Abs((lineStartPos.y - positionAroundWhichToDraw.y) / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + Color lineColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 1.0f - 0.9f * distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1); + Line_fadeableAnimSpeed.InternalDraw(lineStartPos, lineEndPos, lineColor, linesWidth_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, vectorAlongGrowingLineWidth_normalized, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + bool drawCoordsTextAtLeastOnce = (distanceBetweenRepeatingCoordsTexts_relToGridDistance >= 0.0f); + if (drawCoordsTextAtLeastOnce) + { + string coordsAsText = GetCoordsAsText_forYDimLines(lineStartPos.y, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder); + Vector3 textPos_ifTextIsInsideRepresentedGridAxis = theYGridLines_areAlingedAlongZ_notAlongX ? new Vector3(positionAroundWhichToDraw.x, lineStartPos.y + spaceBetweenLineAndCoordsText, positionAroundWhichToDraw.z + textPosOffset) : new Vector3(positionAroundWhichToDraw.x + textPosOffset, lineStartPos.y + spaceBetweenLineAndCoordsText, positionAroundWhichToDraw.z); + Vector3 textPos_ifTextIsPerpToRepresentedGridAxis = theYGridLines_areAlingedAlongZ_notAlongX ? new Vector3(positionAroundWhichToDraw.x - spaceBetweenLineAndCoordsText, lineStartPos.y, positionAroundWhichToDraw.z + textPosOffset) : new Vector3(positionAroundWhichToDraw.x + textPosOffset, lineStartPos.y, positionAroundWhichToDraw.z + spaceBetweenLineAndCoordsText); + Vector3 textPos = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? textPos_ifTextIsInsideRepresentedGridAxis : textPos_ifTextIsPerpToRepresentedGridAxis; + UtilitiesDXXL_Text.Write(coordsAsText, textPos, lineColor, textSize, vectorAlongGridLine_normalized, vectorAlongGrowingLineWidth_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + DrawAdditionalCoordsTexts(vectorAlongGridLine_normalized, vectorAlongGrowingLineWidth_normalized, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, distanceBetweenRepeatingCoordsTexts_relToGridDistance, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, lineColor, textPos, coordsAsText, textSize, durationInSec, hiddenByNearerObjects); + } + } + + TryDrawDistanceLines_fromDrawAroundPos_toNeighboringGridValue(forGridLINES_notForGridPLANES, 1.0f, Vector3.up, vectorAlongGridLine_normalized, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, positionAroundWhichToDraw, positionAroundWhichToDraw_expressedInUnitsOfThisOrder_y, color, durationInSec, hiddenByNearerObjects); + } + + static string GetCoordsAsText_forYDimLines(float lineStartPos_y, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder) + { + if (DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes) + { + return ("" + (Mathf.Round(lineStartPos_y / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder)); //-> fixing floatCalculationImprecisionErrors (like "0.099999999" -> "0.1") + } + else + { + return ("y = " + (Mathf.Round(lineStartPos_y / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder)); //-> fixing floatCalculationImprecisionErrors (like "0.099999999" -> "0.1") + } + } + + static void DrawZDimLinesOfGrid(bool forGridLINES_notForGridPLANES, Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, bool theZGridLines_areAlingedAlongX_notAlongY, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textPosOffset = DrawEngineBasics.offsetForCoordinateTextDisplays_inGrids * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textSize = distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * DrawEngineBasics.SizeScalingForCoordinateTexts_inGrids; + float linesWidth_worldSpace = linesWidth * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float absHalfLinesWidth = Mathf.Abs(0.5f * linesWidth_worldSpace); + float spaceBetweenLineAndCoordsText = absHalfLinesWidth + rel_spaceBetweenLineAndCoordsText * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + float positionAroundWhichToDraw_expressedInUnitsOfThisOrder_z = positionAroundWhichToDraw.z / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float zPos_ofLowestGridPos = Mathf.Round(positionAroundWhichToDraw_expressedInUnitsOfThisOrder_z - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + bool lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt = (linesWidth >= 0.0f); + Vector3 vectorAlongGridLine_normalized = theZGridLines_areAlingedAlongX_notAlongY ? Vector3.right : Vector3.up; + Vector3 vectorAlongPerpGrowingLineWidth_normalized = theZGridLines_areAlingedAlongX_notAlongY ? Vector3.up : Vector3.left; + Vector3 textUp_normalized_ifTextIsInsideRepresentedGridAxis = theZGridLines_areAlingedAlongX_notAlongY ? Vector3.forward : Vector3.back; + Vector3 vectorAlongGrowingLineWidth_normalized = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? textUp_normalized_ifTextIsInsideRepresentedGridAxis : vectorAlongPerpGrowingLineWidth_normalized; + + Vector3 lineStart_ofLowestGridPos; + Vector3 lineEnd_ofLowestGridPos; + if (theZGridLines_areAlingedAlongX_notAlongY) + { + lineStart_ofLowestGridPos = new Vector3(positionAroundWhichToDraw.x - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, positionAroundWhichToDraw.y, zPos_ofLowestGridPos); + lineEnd_ofLowestGridPos = new Vector3(positionAroundWhichToDraw.x + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, positionAroundWhichToDraw.y, zPos_ofLowestGridPos); + } + else + { + lineStart_ofLowestGridPos = new Vector3(positionAroundWhichToDraw.x, positionAroundWhichToDraw.y - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, zPos_ofLowestGridPos); + lineEnd_ofLowestGridPos = new Vector3(positionAroundWhichToDraw.x, positionAroundWhichToDraw.y + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, zPos_ofLowestGridPos); + } + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridPointsAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 1; + numberOfVisualizedGridPointsAlongAxis = Mathf.Max(numberOfVisualizedGridPointsAlongAxis, 3); + for (int i = 0; i < numberOfVisualizedGridPointsAlongAxis; i++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 shiftVector = Vector3.forward * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i; + Vector3 lineStartPos = lineStart_ofLowestGridPos + shiftVector; + Vector3 lineEndPos = lineEnd_ofLowestGridPos + shiftVector; + float distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 = Mathf.Abs((lineStartPos.z - positionAroundWhichToDraw.z) / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + Color lineColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 1.0f - 0.9f * distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1); + Line_fadeableAnimSpeed.InternalDraw(lineStartPos, lineEndPos, lineColor, linesWidth_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, vectorAlongGrowingLineWidth_normalized, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + bool drawCoordsTextAtLeastOnce = (distanceBetweenRepeatingCoordsTexts_relToGridDistance >= 0.0f); + if (drawCoordsTextAtLeastOnce) + { + string coordsAsText = GetCoordsAsText_forZDimLines(lineStartPos.z, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder); + Vector3 textPos_ifTextIsInsideRepresentedGridAxis = theZGridLines_areAlingedAlongX_notAlongY ? new Vector3(positionAroundWhichToDraw.x + textPosOffset, positionAroundWhichToDraw.y, lineStartPos.z + spaceBetweenLineAndCoordsText) : new Vector3(positionAroundWhichToDraw.x, positionAroundWhichToDraw.y + textPosOffset, lineStartPos.z - spaceBetweenLineAndCoordsText); + Vector3 textPos_ifTextIsPerpToRepresentedGridAxis = theZGridLines_areAlingedAlongX_notAlongY ? new Vector3(positionAroundWhichToDraw.x + textPosOffset, positionAroundWhichToDraw.y + spaceBetweenLineAndCoordsText, lineStartPos.z) : new Vector3(positionAroundWhichToDraw.x - spaceBetweenLineAndCoordsText, positionAroundWhichToDraw.y + textPosOffset, lineStartPos.z); + Vector3 textPos = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? textPos_ifTextIsInsideRepresentedGridAxis : textPos_ifTextIsPerpToRepresentedGridAxis; + UtilitiesDXXL_Text.Write(coordsAsText, textPos, lineColor, textSize, vectorAlongGridLine_normalized, vectorAlongGrowingLineWidth_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + DrawAdditionalCoordsTexts(vectorAlongGridLine_normalized, vectorAlongGrowingLineWidth_normalized, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, distanceBetweenRepeatingCoordsTexts_relToGridDistance, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, lineColor, textPos, coordsAsText, textSize, durationInSec, hiddenByNearerObjects); + } + } + + TryDrawDistanceLines_fromDrawAroundPos_toNeighboringGridValue(forGridLINES_notForGridPLANES, 1.0f, Vector3.forward, vectorAlongGridLine_normalized, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, positionAroundWhichToDraw, positionAroundWhichToDraw_expressedInUnitsOfThisOrder_z, color, durationInSec, hiddenByNearerObjects); + } + + static string GetCoordsAsText_forZDimLines(float lineStartPos_z, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder) + { + if (DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes) + { + return ("" + (Mathf.Round(lineStartPos_z / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder)); //-> fixing floatCalculationImprecisionErrors (like "0.099999999" -> "0.1") + } + else + { + return ("z = " + (Mathf.Round(lineStartPos_z / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder)); //-> fixing floatCalculationImprecisionErrors (like "0.099999999" -> "0.1") + } + } + + static void DrawXDimLinesOfGridLocal(bool forGridLINES_notForGridPLANES, Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth_inLocalSpaceUnits, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, bool theXGridLines_areAlingedAlongZ_notAlongY, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.x; + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textPosOffset = DrawEngineBasics.offsetForCoordinateTextDisplays_inGrids * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textSize = distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * DrawEngineBasics.SizeScalingForCoordinateTexts_inGrids; + float linesWidth_inGlobalUnits = linesWidth_inLocalSpaceUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float absHalfLinesWidth_inGlobalUnits = Mathf.Abs(0.5f * linesWidth_inGlobalUnits); + float spaceBetweenLineAndCoordsText_inGlobalUnits = absHalfLinesWidth_inGlobalUnits + rel_spaceBetweenLineAndCoordsText * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + float localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_x = localPositionAroundWhichToDraw.x / distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + float localXPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated = Mathf.Round(localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_x - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + + bool lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt = (linesWidth_inLocalSpaceUnits >= 0.0f); + float distance_fromDrawAroundPos_to_smallestXGridPos_inGlobalWorldUnits = Mathf.Abs(localXPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated - localPositionAroundWhichToDraw.x) * scaleOfLocalSpace.x; + Vector3 drawAroundPosGlobal_to_smallestXGlobal = (-localRight_normalizedInGlobalSpace) * distance_fromDrawAroundPos_to_smallestXGridPos_inGlobalWorldUnits; + Vector3 lineCenterGlobal_to_lineEndGlobal = theXGridLines_areAlingedAlongZ_notAlongY ? (localForward_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits) : (localUp_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + Vector3 lineCenterGlobal_ofLowestGridPos = positionAroundWhichToDraw_global + drawAroundPosGlobal_to_smallestXGlobal; + Vector3 lineStartGlobal_ofLowestGridPos = lineCenterGlobal_ofLowestGridPos - lineCenterGlobal_to_lineEndGlobal; + Vector3 lineEndGlobal_ofLowestGridPos = lineCenterGlobal_ofLowestGridPos + lineCenterGlobal_to_lineEndGlobal; + Vector3 lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global = positionAroundWhichToDraw_global - lineCenterGlobal_to_lineEndGlobal; + Vector3 vectorAlongGridLine_normalizedInGlobalSpace = theXGridLines_areAlingedAlongZ_notAlongY ? localForward_normalizedInGlobalSpace : localUp_normalizedInGlobalSpace; + Vector3 vectorAlongPerpGrowingLineWidth_normalizedInGlobalSpace = theXGridLines_areAlingedAlongZ_notAlongY ? localUp_normalizedInGlobalSpace : localForward_normalizedInGlobalSpace; + Vector3 vectorAlongGrowingLineWidth_normalizedInGlobalSpace = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? (-localRight_normalizedInGlobalSpace) : vectorAlongPerpGrowingLineWidth_normalizedInGlobalSpace; + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridPointsAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 1; + numberOfVisualizedGridPointsAlongAxis = Mathf.Max(numberOfVisualizedGridPointsAlongAxis, 3); + for (int i = 0; i < numberOfVisualizedGridPointsAlongAxis; i++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 shiftVector = localRight_normalizedInGlobalSpace * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i; + Vector3 lineCenterPos = lineCenterGlobal_ofLowestGridPos + shiftVector; + Vector3 lineStartPos = lineStartGlobal_ofLowestGridPos + shiftVector; + Vector3 lineEndPos = lineEndGlobal_ofLowestGridPos + shiftVector; + float distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 = Mathf.Abs((lineStartPos - lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global).magnitude / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + Color lineColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 1.0f - 0.9f * distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1); + Line_fadeableAnimSpeed.InternalDraw(lineStartPos, lineEndPos, lineColor, linesWidth_inGlobalUnits, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, vectorAlongGrowingLineWidth_normalizedInGlobalSpace, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + bool drawCoordsTextAtLeastOnce = (distanceBetweenRepeatingCoordsTexts_relToGridDistance >= 0.0f); + if (drawCoordsTextAtLeastOnce) + { + float localXPos_ofCurrGridPos_inLocalSpaceUnits = localXPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated + distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * i; + float coordsWithFixedRoundingError = (Mathf.Round(localXPos_ofCurrGridPos_inLocalSpaceUnits / distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder) * distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder); //-> fixing floatCalculationImprecisionErrors (like "0.099999999" -> "0.1") + string coordsAsText = GetCoordsAsText_forLocalXDimLines(coordsWithFixedRoundingError, lineColor); + Vector3 textPos_ifTextIsInsideRepresentedGridAxis = theXGridLines_areAlingedAlongZ_notAlongY ? (lineCenterPos - localRight_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localForward_normalizedInGlobalSpace * textPosOffset) : (lineCenterPos - localRight_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localUp_normalizedInGlobalSpace * textPosOffset); + Vector3 textPos_ifTextIsPerpToRepresentedGridAxis = theXGridLines_areAlingedAlongZ_notAlongY ? (lineCenterPos + localUp_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localForward_normalizedInGlobalSpace * textPosOffset) : (lineCenterPos + localForward_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localUp_normalizedInGlobalSpace * textPosOffset); + Vector3 textPos = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? textPos_ifTextIsInsideRepresentedGridAxis : textPos_ifTextIsPerpToRepresentedGridAxis; + UtilitiesDXXL_Text.Write(coordsAsText, textPos, lineColor, textSize, vectorAlongGridLine_normalizedInGlobalSpace, vectorAlongGrowingLineWidth_normalizedInGlobalSpace, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + DrawAdditionalCoordsTexts(vectorAlongGridLine_normalizedInGlobalSpace, vectorAlongGrowingLineWidth_normalizedInGlobalSpace, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, distanceBetweenRepeatingCoordsTexts_relToGridDistance, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, lineColor, textPos, coordsAsText, textSize, durationInSec, hiddenByNearerObjects); + } + } + + TryDrawDistanceLines_fromDrawAroundPos_toNeighboringGridValue(forGridLINES_notForGridPLANES, scaleOfLocalSpace.x, localRight_normalizedInGlobalSpace, vectorAlongGridLine_normalizedInGlobalSpace, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, positionAroundWhichToDraw_global, localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_x, color, durationInSec, hiddenByNearerObjects); + } + + static string GetCoordsAsText_forLocalXDimLines(float coordsWithFixedRoundingError, Color lineColor) + { + + if (DrawEngineBasics.skipLocalPrefix_inCoordinateTextsOnGridAxes) + { + if (DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes) + { + return ("" + coordsWithFixedRoundingError); + } + else + { + return ("x = " + coordsWithFixedRoundingError); + } + } + else + { + if (DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes) + { + return ("local" + coordsWithFixedRoundingError); + } + else + { + return ("localx = " + coordsWithFixedRoundingError); + } + } + } + + static void DrawYDimLinesOfGridLocal(bool forGridLINES_notForGridPLANES, Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth_inLocalSpaceUnits, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, bool theYGridLines_areAlingedAlongZ_notAlongX, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.y; + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textPosOffset = DrawEngineBasics.offsetForCoordinateTextDisplays_inGrids * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textSize = distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * DrawEngineBasics.SizeScalingForCoordinateTexts_inGrids; + float linesWidth_inGlobalUnits = linesWidth_inLocalSpaceUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float absHalfLinesWidth_inGlobalUnits = Mathf.Abs(0.5f * linesWidth_inGlobalUnits); + float spaceBetweenLineAndCoordsText_inGlobalUnits = absHalfLinesWidth_inGlobalUnits + rel_spaceBetweenLineAndCoordsText * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + float localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_y = localPositionAroundWhichToDraw.y / distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + float localYPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated = Mathf.Round(localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_y - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + + bool lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt = (linesWidth_inLocalSpaceUnits >= 0.0f); + float distance_fromDrawAroundPos_to_smallestYGridPos_inGlobalWorldUnits = Mathf.Abs(localYPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated - localPositionAroundWhichToDraw.y) * scaleOfLocalSpace.y; + Vector3 drawAroundPosGlobal_to_smallestYGlobal = (-localUp_normalizedInGlobalSpace) * distance_fromDrawAroundPos_to_smallestYGridPos_inGlobalWorldUnits; + Vector3 lineCenterGlobal_to_lineEndGlobal = theYGridLines_areAlingedAlongZ_notAlongX ? (localForward_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits) : (localRight_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + Vector3 lineCenterGlobal_ofLowestGridPos = positionAroundWhichToDraw_global + drawAroundPosGlobal_to_smallestYGlobal; + Vector3 lineStartGlobal_ofLowestGridPos = lineCenterGlobal_ofLowestGridPos - lineCenterGlobal_to_lineEndGlobal; + Vector3 lineEndGlobal_ofLowestGridPos = lineCenterGlobal_ofLowestGridPos + lineCenterGlobal_to_lineEndGlobal; + Vector3 lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global = positionAroundWhichToDraw_global - lineCenterGlobal_to_lineEndGlobal; + Vector3 vectorAlongGridLine_normalizedInGlobalSpace = theYGridLines_areAlingedAlongZ_notAlongX ? localForward_normalizedInGlobalSpace : localRight_normalizedInGlobalSpace; + Vector3 vectorAlongPerpGrowingLineWidth_normalizedInGlobalSpace = theYGridLines_areAlingedAlongZ_notAlongX ? (-localRight_normalizedInGlobalSpace) : localForward_normalizedInGlobalSpace; + Vector3 vectorAlongGrowingLineWidth_normalizedInGlobalSpace = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? localUp_normalizedInGlobalSpace : vectorAlongPerpGrowingLineWidth_normalizedInGlobalSpace; + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridPointsAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 1; + numberOfVisualizedGridPointsAlongAxis = Mathf.Max(numberOfVisualizedGridPointsAlongAxis, 3); + for (int i = 0; i < numberOfVisualizedGridPointsAlongAxis; i++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 shiftVector = localUp_normalizedInGlobalSpace * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i; + Vector3 lineCenterPos = lineCenterGlobal_ofLowestGridPos + shiftVector; + Vector3 lineStartPos = lineStartGlobal_ofLowestGridPos + shiftVector; + Vector3 lineEndPos = lineEndGlobal_ofLowestGridPos + shiftVector; + float distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 = Mathf.Abs((lineStartPos - lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global).magnitude / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + Color lineColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 1.0f - 0.9f * distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1); + Line_fadeableAnimSpeed.InternalDraw(lineStartPos, lineEndPos, lineColor, linesWidth_inGlobalUnits, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, vectorAlongGrowingLineWidth_normalizedInGlobalSpace, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + bool drawCoordsTextAtLeastOnce = (distanceBetweenRepeatingCoordsTexts_relToGridDistance >= 0.0f); + if (drawCoordsTextAtLeastOnce) + { + float localYPos_ofCurrGridPos_inLocalSpaceUnits = localYPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated + distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * i; + float coordsWithFixedRoundingError = (Mathf.Round(localYPos_ofCurrGridPos_inLocalSpaceUnits / distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder) * distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder); //-> fixing floatCalculationImprecisionErrors (like "0.099999999" -> "0.1") + string coordsAsText = GetCoordsAsText_forLocalYDimLines(coordsWithFixedRoundingError, lineColor); + Vector3 textPos_ifTextIsInsideRepresentedGridAxis = theYGridLines_areAlingedAlongZ_notAlongX ? (lineCenterPos + localUp_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localForward_normalizedInGlobalSpace * textPosOffset) : (lineCenterPos + localUp_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localRight_normalizedInGlobalSpace * textPosOffset); + Vector3 textPos_ifTextIsPerpToRepresentedGridAxis = theYGridLines_areAlingedAlongZ_notAlongX ? (lineCenterPos - localRight_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localForward_normalizedInGlobalSpace * textPosOffset) : (lineCenterPos + localForward_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localRight_normalizedInGlobalSpace * textPosOffset); + Vector3 textPos = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? textPos_ifTextIsInsideRepresentedGridAxis : textPos_ifTextIsPerpToRepresentedGridAxis; + UtilitiesDXXL_Text.Write(coordsAsText, textPos, lineColor, textSize, vectorAlongGridLine_normalizedInGlobalSpace, vectorAlongGrowingLineWidth_normalizedInGlobalSpace, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + DrawAdditionalCoordsTexts(vectorAlongGridLine_normalizedInGlobalSpace, vectorAlongGrowingLineWidth_normalizedInGlobalSpace, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, distanceBetweenRepeatingCoordsTexts_relToGridDistance, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, lineColor, textPos, coordsAsText, textSize, durationInSec, hiddenByNearerObjects); + } + } + + TryDrawDistanceLines_fromDrawAroundPos_toNeighboringGridValue(forGridLINES_notForGridPLANES, scaleOfLocalSpace.y, localUp_normalizedInGlobalSpace, vectorAlongGridLine_normalizedInGlobalSpace, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, positionAroundWhichToDraw_global, localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_y, color, durationInSec, hiddenByNearerObjects); + } + + static string GetCoordsAsText_forLocalYDimLines(float coordsWithFixedRoundingError, Color lineColor) + { + if (DrawEngineBasics.skipLocalPrefix_inCoordinateTextsOnGridAxes) + { + if (DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes) + { + return ("" + coordsWithFixedRoundingError); + } + else + { + return ("y = " + coordsWithFixedRoundingError); + } + } + else + { + if (DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes) + { + return ("local" + coordsWithFixedRoundingError); + } + else + { + return ("localy = " + coordsWithFixedRoundingError); + } + } + } + + static void DrawZDimLinesOfGridLocal(bool forGridLINES_notForGridPLANES, Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float linesWidth_inLocalSpaceUnits, float durationInSec, bool hiddenByNearerObjects, Color color, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, bool theZGridLines_areAlingedAlongX_notAlongY, float distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.z; + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textPosOffset = DrawEngineBasics.offsetForCoordinateTextDisplays_inGrids * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float textSize = distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * DrawEngineBasics.SizeScalingForCoordinateTexts_inGrids; + float linesWidth_inGlobalUnits = linesWidth_inLocalSpaceUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float absHalfLinesWidth_inGlobalUnits = Mathf.Abs(0.5f * linesWidth_inGlobalUnits); + float spaceBetweenLineAndCoordsText_inGlobalUnits = absHalfLinesWidth_inGlobalUnits + rel_spaceBetweenLineAndCoordsText * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + float localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_z = localPositionAroundWhichToDraw.z / distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + float localZPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated = Mathf.Round(localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_z - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + + bool lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt = (linesWidth_inLocalSpaceUnits >= 0.0f); + float distance_fromDrawAroundPos_to_smallestZGridPos_inGlobalWorldUnits = Mathf.Abs(localZPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated - localPositionAroundWhichToDraw.z) * scaleOfLocalSpace.z; + Vector3 drawAroundPosGlobal_to_smallestZGlobal = (-localForward_normalizedInGlobalSpace) * distance_fromDrawAroundPos_to_smallestZGridPos_inGlobalWorldUnits; + Vector3 lineCenterGlobal_to_lineEndGlobal = theZGridLines_areAlingedAlongX_notAlongY ? (localRight_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits) : (localUp_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + Vector3 lineCenterGlobal_ofLowestGridPos = positionAroundWhichToDraw_global + drawAroundPosGlobal_to_smallestZGlobal; + Vector3 lineStartGlobal_ofLowestGridPos = lineCenterGlobal_ofLowestGridPos - lineCenterGlobal_to_lineEndGlobal; + Vector3 lineEndGlobal_ofLowestGridPos = lineCenterGlobal_ofLowestGridPos + lineCenterGlobal_to_lineEndGlobal; + Vector3 lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global = positionAroundWhichToDraw_global - lineCenterGlobal_to_lineEndGlobal; + Vector3 vectorAlongGridLine_normalizedInGlobalSpace = theZGridLines_areAlingedAlongX_notAlongY ? localRight_normalizedInGlobalSpace : localUp_normalizedInGlobalSpace; + Vector3 vectorAlongPerpGrowingLineWidth_normalizedInGlobalSpace = theZGridLines_areAlingedAlongX_notAlongY ? localUp_normalizedInGlobalSpace : (-localRight_normalizedInGlobalSpace); + Vector3 textUp_normalizedInGlobalSpace_ifTextIsInsideRepresentedGridAxis = theZGridLines_areAlingedAlongX_notAlongY ? localForward_normalizedInGlobalSpace : (-localForward_normalizedInGlobalSpace); + Vector3 vectorAlongGrowingLineWidth_normalizedInGlobalSpace = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? textUp_normalizedInGlobalSpace_ifTextIsInsideRepresentedGridAxis : vectorAlongPerpGrowingLineWidth_normalizedInGlobalSpace; + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridPointsAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 1; + numberOfVisualizedGridPointsAlongAxis = Mathf.Max(numberOfVisualizedGridPointsAlongAxis, 3); + for (int i = 0; i < numberOfVisualizedGridPointsAlongAxis; i++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 shiftVector = localForward_normalizedInGlobalSpace * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i; + Vector3 lineCenterPos = lineCenterGlobal_ofLowestGridPos + shiftVector; + Vector3 lineStartPos = lineStartGlobal_ofLowestGridPos + shiftVector; + Vector3 lineEndPos = lineEndGlobal_ofLowestGridPos + shiftVector; + float distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 = Mathf.Abs((lineStartPos - lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global).magnitude / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + Color lineColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 1.0f - 0.9f * distanceOfVisualizedGridPosToPosAroundWhichToDraw_0to1); + Line_fadeableAnimSpeed.InternalDraw(lineStartPos, lineEndPos, lineColor, linesWidth_inGlobalUnits, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, vectorAlongGrowingLineWidth_normalizedInGlobalSpace, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + bool drawCoordsTextAtLeastOnce = (distanceBetweenRepeatingCoordsTexts_relToGridDistance >= 0.0f); + if (drawCoordsTextAtLeastOnce) + { + float localZPos_ofCurrGridPos_inLocalSpaceUnits = localZPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated + distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * i; + float coordsWithFixedRoundingError = (Mathf.Round(localZPos_ofCurrGridPos_inLocalSpaceUnits / distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder) * distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder); //-> fixing floatCalculationImprecisionErrors (like "0.099999999" -> "0.1") + string coordsAsText = GetCoordsAsText_forLocalZDimLines(coordsWithFixedRoundingError, lineColor); + Vector3 textPos_ifTextIsInsideRepresentedGridAxis = theZGridLines_areAlingedAlongX_notAlongY ? (lineCenterPos + localForward_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localRight_normalizedInGlobalSpace * textPosOffset) : (lineCenterPos - localForward_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localUp_normalizedInGlobalSpace * textPosOffset); + Vector3 textPos_ifTextIsPerpToRepresentedGridAxis = theZGridLines_areAlingedAlongX_notAlongY ? (lineCenterPos + localUp_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localRight_normalizedInGlobalSpace * textPosOffset) : (lineCenterPos - localRight_normalizedInGlobalSpace * spaceBetweenLineAndCoordsText_inGlobalUnits + localUp_normalizedInGlobalSpace * textPosOffset); + Vector3 textPos = lineWidthAndText_growsInsideRepresentedGridAxis_notPerpToIt ? textPos_ifTextIsInsideRepresentedGridAxis : textPos_ifTextIsPerpToRepresentedGridAxis; + UtilitiesDXXL_Text.Write(coordsAsText, textPos, lineColor, textSize, vectorAlongGridLine_normalizedInGlobalSpace, vectorAlongGrowingLineWidth_normalizedInGlobalSpace, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + DrawAdditionalCoordsTexts(vectorAlongGridLine_normalizedInGlobalSpace, vectorAlongGrowingLineWidth_normalizedInGlobalSpace, extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, distanceBetweenRepeatingCoordsTexts_relToGridDistance, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, lineColor, textPos, coordsAsText, textSize, durationInSec, hiddenByNearerObjects); + } + } + + TryDrawDistanceLines_fromDrawAroundPos_toNeighboringGridValue(forGridLINES_notForGridPLANES, scaleOfLocalSpace.z, localForward_normalizedInGlobalSpace, vectorAlongGridLine_normalizedInGlobalSpace, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, positionAroundWhichToDraw_global, localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_z, color, durationInSec, hiddenByNearerObjects); + } + + static string GetCoordsAsText_forLocalZDimLines(float coordsWithFixedRoundingError, Color lineColor) + { + if (DrawEngineBasics.skipLocalPrefix_inCoordinateTextsOnGridAxes) + { + if (DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes) + { + return ("" + coordsWithFixedRoundingError); + } + else + { + return ("z = " + coordsWithFixedRoundingError); + } + } + else + { + if (DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes) + { + return ("local" + coordsWithFixedRoundingError); + } + else + { + return ("localz = " + coordsWithFixedRoundingError); + } + } + } + + static void DrawAdditionalCoordsTexts(Vector3 vectorAlongGridLine_normalized, Vector3 textUp, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float distanceBetweenRepeatingCoordsTexts_relToGridDistance, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Color textColor, Vector3 unshiftedTextPos, string coordsAsText, float textSize, float durationInSec, bool hiddenByNearerObjects) + { + bool drawAdditionalCoordsTexts = (UtilitiesDXXL_Math.ApproximatelyZero(distanceBetweenRepeatingCoordsTexts_relToGridDistance) == false); //-> negative values of "distanceBetweenRepeatingCoordsTexts_relToGridDistance" don't even arrive here + if (drawAdditionalCoordsTexts) + { + distanceBetweenRepeatingCoordsTexts_relToGridDistance = Mathf.Max(distanceBetweenRepeatingCoordsTexts_relToGridDistance, min_distanceBetweenRepeatingCoordsTexts_relToGridDistance); //-> setting "distanceBetweenRepeatingCoordsTexts_relToGridDistance" to lower values can cause massive performance hit/editor freeze + if (extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits > distanceBetweenRepeatingCoordsTexts_relToGridDistance) + { + int numberOfAdditinalCoordsTexts = Mathf.FloorToInt(extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits / distanceBetweenRepeatingCoordsTexts_relToGridDistance); + numberOfAdditinalCoordsTexts = Mathf.Max(numberOfAdditinalCoordsTexts, 1); + for (int i_additionalCoordsText = 0; i_additionalCoordsText < numberOfAdditinalCoordsTexts; i_additionalCoordsText++) + { + Vector3 shiftVectorForward = vectorAlongGridLine_normalized * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * distanceBetweenRepeatingCoordsTexts_relToGridDistance * (1 + i_additionalCoordsText); + Vector3 posOfLowerText = unshiftedTextPos + shiftVectorForward; + Vector3 posOfHigherText = unshiftedTextPos - shiftVectorForward; + UtilitiesDXXL_Text.Write(coordsAsText, posOfLowerText, textColor, textSize, vectorAlongGridLine_normalized, textUp, DrawText.TextAnchorDXXL.LowerCenterOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + UtilitiesDXXL_Text.Write(coordsAsText, posOfHigherText, textColor, textSize, vectorAlongGridLine_normalized, textUp, DrawText.TextAnchorDXXL.LowerCenterOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + } + } + + static void DrawXDimPlanesDenseWithoutText(Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float drawDensity, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, float durationInSec, bool hiddenByNearerObjects, Color color, bool turned90DegAroundHisAxis) + { + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float lengthOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = 2.0f * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + float distanceBeweenLinesInsideGridSlice_inWorldUnits = gridDensityDefaultScaleFactor * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder / drawDensity; + int numberOfLinesPerGridSlice = Mathf.RoundToInt(lengthOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits / distanceBeweenLinesInsideGridSlice_inWorldUnits); + numberOfLinesPerGridSlice = Mathf.Max(numberOfLinesPerGridSlice, 3); + float halfNumberOfLinesPerGridSlice = 0.5f * numberOfLinesPerGridSlice; + + float positionAroundWhichToDraw_expressedInUnitsOfThisOrder_x = positionAroundWhichToDraw.x / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float xPos_ofLowestGridSlice = Mathf.Round(positionAroundWhichToDraw_expressedInUnitsOfThisOrder_x - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + Vector3 startPosGlobal_ofMainLineOfLowestGridSlice; + Vector3 endPosGlobal_ofMainLineOfLowestGridSlice; + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized; + if (turned90DegAroundHisAxis) + { + startPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(xPos_ofLowestGridSlice, positionAroundWhichToDraw.y, positionAroundWhichToDraw.z - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + endPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(xPos_ofLowestGridSlice, positionAroundWhichToDraw.y, positionAroundWhichToDraw.z + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized = Vector3.down; + } + else + { + startPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(xPos_ofLowestGridSlice, positionAroundWhichToDraw.y - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, positionAroundWhichToDraw.z); + endPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(xPos_ofLowestGridSlice, positionAroundWhichToDraw.y + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, positionAroundWhichToDraw.z); + vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized = Vector3.back; + } + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice = vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridSlicesAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 2; //-> "+ 2" instead of "+ 1", because otherwise planes pop to invisible before reaching nearZeroAlpha. The "distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1"-earlyContinue inside the for-loop ensures that the line count doesn't rise through this measure + numberOfVisualizedGridSlicesAlongAxis = Mathf.Max(numberOfVisualizedGridSlicesAlongAxis, 2); + for (int i_gridSlice = 0; i_gridSlice < numberOfVisualizedGridSlicesAlongAxis; i_gridSlice++) + { + Vector3 lowestSlice_to_currSlice = Vector3.right * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i_gridSlice; + float x_ofCurrSlice = startPosGlobal_ofMainLineOfLowestGridSlice.x + lowestSlice_to_currSlice.x; + float distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 = Mathf.Abs((x_ofCurrSlice - positionAroundWhichToDraw.x) / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + float alphaOfCurrGridSlicesMainLine = 1.0f - 0.9f * distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1; + Vector3 lineStartPos_ofLowestLineInsideSlice = startPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + Vector3 lineEndPos_ofLowestLineInsideSlice = endPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + + for (int i_lineInsideSlice = 0; i_lineInsideSlice < numberOfLinesPerGridSlice; i_lineInsideSlice++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 lowestLineInsideSlice_to_currLineInsideSlice = (-vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized) * distanceBeweenLinesInsideGridSlice_inWorldUnits * i_lineInsideSlice; + Vector3 startPos_ofLineInsideSlice = lineStartPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + Vector3 endPos_ofLineInsideSlice = lineEndPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + float distanceToCurrSlicesMainLine_0to1 = Mathf.Abs(((float)i_lineInsideSlice - halfNumberOfLinesPerGridSlice) / halfNumberOfLinesPerGridSlice); + float alphaOfLineInsideSlice = alphaOfCurrGridSlicesMainLine * (1.0f - 0.9f * distanceToCurrSlicesMainLine_0to1); + Color lineColor_ofLineInsideSlice = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfLineInsideSlice); + Line_fadeableAnimSpeed.InternalDraw(startPos_ofLineInsideSlice, endPos_ofLineInsideSlice, lineColor_ofLineInsideSlice, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + + static void DrawYDimPlanesDenseWithoutText(Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float drawDensity, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, float durationInSec, bool hiddenByNearerObjects, Color color, bool turned90DegAroundHisAxis) + { + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float lengthOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = 2.0f * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + float distanceBeweenLinesInsideGridSlice_inWorldUnits = gridDensityDefaultScaleFactor * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder / drawDensity; + int numberOfLinesPerGridSlice = Mathf.RoundToInt(lengthOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits / distanceBeweenLinesInsideGridSlice_inWorldUnits); + numberOfLinesPerGridSlice = Mathf.Max(numberOfLinesPerGridSlice, 3); + float halfNumberOfLinesPerGridSlice = 0.5f * numberOfLinesPerGridSlice; + + float positionAroundWhichToDraw_expressedInUnitsOfThisOrder_y = positionAroundWhichToDraw.y / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float yPos_ofLowestGridSlice = Mathf.Round(positionAroundWhichToDraw_expressedInUnitsOfThisOrder_y - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + Vector3 startPosGlobal_ofMainLineOfLowestGridSlice; + Vector3 endPosGlobal_ofMainLineOfLowestGridSlice; + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized; + if (turned90DegAroundHisAxis) + { + startPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(positionAroundWhichToDraw.x, yPos_ofLowestGridSlice, positionAroundWhichToDraw.z - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + endPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(positionAroundWhichToDraw.x, yPos_ofLowestGridSlice, positionAroundWhichToDraw.z + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized = Vector3.left; + } + else + { + startPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(positionAroundWhichToDraw.x - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, yPos_ofLowestGridSlice, positionAroundWhichToDraw.z); + endPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(positionAroundWhichToDraw.x + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, yPos_ofLowestGridSlice, positionAroundWhichToDraw.z); + vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized = Vector3.back; + } + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice = vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridSlicesAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 2; //-> "+ 2" instead of "+ 1", because otherwise planes pop to invisible before reaching nearZeroAlpha. The "distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1"-earlyContinue inside the for-loop ensures that the line count doesn't rise through this measure + numberOfVisualizedGridSlicesAlongAxis = Mathf.Max(numberOfVisualizedGridSlicesAlongAxis, 2); + for (int i_gridSlice = 0; i_gridSlice < numberOfVisualizedGridSlicesAlongAxis; i_gridSlice++) + { + Vector3 lowestSlice_to_currSlice = Vector3.up * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i_gridSlice; + float y_ofCurrSlice = startPosGlobal_ofMainLineOfLowestGridSlice.y + lowestSlice_to_currSlice.y; + float distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 = Mathf.Abs((y_ofCurrSlice - positionAroundWhichToDraw.y) / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + float alphaOfCurrGridSlicesMainLine = 1.0f - 0.9f * distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1; + Vector3 lineStartPos_ofLowestLineInsideSlice = startPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + Vector3 lineEndPos_ofLowestLineInsideSlice = endPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + + for (int i_lineInsideSlice = 0; i_lineInsideSlice < numberOfLinesPerGridSlice; i_lineInsideSlice++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 lowestLineInsideSlice_to_currLineInsideSlice = (-vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized) * distanceBeweenLinesInsideGridSlice_inWorldUnits * i_lineInsideSlice; + Vector3 startPos_ofLineInsideSlice = lineStartPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + Vector3 endPos_ofLineInsideSlice = lineEndPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + float distanceToCurrSlicesMainLine_0to1 = Mathf.Abs(((float)i_lineInsideSlice - halfNumberOfLinesPerGridSlice) / halfNumberOfLinesPerGridSlice); + float alphaOfLineInsideSlice = alphaOfCurrGridSlicesMainLine * (1.0f - 0.9f * distanceToCurrSlicesMainLine_0to1); + Color lineColor_ofLineInsideSlice = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfLineInsideSlice); + Line_fadeableAnimSpeed.InternalDraw(startPos_ofLineInsideSlice, endPos_ofLineInsideSlice, lineColor_ofLineInsideSlice, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + + + static void DrawZDimPlanesDenseWithoutText(Vector3 positionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float drawDensity, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, float durationInSec, bool hiddenByNearerObjects, Color color, bool turned90DegAroundHisAxis) + { + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float lengthOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = 2.0f * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + float distanceBeweenLinesInsideGridSlice_inWorldUnits = gridDensityDefaultScaleFactor * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder / drawDensity; + int numberOfLinesPerGridSlice = Mathf.RoundToInt(lengthOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits / distanceBeweenLinesInsideGridSlice_inWorldUnits); + numberOfLinesPerGridSlice = Mathf.Max(numberOfLinesPerGridSlice, 3); + float halfNumberOfLinesPerGridSlice = 0.5f * numberOfLinesPerGridSlice; + + float positionAroundWhichToDraw_expressedInUnitsOfThisOrder_z = positionAroundWhichToDraw.z / distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float zPos_ofLowestGridSlice = Mathf.Round(positionAroundWhichToDraw_expressedInUnitsOfThisOrder_z - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + Vector3 startPosGlobal_ofMainLineOfLowestGridSlice; + Vector3 endPosGlobal_ofMainLineOfLowestGridSlice; + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized; + if (turned90DegAroundHisAxis) + { + startPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(positionAroundWhichToDraw.x - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, positionAroundWhichToDraw.y, zPos_ofLowestGridSlice); + endPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(positionAroundWhichToDraw.x + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, positionAroundWhichToDraw.y, zPos_ofLowestGridSlice); + vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized = Vector3.down; + } + else + { + startPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(positionAroundWhichToDraw.x, positionAroundWhichToDraw.y - extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, zPos_ofLowestGridSlice); + endPosGlobal_ofMainLineOfLowestGridSlice = new Vector3(positionAroundWhichToDraw.x, positionAroundWhichToDraw.y + extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits, zPos_ofLowestGridSlice); + vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized = Vector3.left; + } + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice = vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridSlicesAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 2; //-> "+ 2" instead of "+ 1", because otherwise planes pop to invisible before reaching nearZeroAlpha. The "distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1"-earlyContinue inside the for-loop ensures that the line count doesn't rise through this measure + numberOfVisualizedGridSlicesAlongAxis = Mathf.Max(numberOfVisualizedGridSlicesAlongAxis, 2); + for (int i_gridSlice = 0; i_gridSlice < numberOfVisualizedGridSlicesAlongAxis; i_gridSlice++) + { + Vector3 lowestSlice_to_currSlice = Vector3.forward * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i_gridSlice; + float z_ofCurrSlice = startPosGlobal_ofMainLineOfLowestGridSlice.z + lowestSlice_to_currSlice.z; + float distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 = Mathf.Abs((z_ofCurrSlice - positionAroundWhichToDraw.z) / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + float alphaOfCurrGridSlicesMainLine = 1.0f - 0.9f * distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1; + Vector3 lineStartPos_ofLowestLineInsideSlice = startPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + Vector3 lineEndPos_ofLowestLineInsideSlice = endPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + + for (int i_lineInsideSlice = 0; i_lineInsideSlice < numberOfLinesPerGridSlice; i_lineInsideSlice++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 lowestLineInsideSlice_to_currLineInsideSlice = (-vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized) * distanceBeweenLinesInsideGridSlice_inWorldUnits * i_lineInsideSlice; + Vector3 startPos_ofLineInsideSlice = lineStartPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + Vector3 endPos_ofLineInsideSlice = lineEndPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + float distanceToCurrSlicesMainLine_0to1 = Mathf.Abs(((float)i_lineInsideSlice - halfNumberOfLinesPerGridSlice) / halfNumberOfLinesPerGridSlice); + float alphaOfLineInsideSlice = alphaOfCurrGridSlicesMainLine * (1.0f - 0.9f * distanceToCurrSlicesMainLine_0to1); + Color lineColor_ofLineInsideSlice = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfLineInsideSlice); + Line_fadeableAnimSpeed.InternalDraw(startPos_ofLineInsideSlice, endPos_ofLineInsideSlice, lineColor_ofLineInsideSlice, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + + static void DrawXDimPlanesDenseWithoutTextLocal(Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float drawDensity, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, float durationInSec, bool hiddenByNearerObjects, Color color, bool turned90DegAroundHisAxis) + { + float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.x; + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float lengthOfDrawnLinesAtEachGridSlicePos_inWorldUnits = 2.0f * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + float distanceBeweenLinesInsideGridSlice_inWorldUnits = gridDensityDefaultScaleFactor * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder / drawDensity; + int numberOfLinesPerGridSlice = Mathf.RoundToInt(lengthOfDrawnLinesAtEachGridSlicePos_inWorldUnits / distanceBeweenLinesInsideGridSlice_inWorldUnits); + numberOfLinesPerGridSlice = Mathf.Max(numberOfLinesPerGridSlice, 3); + float halfNumberOfLinesPerGridSlice = 0.5f * numberOfLinesPerGridSlice; + + float localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_x = localPositionAroundWhichToDraw.x / distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + float localXPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated = Mathf.Round(localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_x - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + + float distance_fromDrawAroundPos_to_smallestXGridPos_inGlobalWorldUnits = Mathf.Abs(localXPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated - localPositionAroundWhichToDraw.x) * scaleOfLocalSpace.x; + Vector3 drawAroundPosGlobal_to_smallestXGlobal = (-localRight_normalizedInGlobalSpace) * distance_fromDrawAroundPos_to_smallestXGridPos_inGlobalWorldUnits; + Vector3 lineCenterGlobal_to_lineEndGlobal = turned90DegAroundHisAxis ? (localForward_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits) : (localUp_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + Vector3 lineCenterGlobal_ofLowestGridSlice = positionAroundWhichToDraw_global + drawAroundPosGlobal_to_smallestXGlobal; + Vector3 startPosGlobal_ofMainLineOfLowestGridSlice = lineCenterGlobal_ofLowestGridSlice - lineCenterGlobal_to_lineEndGlobal; + Vector3 endPosGlobal_ofMainLineOfLowestGridSlice = lineCenterGlobal_ofLowestGridSlice + lineCenterGlobal_to_lineEndGlobal; + Vector3 lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global = positionAroundWhichToDraw_global - lineCenterGlobal_to_lineEndGlobal; + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized = turned90DegAroundHisAxis ? (-localUp_normalizedInGlobalSpace) : (-localForward_normalizedInGlobalSpace); + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice = vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridSlicesAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 2; //-> "+ 2" instead of "+ 1", because otherwise planes pop to invisible before reaching nearZeroAlpha. The "distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1"-earlyContinue inside the for-loop ensures that the line count doesn't rise through this measure + numberOfVisualizedGridSlicesAlongAxis = Mathf.Max(numberOfVisualizedGridSlicesAlongAxis, 2); + for (int i_gridSlice = 0; i_gridSlice < numberOfVisualizedGridSlicesAlongAxis; i_gridSlice++) + { + Vector3 lowestSlice_to_currSlice = localRight_normalizedInGlobalSpace * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i_gridSlice; + Vector3 lineStartPos_ofMainLineInsideSlice = startPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice; + Vector3 lineEndPos_ofMainLineInsideSlice = endPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice; + float distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 = Mathf.Abs((lineStartPos_ofMainLineInsideSlice - lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global).magnitude / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + float alphaOfCurrGridSlicesMainLine = 1.0f - 0.9f * distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1; + Vector3 lineStartPos_ofLowestLineInsideSlice = lineStartPos_ofMainLineInsideSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + Vector3 lineEndPos_ofLowestLineInsideSlice = lineEndPos_ofMainLineInsideSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + + for (int i_lineInsideSlice = 0; i_lineInsideSlice < numberOfLinesPerGridSlice; i_lineInsideSlice++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 lowestLineInsideSlice_to_currLineInsideSlice = (-vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized) * distanceBeweenLinesInsideGridSlice_inWorldUnits * i_lineInsideSlice; + Vector3 startPos_ofLineInsideSlice = lineStartPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + Vector3 endPos_ofLineInsideSlice = lineEndPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + float distanceToCurrSlicesMainLine_0to1 = Mathf.Abs(((float)i_lineInsideSlice - halfNumberOfLinesPerGridSlice) / halfNumberOfLinesPerGridSlice); + float alphaOfLineInsideSlice = alphaOfCurrGridSlicesMainLine * (1.0f - 0.9f * distanceToCurrSlicesMainLine_0to1); + Color lineColor_ofLineInsideSlice = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfLineInsideSlice); + Line_fadeableAnimSpeed.InternalDraw(startPos_ofLineInsideSlice, endPos_ofLineInsideSlice, lineColor_ofLineInsideSlice, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + + static void DrawYDimPlanesDenseWithoutTextLocal(Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float drawDensity, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, float durationInSec, bool hiddenByNearerObjects, Color color, bool turned90DegAroundHisAxis) + { + float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.y; + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float lengthOfDrawnLinesAtEachGridSlicePos_inWorldUnits = 2.0f * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + float distanceBeweenLinesInsideGridSlice_inWorldUnits = gridDensityDefaultScaleFactor * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder / drawDensity; + int numberOfLinesPerGridSlice = Mathf.RoundToInt(lengthOfDrawnLinesAtEachGridSlicePos_inWorldUnits / distanceBeweenLinesInsideGridSlice_inWorldUnits); + numberOfLinesPerGridSlice = Mathf.Max(numberOfLinesPerGridSlice, 3); + float halfNumberOfLinesPerGridSlice = 0.5f * numberOfLinesPerGridSlice; + + float localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_y = localPositionAroundWhichToDraw.y / distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + float localYPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated = Mathf.Round(localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_y - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + + float distance_fromDrawAroundPos_to_smallestYGridPos_inGlobalWorldUnits = Mathf.Abs(localYPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated - localPositionAroundWhichToDraw.y) * scaleOfLocalSpace.y; + Vector3 drawAroundPosGlobal_to_smallestYGlobal = (-localUp_normalizedInGlobalSpace) * distance_fromDrawAroundPos_to_smallestYGridPos_inGlobalWorldUnits; + Vector3 lineCenterGlobal_to_lineEndGlobal = turned90DegAroundHisAxis ? (localForward_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits) : (localRight_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + Vector3 lineCenterGlobal_ofLowestGridSlice = positionAroundWhichToDraw_global + drawAroundPosGlobal_to_smallestYGlobal; + Vector3 startPosGlobal_ofMainLineOfLowestGridSlice = lineCenterGlobal_ofLowestGridSlice - lineCenterGlobal_to_lineEndGlobal; + Vector3 endPosGlobal_ofMainLineOfLowestGridSlice = lineCenterGlobal_ofLowestGridSlice + lineCenterGlobal_to_lineEndGlobal; + Vector3 lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global = positionAroundWhichToDraw_global - lineCenterGlobal_to_lineEndGlobal; + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized = turned90DegAroundHisAxis ? (-localRight_normalizedInGlobalSpace) : (-localForward_normalizedInGlobalSpace); + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice = vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridSlicesAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 2; //-> "+ 2" instead of "+ 1", because otherwise planes pop to invisible before reaching nearZeroAlpha. The "distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1"-earlyContinue inside the for-loop ensures that the line count doesn't rise through this measure + numberOfVisualizedGridSlicesAlongAxis = Mathf.Max(numberOfVisualizedGridSlicesAlongAxis, 2); + for (int i_gridSlice = 0; i_gridSlice < numberOfVisualizedGridSlicesAlongAxis; i_gridSlice++) + { + Vector3 lowestSlice_to_currSlice = localUp_normalizedInGlobalSpace * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i_gridSlice; + Vector3 lineStartPos_ofMainLineInsideSlice = startPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice; + Vector3 lineEndPos_ofMainLineInsideSlice = endPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice; + float distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 = Mathf.Abs((lineStartPos_ofMainLineInsideSlice - lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global).magnitude / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + float alphaOfCurrGridSlicesMainLine = 1.0f - 0.9f * distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1; + Vector3 lineStartPos_ofLowestLineInsideSlice = lineStartPos_ofMainLineInsideSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + Vector3 lineEndPos_ofLowestLineInsideSlice = lineEndPos_ofMainLineInsideSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + + for (int i_lineInsideSlice = 0; i_lineInsideSlice < numberOfLinesPerGridSlice; i_lineInsideSlice++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 lowestLineInsideSlice_to_currLineInsideSlice = (-vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized) * distanceBeweenLinesInsideGridSlice_inWorldUnits * i_lineInsideSlice; + Vector3 startPos_ofLineInsideSlice = lineStartPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + Vector3 endPos_ofLineInsideSlice = lineEndPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + float distanceToCurrSlicesMainLine_0to1 = Mathf.Abs(((float)i_lineInsideSlice - halfNumberOfLinesPerGridSlice) / halfNumberOfLinesPerGridSlice); + float alphaOfLineInsideSlice = alphaOfCurrGridSlicesMainLine * (1.0f - 0.9f * distanceToCurrSlicesMainLine_0to1); + Color lineColor_ofLineInsideSlice = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfLineInsideSlice); + Line_fadeableAnimSpeed.InternalDraw(startPos_ofLineInsideSlice, endPos_ofLineInsideSlice, lineColor_ofLineInsideSlice, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + + static void DrawZDimPlanesDenseWithoutTextLocal(Vector3 positionAroundWhichToDraw_global, Vector3 localForward_normalizedInGlobalSpace, Vector3 localUp_normalizedInGlobalSpace, Vector3 localRight_normalizedInGlobalSpace, Vector3 scaleOfLocalSpace, Vector3 localPositionAroundWhichToDraw, float extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits, float extentOfWholeCascadeAlongAxis_inOrdersOwnUnits, float drawDensity, float distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder, float durationInSec, bool hiddenByNearerObjects, Color color, bool turned90DegAroundHisAxis) + { + float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder = distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder * scaleOfLocalSpace.z; + float extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits = extentOfDrawnLinesAtEachFixedPosOnAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float extentOfWholeCascadeAlongAxis_inWorldUnits = extentOfWholeCascadeAlongAxis_inOrdersOwnUnits * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float lengthOfDrawnLinesAtEachGridSlicePos_inWorldUnits = 2.0f * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + float distanceBeweenLinesInsideGridSlice_inWorldUnits = gridDensityDefaultScaleFactor * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder / drawDensity; + int numberOfLinesPerGridSlice = Mathf.RoundToInt(lengthOfDrawnLinesAtEachGridSlicePos_inWorldUnits / distanceBeweenLinesInsideGridSlice_inWorldUnits); + numberOfLinesPerGridSlice = Mathf.Max(numberOfLinesPerGridSlice, 3); + float halfNumberOfLinesPerGridSlice = 0.5f * numberOfLinesPerGridSlice; + + float localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_z = localPositionAroundWhichToDraw.z / distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + float localZPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated = Mathf.Round(localPositionAroundWhichToDraw_expressedInUnitsOfThisOrder_z - extentOfWholeCascadeAlongAxis_inOrdersOwnUnits) * distanceBetweenVisualizedGridPointsInLocalSpaceUnits_forThisOrder; + + float distance_fromDrawAroundPos_to_smallestZGridPos_inGlobalWorldUnits = Mathf.Abs(localZPos_ofLowestGridPos_inLocalSpaceUnits_ifUnrotated - localPositionAroundWhichToDraw.z) * scaleOfLocalSpace.z; + Vector3 drawAroundPosGlobal_to_smallestZGlobal = (-localForward_normalizedInGlobalSpace) * distance_fromDrawAroundPos_to_smallestZGridPos_inGlobalWorldUnits; + Vector3 lineCenterGlobal_to_lineEndGlobal = turned90DegAroundHisAxis ? (localRight_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits) : (localUp_normalizedInGlobalSpace * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits); + Vector3 lineCenterGlobal_ofLowestGridSlice = positionAroundWhichToDraw_global + drawAroundPosGlobal_to_smallestZGlobal; + Vector3 startPosGlobal_ofMainLineOfLowestGridSlice = lineCenterGlobal_ofLowestGridSlice - lineCenterGlobal_to_lineEndGlobal; + Vector3 endPosGlobal_ofMainLineOfLowestGridSlice = lineCenterGlobal_ofLowestGridSlice + lineCenterGlobal_to_lineEndGlobal; + Vector3 lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global = positionAroundWhichToDraw_global - lineCenterGlobal_to_lineEndGlobal; + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized = turned90DegAroundHisAxis ? (-localUp_normalizedInGlobalSpace) : (-localRight_normalizedInGlobalSpace); + Vector3 vectorFromGridSlicesMainLineToLowestLineInsideSlice = vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized * extentOfDrawnLinesAtEachFixedPosOnAxis_inWorldUnits; + + float lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits = 2.0f * extentOfWholeCascadeAlongAxis_inOrdersOwnUnits; + int numberOfVisualizedGridSlicesAlongAxis = Mathf.RoundToInt(lengthOfWholeCascadeAlongAxis_inOrdersOwnUnits) + 2; //-> "+ 2" instead of "+ 1", because otherwise planes pop to invisible before reaching nearZeroAlpha. The "distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1"-earlyContinue inside the for-loop ensures that the line count doesn't rise through this measure + numberOfVisualizedGridSlicesAlongAxis = Mathf.Max(numberOfVisualizedGridSlicesAlongAxis, 2); + for (int i_gridSlice = 0; i_gridSlice < numberOfVisualizedGridSlicesAlongAxis; i_gridSlice++) + { + Vector3 lowestSlice_to_currSlice = localForward_normalizedInGlobalSpace * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder * i_gridSlice; + Vector3 lineStartPos_ofMainLineInsideSlice = startPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice; + Vector3 lineEndPos_ofMainLineInsideSlice = endPosGlobal_ofMainLineOfLowestGridSlice + lowestSlice_to_currSlice; + float distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 = Mathf.Abs((lineStartPos_ofMainLineInsideSlice - lineStartPos_ifALineWouldBeDrawnThroughPositionAroundWhichToDraw_global).magnitude / extentOfWholeCascadeAlongAxis_inWorldUnits); + if (distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1 > 1.12f) { continue; } //-> saving some performance for planes that are anyway not visible (because their alpha reached zero) + float alphaOfCurrGridSlicesMainLine = 1.0f - 0.9f * distanceOfCurrGridSliceToPosAroundWhichToDraw_0to1; + Vector3 lineStartPos_ofLowestLineInsideSlice = lineStartPos_ofMainLineInsideSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + Vector3 lineEndPos_ofLowestLineInsideSlice = lineEndPos_ofMainLineInsideSlice + vectorFromGridSlicesMainLineToLowestLineInsideSlice; + + for (int i_lineInsideSlice = 0; i_lineInsideSlice < numberOfLinesPerGridSlice; i_lineInsideSlice++) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + Vector3 lowestLineInsideSlice_to_currLineInsideSlice = (-vectorFromGridSlicesMainLineToLowestLineInsideSlice_normalized) * distanceBeweenLinesInsideGridSlice_inWorldUnits * i_lineInsideSlice; + Vector3 startPos_ofLineInsideSlice = lineStartPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + Vector3 endPos_ofLineInsideSlice = lineEndPos_ofLowestLineInsideSlice + lowestLineInsideSlice_to_currLineInsideSlice; + float distanceToCurrSlicesMainLine_0to1 = Mathf.Abs(((float)i_lineInsideSlice - halfNumberOfLinesPerGridSlice) / halfNumberOfLinesPerGridSlice); + float alphaOfLineInsideSlice = alphaOfCurrGridSlicesMainLine * (1.0f - 0.9f * distanceToCurrSlicesMainLine_0to1); + Color lineColor_ofLineInsideSlice = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaOfLineInsideSlice); + Line_fadeableAnimSpeed.InternalDraw(startPos_ofLineInsideSlice, endPos_ofLineInsideSlice, lineColor_ofLineInsideSlice, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + + static void TryDrawDistanceLines_fromDrawAroundPos_toNeighboringGridValue(bool forGridLINES_notForGridPLANES, float scaleOfLocalSpace, Vector3 forwardNormalized_ofRepresentedGridAxis, Vector3 vectorAlongGridLine_normalized, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Vector3 positionAroundWhichToDraw_global, float positionAroundWhichToDraw_expressedInUnitsOfThisOrder, Color colorOfGridLines, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawEngineBasics.hide_distanceDisplay_forGrids == false) + { + float floor_of_positionAroundWhichToDraw_expressedInUnitsOfThisOrder = Mathf.Floor(positionAroundWhichToDraw_expressedInUnitsOfThisOrder); + float floorToDrawAroundPos_expressedInUnitsOfThisOrder = positionAroundWhichToDraw_expressedInUnitsOfThisOrder - floor_of_positionAroundWhichToDraw_expressedInUnitsOfThisOrder; + float drawAroundPosToCeil_expressedInUnitsOfThisOrder = 1.0f - floorToDrawAroundPos_expressedInUnitsOfThisOrder; + float portion0to1_ofDrawAroundPos_fromNextLowerToNextHigherGridLine = floorToDrawAroundPos_expressedInUnitsOfThisOrder; + + float distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace = floorToDrawAroundPos_expressedInUnitsOfThisOrder * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace = drawAroundPosToCeil_expressedInUnitsOfThisOrder * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace = Mathf.Approximately(1.0f, scaleOfLocalSpace) ? distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace : (distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace / scaleOfLocalSpace); //-> slightly complicated calculation pattern (instead of plainly diving by "scaleOfLocalSpace", which shouldn't make a difference if it is anyway "1"), because float calculations should be avoided here if possible, since they may introduce errors that will get displayed as text + float distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace = Mathf.Approximately(1.0f, scaleOfLocalSpace) ? distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace : (distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace / scaleOfLocalSpace); //-> slightly complicated calculation pattern (instead of plainly diving by "scaleOfLocalSpace", which shouldn't make a difference if it is anyway "1"), because float calculations should be avoided here if possible, since they may introduce errors that will get displayed as text + + float shiftOffsetDistance_fromDrawAroundPos_toDistanceDisplay = DrawEngineBasics.offsetForDistanceDisplays_inGrids * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + Vector3 shiftOffsetVector_fromDrawAroundPos_toDistanceDisplay = shiftOffsetDistance_fromDrawAroundPos_toDistanceDisplay * vectorAlongGridLine_normalized; + Vector3 positionAroundWhichToDraw_shiftedParallelToGrid_toDistanceDisplay = positionAroundWhichToDraw_global + shiftOffsetVector_fromDrawAroundPos_toDistanceDisplay; + Vector3 endOfDistanceVector_onNextLOWERgridPosition = positionAroundWhichToDraw_shiftedParallelToGrid_toDistanceDisplay - forwardNormalized_ofRepresentedGridAxis * distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace; + Vector3 endOfDistanceVector_onNextHIGHERgridPosition = positionAroundWhichToDraw_shiftedParallelToGrid_toDistanceDisplay + forwardNormalized_ofRepresentedGridAxis * distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace; + + float portion0to1_beside0p5_whereSecondaryVectorIsCompletelyFadedOut = 0.125f; + float Op5_minus_portion0to1_beside0p5_whereSecondaryVectorIsCompletelyFadedOut = 0.5f - portion0to1_beside0p5_whereSecondaryVectorIsCompletelyFadedOut; + float alpha_ofColorToBelow_insideFadeOutSpan = 1.0f - UtilitiesDXXL_Math.Get_2degParabolicFlateningRise((portion0to1_ofDrawAroundPos_fromNextLowerToNextHigherGridLine - 0.5f) / portion0to1_beside0p5_whereSecondaryVectorIsCompletelyFadedOut); + float alpha_ofColorToAbove_insideFadeOutSpan = UtilitiesDXXL_Math.Get_2degParabolicSteepeningRise((portion0to1_ofDrawAroundPos_fromNextLowerToNextHigherGridLine - Op5_minus_portion0to1_beside0p5_whereSecondaryVectorIsCompletelyFadedOut) / portion0to1_beside0p5_whereSecondaryVectorIsCompletelyFadedOut); + float alpha_ofColorToBelow_ifOnSideOfLongerVector = (portion0to1_ofDrawAroundPos_fromNextLowerToNextHigherGridLine > (0.5f + portion0to1_beside0p5_whereSecondaryVectorIsCompletelyFadedOut)) ? 0.0f : alpha_ofColorToBelow_insideFadeOutSpan; + float alpha_ofColorToAbove_ifOnSideOfLongerVector = (portion0to1_ofDrawAroundPos_fromNextLowerToNextHigherGridLine < (0.5f - portion0to1_beside0p5_whereSecondaryVectorIsCompletelyFadedOut)) ? 0.0f : alpha_ofColorToAbove_insideFadeOutSpan; + float alpha_ofColorToBelow = (portion0to1_ofDrawAroundPos_fromNextLowerToNextHigherGridLine < 0.5f) ? 1.0f : alpha_ofColorToBelow_ifOnSideOfLongerVector; + float alpha_ofColorToAbove = (portion0to1_ofDrawAroundPos_fromNextLowerToNextHigherGridLine > 0.5f) ? 1.0f : alpha_ofColorToAbove_ifOnSideOfLongerVector; + + bool toBelow_isVisible = (UtilitiesDXXL_Math.ApproximatelyZero(alpha_ofColorToBelow) == false); + bool toAbove_isVisible = (UtilitiesDXXL_Math.ApproximatelyZero(alpha_ofColorToAbove) == false); + + Color colorOfVectorToBelow = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorOfGridLines, alpha_ofColorToBelow); + Color colorOfVectorToAbove = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorOfGridLines, alpha_ofColorToAbove); + + float lineWidth_ofDistanceLine = 0.04f * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + + DrawDistanceVectors(toBelow_isVisible, toAbove_isVisible, distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace, distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace, positionAroundWhichToDraw_shiftedParallelToGrid_toDistanceDisplay, endOfDistanceVector_onNextLOWERgridPosition, endOfDistanceVector_onNextHIGHERgridPosition, lineWidth_ofDistanceLine, vectorAlongGridLine_normalized, colorOfVectorToBelow, colorOfVectorToAbove, durationInSec, hiddenByNearerObjects); + DrawDistanceTexts(toBelow_isVisible, toAbove_isVisible, distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace, distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace, endOfDistanceVector_onNextLOWERgridPosition, endOfDistanceVector_onNextHIGHERgridPosition, forwardNormalized_ofRepresentedGridAxis, vectorAlongGridLine_normalized, lineWidth_ofDistanceLine, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, colorOfVectorToBelow, colorOfVectorToAbove, durationInSec, hiddenByNearerObjects); + DrawDistanceEndPlates(forGridLINES_notForGridPLANES, toBelow_isVisible, toAbove_isVisible, endOfDistanceVector_onNextLOWERgridPosition, endOfDistanceVector_onNextHIGHERgridPosition, forwardNormalized_ofRepresentedGridAxis, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, colorOfVectorToBelow, colorOfVectorToAbove, durationInSec, hiddenByNearerObjects); + DrawDashedLineToDistanceVector(positionAroundWhichToDraw_global, positionAroundWhichToDraw_shiftedParallelToGrid_toDistanceDisplay, forwardNormalized_ofRepresentedGridAxis, vectorAlongGridLine_normalized, distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, colorOfGridLines, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawDistanceVectors(bool toBelow_isVisible, bool toAbove_isVisible, float distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace, float distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace, Vector3 positionAroundWhichToDraw_shiftedParallelToGrid_toDistanceDisplay, Vector3 endOfDistanceVector_onNextLOWERgridPosition, Vector3 endOfDistanceVector_onNextHIGHERgridPosition, float lineWidth_ofDistanceLine, Vector3 vectorAlongGridLine_normalized, Color colorOfVectorToBelow, Color colorOfVectorToAbove, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 customAmplitudeAndTextDir = vectorAlongGridLine_normalized; + float endPlates_size = 0.0f; //-> the end plates are drawn separately, so not here together with the vector + float coneLength = 0.17f; + bool flattenThickRoundLineIntoAmplitudePlane = true; + bool pointerAtBothSides = true; + + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + + if (toBelow_isVisible) + { + if (distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace > UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.shortestLineWithDefinedAmplitudeDir_withTolerancePadding) + { + DrawBasics.Vector(positionAroundWhichToDraw_shiftedParallelToGrid_toDistanceDisplay, endOfDistanceVector_onNextLOWERgridPosition, colorOfVectorToBelow, lineWidth_ofDistanceLine, null, coneLength, pointerAtBothSides, flattenThickRoundLineIntoAmplitudePlane, customAmplitudeAndTextDir, false, 0.0f, false, endPlates_size, durationInSec, hiddenByNearerObjects); + } + } + + if (toAbove_isVisible) + { + if (distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inWorldSpace > UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.shortestLineWithDefinedAmplitudeDir_withTolerancePadding) + { + DrawBasics.Vector(positionAroundWhichToDraw_shiftedParallelToGrid_toDistanceDisplay, endOfDistanceVector_onNextHIGHERgridPosition, colorOfVectorToAbove, lineWidth_ofDistanceLine, null, coneLength, pointerAtBothSides, flattenThickRoundLineIntoAmplitudePlane, customAmplitudeAndTextDir, false, 0.0f, false, endPlates_size, durationInSec, hiddenByNearerObjects); + } + } + + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + static void DrawDistanceTexts(bool toBelow_isVisible, bool toAbove_isVisible, float distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace, float distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace, Vector3 endOfDistanceVector_onNextLOWERgridPosition, Vector3 endOfDistanceVector_onNextHIGHERgridPosition, Vector3 forwardNormalized_ofRepresentedGridAxis, Vector3 vectorAlongGridLine_normalized, float lineWidth_ofDistanceLine, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Color colorOfVectorToBelow, Color colorOfVectorToAbove, float durationInSec, bool hiddenByNearerObjects) + { + float size = 0.1f;//-> will anyway get overwritten by "forceTextBlockEnlargementToThisMinWidth"/"forceRestrictTextBlockSizeToThisMaxTextWidth" + Vector3 textDirection = forwardNormalized_ofRepresentedGridAxis; + Vector3 textUp = vectorAlongGridLine_normalized; + Vector3 textShiftOffset_thatCompensatesLineWidth = 0.5f * lineWidth_ofDistanceLine * vectorAlongGridLine_normalized; + float forceTextBlockEnlargementToThisMinWidth = 0.7f * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + float forceRestrictTextBlockSizeToThisMaxTextWidth = forceTextBlockEnlargementToThisMinWidth; + int strokeWidth = 60000; + + string text; + Vector3 textPosition; + DrawText.TextAnchorDXXL textAnchor; + + if (toBelow_isVisible) + { + if (Mathf.Approximately(0.0f, distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace)) + { + //-> mitigate non-stable flickering (due to float calculation imprecision) between different grid segments (if the drawAroundPos is right on the border) by drawing the text for both side in these cases: + text = DrawText.MarkupStrokeWidth("-" + distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace, strokeWidth); + textPosition = endOfDistanceVector_onNextLOWERgridPosition + GetDistanceTextPositionOffset_relToVectorLine_forDisanceDisplayBELOWtheVectorLine(distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, vectorAlongGridLine_normalized); + textAnchor = DrawText.TextAnchorDXXL.UpperRight; + UtilitiesDXXL_Text.WriteFramed(text, textPosition, colorOfVectorToBelow, size, textDirection, textUp, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, 0.0f, true, durationInSec, hiddenByNearerObjects); + + //Adding a "+" prefix, so that the text size difference doesn't get to irritatingly big: + text = DrawText.MarkupStrokeWidth("+" + distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace, strokeWidth); + } + else + { + text = DrawText.MarkupStrokeWidth("" + distanceToNextGridLineBELOWdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace, strokeWidth); + } + + textPosition = endOfDistanceVector_onNextLOWERgridPosition + textShiftOffset_thatCompensatesLineWidth + GetDistanceTextPositionOffset_relToVectorLine_forDisanceDisplayABOVEtheVectorLine(distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, vectorAlongGridLine_normalized); + textAnchor = DrawText.TextAnchorDXXL.LowerLeftOfFirstLine; + UtilitiesDXXL_Text.WriteFramed(text, textPosition, colorOfVectorToBelow, size, textDirection, textUp, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + + if (toAbove_isVisible) + { + if (Mathf.Approximately(0.0f, distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace)) + { + //-> mitigate non-stable flickering (due to float calculation imprecision) between different grid segments (if the drawAroundPos is right on the border) by drawing the text for both side in these cases: + text = DrawText.MarkupStrokeWidth("+" + distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace, strokeWidth); + textPosition = endOfDistanceVector_onNextHIGHERgridPosition + textShiftOffset_thatCompensatesLineWidth + GetDistanceTextPositionOffset_relToVectorLine_forDisanceDisplayABOVEtheVectorLine(distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, vectorAlongGridLine_normalized); + textAnchor = DrawText.TextAnchorDXXL.LowerLeftOfFirstLine; + UtilitiesDXXL_Text.WriteFramed(text, textPosition, colorOfVectorToAbove, size, textDirection, textUp, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, 0.0f, true, durationInSec, hiddenByNearerObjects); + + //Adding a "-" prefix, so that the text size difference doesn't get to irritatingly big: + text = DrawText.MarkupStrokeWidth("-" + distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace, strokeWidth); + } + else + { + text = DrawText.MarkupStrokeWidth("" + distanceToNextGridLineABOVEdrawAroundPos_forCurrentOrderOfMagnitude_inLocalSpace, strokeWidth); + } + + textPosition = endOfDistanceVector_onNextHIGHERgridPosition + GetDistanceTextPositionOffset_relToVectorLine_forDisanceDisplayBELOWtheVectorLine(distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, vectorAlongGridLine_normalized); + textAnchor = DrawText.TextAnchorDXXL.UpperRight; + UtilitiesDXXL_Text.WriteFramed(text, textPosition, colorOfVectorToAbove, size, textDirection, textUp, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawDistanceEndPlates(bool forGridLINES_notForGridPLANES, bool toBelow_isVisible, bool toAbove_isVisible, Vector3 endOfDistanceVector_onNextLOWERgridPosition, Vector3 endOfDistanceVector_onNextHIGHERgridPosition, Vector3 forwardNormalized_ofRepresentedGridAxis, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Color colorOfVectorToBelow, Color colorOfVectorToAbove, float durationInSec, bool hiddenByNearerObjects) + { + if (forGridLINES_notForGridPLANES == false) + { + float radius = 0.08f * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + Vector3 normal = forwardNormalized_ofRepresentedGridAxis; + bool filledWithSpokes = true; + float alphaFactor_forDecagons = 0.7f; + Color colorOfDecagon_forVectorToBelow = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorOfVectorToBelow, alphaFactor_forDecagons); + Color colorOfDecagon_forVectorToAbove = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorOfVectorToAbove, alphaFactor_forDecagons); + + if (toBelow_isVisible) + { + DrawShapes.Decagon(endOfDistanceVector_onNextLOWERgridPosition, radius, colorOfDecagon_forVectorToBelow, normal, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + } + + if (toAbove_isVisible) + { + DrawShapes.Decagon(endOfDistanceVector_onNextHIGHERgridPosition, radius, colorOfDecagon_forVectorToAbove, normal, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects); + } + } + } + + static void DrawDashedLineToDistanceVector(Vector3 positionAroundWhichToDraw_global, Vector3 positionAroundWhichToDraw_shiftedParallelToGrid_toDistanceDisplay, Vector3 forwardNormalized_ofRepresentedGridAxis, Vector3 vectorAlongGridLine_normalized, float distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder, Color colorOfGridLines, float durationInSec, bool hiddenByNearerObjects) + { + float lineWidth = 0.01f * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + DrawBasics.LineStyle style = DrawBasics.LineStyle.dashedLong; + float stylePatternScaleFactor = 1.8f * distanceBetweenVisualizedGridPointsInWorldUnits_forThisOrder; + Vector3 customAmplitudeAndTextDir = Vector3.Cross(forwardNormalized_ofRepresentedGridAxis, vectorAlongGridLine_normalized); + bool flattenThickRoundLineIntoAmplitudePlane = true; + bool skipPatternEnlargementForLongLines = true; + bool skipPatternEnlargementForShortLines = true; + DrawBasics.Line(positionAroundWhichToDraw_global, positionAroundWhichToDraw_shiftedParallelToGrid_toDistanceDisplay, colorOfGridLines, lineWidth, null, style, stylePatternScaleFactor, 0.0f, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + static Color GetFallbackColor(bool drawXDim, bool drawYDim, bool drawZDim, Color colorForMainX, Color colorForMainY, Color colorForMainZ) + { + Color fallbackColor = default; + if (drawZDim) + { + fallbackColor = colorForMainZ; + } + if (drawYDim) + { + fallbackColor = colorForMainY; + } + if (drawXDim) + { + fallbackColor = colorForMainX; + } + return fallbackColor; + } + + static void DrawSkewedPosIndicatingCubes(Vector3 positionAroundWhichToDraw, Color color, float extentOfOrder_inWorldUnits, bool drawXDim, bool drawYDim, bool drawZDim, float durationInSec, bool hiddenByNearerObjects) + { + float witdth_ofSquare = 0.015f * extentOfOrder_inWorldUnits; + float diagonal_ofSquare = witdth_ofSquare * UtilitiesDXXL_Math.sqrtOf2_precalced; + float half_diagonal_ofSquare = 0.5f * diagonal_ofSquare; + + if (drawXDim) + { + DrawShapes.FlatShape(positionAroundWhichToDraw, DrawShapes.Shape2DType.square, witdth_ofSquare, witdth_ofSquare, color, Quaternion.LookRotation(Vector3.right, new Vector3(0.0f, 1.0f, 1.0f)), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, DrawBasics.LineStyle.invisible, false, durationInSec, hiddenByNearerObjects); + Vector3 halfLength_ofLineAlong_xDim = Vector3.right * half_diagonal_ofSquare; + Line_fadeableAnimSpeed.InternalDraw(positionAroundWhichToDraw + halfLength_ofLineAlong_xDim, positionAroundWhichToDraw - halfLength_ofLineAlong_xDim, 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); + } + if (drawYDim) + { + DrawShapes.FlatShape(positionAroundWhichToDraw, DrawShapes.Shape2DType.square, witdth_ofSquare, witdth_ofSquare, color, Quaternion.LookRotation(Vector3.up, new Vector3(1.0f, 0.0f, 1.0f)), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, DrawBasics.LineStyle.invisible, false, durationInSec, hiddenByNearerObjects); + Vector3 halfLength_ofLineAlong_yDim = Vector3.up * half_diagonal_ofSquare; + Line_fadeableAnimSpeed.InternalDraw(positionAroundWhichToDraw + halfLength_ofLineAlong_yDim, positionAroundWhichToDraw - halfLength_ofLineAlong_yDim, 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); + } + if (drawZDim) + { + DrawShapes.FlatShape(positionAroundWhichToDraw, DrawShapes.Shape2DType.square, witdth_ofSquare, witdth_ofSquare, color, Quaternion.LookRotation(Vector3.forward, new Vector3(1.0f, 1.0f, 0.0f)), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, DrawBasics.LineStyle.invisible, false, durationInSec, hiddenByNearerObjects); + Vector3 halfLength_ofLineAlong_zDim = Vector3.forward * half_diagonal_ofSquare; + Line_fadeableAnimSpeed.InternalDraw(positionAroundWhichToDraw + halfLength_ofLineAlong_zDim, positionAroundWhichToDraw - halfLength_ofLineAlong_zDim, 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); + } + } + + static void DrawSkewedPosIndicatingCubes_local(Quaternion rotationOfLocalSpace, Vector3 positionAroundWhichToDraw_global, Color color, float extentOfOrder_inWorldUnits, bool drawXDim, bool drawYDim, bool drawZDim, float durationInSec, bool hiddenByNearerObjects) + { + float witdth_ofSquare = 0.015f * extentOfOrder_inWorldUnits; + float diagonal_ofSquare = witdth_ofSquare * UtilitiesDXXL_Math.sqrtOf2_precalced; + float half_diagonal_ofSquare = 0.5f * diagonal_ofSquare; + + if (drawXDim) + { + DrawShapes.FlatShape(positionAroundWhichToDraw_global, DrawShapes.Shape2DType.square, witdth_ofSquare, witdth_ofSquare, color, rotationOfLocalSpace * Quaternion.LookRotation(Vector3.right, new Vector3(0.0f, 1.0f, 1.0f)), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, DrawBasics.LineStyle.invisible, false, durationInSec, hiddenByNearerObjects); + Vector3 halfLength_ofLineAlong_xDim = rotationOfLocalSpace * (Vector3.right) * half_diagonal_ofSquare; + Line_fadeableAnimSpeed.InternalDraw(positionAroundWhichToDraw_global + halfLength_ofLineAlong_xDim, positionAroundWhichToDraw_global - halfLength_ofLineAlong_xDim, 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); + } + if (drawYDim) + { + DrawShapes.FlatShape(positionAroundWhichToDraw_global, DrawShapes.Shape2DType.square, witdth_ofSquare, witdth_ofSquare, color, rotationOfLocalSpace * Quaternion.LookRotation(Vector3.up, new Vector3(1.0f, 0.0f, 1.0f)), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, DrawBasics.LineStyle.invisible, false, durationInSec, hiddenByNearerObjects); + Vector3 halfLength_ofLineAlong_yDim = rotationOfLocalSpace * (Vector3.up) * half_diagonal_ofSquare; + Line_fadeableAnimSpeed.InternalDraw(positionAroundWhichToDraw_global + halfLength_ofLineAlong_yDim, positionAroundWhichToDraw_global - halfLength_ofLineAlong_yDim, 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); + } + if (drawZDim) + { + DrawShapes.FlatShape(positionAroundWhichToDraw_global, DrawShapes.Shape2DType.square, witdth_ofSquare, witdth_ofSquare, color, rotationOfLocalSpace * Quaternion.LookRotation(Vector3.forward, new Vector3(1.0f, 1.0f, 0.0f)), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, DrawBasics.LineStyle.invisible, false, durationInSec, hiddenByNearerObjects); + Vector3 halfLength_ofLineAlong_zDim = rotationOfLocalSpace * (Vector3.forward) * half_diagonal_ofSquare; + Line_fadeableAnimSpeed.InternalDraw(positionAroundWhichToDraw_global + halfLength_ofLineAlong_zDim, positionAroundWhichToDraw_global - halfLength_ofLineAlong_zDim, 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); + } + } + + static bool hide_positionAroundWhichToDraw_forGrids_before; + public static void Set_hide_positionAroundWhichToDraw_forGrids_reversible(bool new_hide_positionAroundWhichToDraw_forGrids) + { + hide_positionAroundWhichToDraw_forGrids_before = DrawEngineBasics.hide_positionAroundWhichToDraw_forGrids; + DrawEngineBasics.hide_positionAroundWhichToDraw_forGrids = new_hide_positionAroundWhichToDraw_forGrids; + } + public static void Reverse_hide_positionAroundWhichToDraw_forGrids() + { + DrawEngineBasics.hide_positionAroundWhichToDraw_forGrids = hide_positionAroundWhichToDraw_forGrids_before; + } + + static bool hide_distanceDisplay_forGrids_before; + public static void Set_hide_distanceDisplay_forGrids_reversible(bool new_hide_distanceDisplay_forGrids) + { + hide_distanceDisplay_forGrids_before = DrawEngineBasics.hide_distanceDisplay_forGrids; + DrawEngineBasics.hide_distanceDisplay_forGrids = new_hide_distanceDisplay_forGrids; + } + public static void Reverse_hide_distanceDisplay_forGrids() + { + DrawEngineBasics.hide_distanceDisplay_forGrids = hide_distanceDisplay_forGrids_before; + } + + static float offsetForDistanceDisplays_inGrids_before; + public static void Set_offsetForDistanceDisplays_inGrids_reversible(float new_offsetForDistanceDisplays_inGrids) + { + offsetForDistanceDisplays_inGrids_before = DrawEngineBasics.offsetForDistanceDisplays_inGrids; + DrawEngineBasics.offsetForDistanceDisplays_inGrids = new_offsetForDistanceDisplays_inGrids; + } + public static void Reverse_offsetForDistanceDisplays_inGrids() + { + DrawEngineBasics.offsetForDistanceDisplays_inGrids = offsetForDistanceDisplays_inGrids_before; + } + + static float offsetForCoordinateTextDisplays_inGrids_before; + public static void Set_offsetForCoordinateTextDisplays_inGrids_reversible(float new_offsetForCoordinateTextDisplays_inGrids) + { + offsetForCoordinateTextDisplays_inGrids_before = DrawEngineBasics.offsetForCoordinateTextDisplays_inGrids; + DrawEngineBasics.offsetForCoordinateTextDisplays_inGrids = new_offsetForCoordinateTextDisplays_inGrids; + } + public static void Reverse_offsetForCoordinateTextDisplays_inGrids() + { + DrawEngineBasics.offsetForCoordinateTextDisplays_inGrids = offsetForCoordinateTextDisplays_inGrids_before; + } + + static float coveredGridUnits_rel_forGridPlanes_before; + public static void Set_coveredGridUnits_rel_forGridPlanes_reversible(float new_coveredGridUnits_rel_forGridPlanes) + { + coveredGridUnits_rel_forGridPlanes_before = DrawEngineBasics.coveredGridUnits_rel_forGridPlanes; + DrawEngineBasics.coveredGridUnits_rel_forGridPlanes = new_coveredGridUnits_rel_forGridPlanes; + } + public static void Reverse_coveredGridUnits_rel_forGridPlanes() + { + DrawEngineBasics.coveredGridUnits_rel_forGridPlanes = coveredGridUnits_rel_forGridPlanes_before; + } + + static float sizeScalingForCoordinateTexts_inGrids_before; + public static void Set_sizeScalingForCoordinateTexts_inGrids_reversible(float new_sizeScalingForCoordinateTexts_inGrids) + { + sizeScalingForCoordinateTexts_inGrids_before = DrawEngineBasics.SizeScalingForCoordinateTexts_inGrids; + DrawEngineBasics.SizeScalingForCoordinateTexts_inGrids = new_sizeScalingForCoordinateTexts_inGrids; + } + public static void Reverse_sizeScalingForCoordinateTexts_inGrids() + { + DrawEngineBasics.SizeScalingForCoordinateTexts_inGrids = sizeScalingForCoordinateTexts_inGrids_before; + } + + static bool skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes_before; + public static void Set_skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes_reversible(bool new_skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes) + { + skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes_before = DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes; + DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes = new_skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes; + } + public static void Reverse_skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes() + { + DrawEngineBasics.skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes = skipXYZAxisIdentifier_inCoordinateTextsOnGridAxes_before; + } + + static bool skipLocalPrefix_inCoordinateTextsOnGridAxes_before; + public static void Set_skipLocalPrefix_inCoordinateTextsOnGridAxes_reversible(bool new_skipLocalPrefix_inCoordinateTextsOnGridAxes) + { + skipLocalPrefix_inCoordinateTextsOnGridAxes_before = DrawEngineBasics.skipLocalPrefix_inCoordinateTextsOnGridAxes; + DrawEngineBasics.skipLocalPrefix_inCoordinateTextsOnGridAxes = new_skipLocalPrefix_inCoordinateTextsOnGridAxes; + } + public static void Reverse_skipLocalPrefix_inCoordinateTextsOnGridAxes() + { + DrawEngineBasics.skipLocalPrefix_inCoordinateTextsOnGridAxes = skipLocalPrefix_inCoordinateTextsOnGridAxes_before; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Grid.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Grid.cs.meta new file mode 100644 index 0000000..8dd0455 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Grid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f41189a3ce1f15f479e10e0234899ed3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.cs new file mode 100644 index 0000000..0e0d8ba --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.cs @@ -0,0 +1,811 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_LineAmplitudeAndTextDirCalculation + { + public static float shortestLineWithDefinedAmplitudeDir = 0.0001f; //below that threshold float calculation imprecision may lead to undefined behaviour + public static float shortestLineWithDefinedAmplitudeDir_withTolerancePadding = 2.0f * shortestLineWithDefinedAmplitudeDir; + public static float absDotProductResult_ofTwoApproxNormalizedVectors_belowWhichVectorsAreConsideredPerp = 0.01f; // "0.01" is equivalent to around +/-0.6° angle deviation from 90° //This is mainly for preventing jitter in situations that are bistable due to float calculation imprecision + + static Vector3 amplitudeUp_normalized_forArrowsOfCurrArrowLine; //defined at start of arrows line + static Vector3 textDir_normalized_forArrowsOfCurrArrowLine = default(Vector3); //always disabled + public static bool theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine = false; + + + static InternalDXXL_Plane plane_perpToLine = new InternalDXXL_Plane(); + public static void Get_normalized_amplitudeAndTextDirVectors(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, Vector3 lineStartPos, Vector3 line_startToEnd, bool isThinLine, bool lineIsSoShortThatItDoesntHaveADefinedAmplitude, string text, bool textDrawingIsSkipped_dueToLineIsTooShort, DrawBasics.LineStyle style, bool flattenThickRoundLineIntoAmplitudePlane, bool uses_endPlates, InternalDXXL_Plane preferredAmplitudePlane, Vector3 customAmplitudeAndTextDir, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D) + { + //"preferredAmplitudePlane" doesn't have to contain the drawnLine (that means it can be parallel shifted to somewhere else), but it only indicates the orientation of amplitudeUp + + if (theCurrentlyDrawnLines_areAllFrom_vectorsThatBuildUpAnArrowsLine) + { + amplitudeUp_normalized = amplitudeUp_normalized_forArrowsOfCurrArrowLine; + textDir_normalized = textDir_normalized_forArrowsOfCurrArrowLine; + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + else + { + bool lineNeedsA_perpNormalizedVector_intoADefinedDirection; + bool lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection; + bool lineNeedsA_textDirection; + bool theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection; + CheckWhichDirectionsAreNeeded(out lineNeedsA_perpNormalizedVector_intoADefinedDirection, out lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection, out lineNeedsA_textDirection, out theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, lineIsSoShortThatItDoesntHaveADefinedAmplitude, isThinLine, style, text, flattenThickRoundLineIntoAmplitudePlane, uses_endPlates, textDrawingIsSkipped_dueToLineIsTooShort); + GetUpAndTextDir_accordingToSubCaseSpecification(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, preferredAmplitudePlane, customAmplitudeAndTextDir, lineNeedsA_perpNormalizedVector_intoADefinedDirection, lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection, lineNeedsA_textDirection, theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, lineIsSoShortThatItDoesntHaveADefinedAmplitude, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D); + if (style == DrawBasics.LineStyle.arrows) { amplitudeUp_normalized_forArrowsOfCurrArrowLine = amplitudeUp_normalized; } + } + } + + static void CheckWhichDirectionsAreNeeded(out bool lineNeedsA_perpNormalizedVector_intoADefinedDirection, out bool lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection, out bool lineNeedsA_textDirection, out bool theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, bool lineIsSoShortThatItDoesntHaveADefinedAmplitude, bool isThinLine, DrawBasics.LineStyle style, string text, bool flattenThickRoundLineIntoAmplitudePlane, bool uses_endPlates, bool textDrawingIsSkipped_dueToLineIsTooShort) + { + lineNeedsA_textDirection = false; + lineNeedsA_perpNormalizedVector_intoADefinedDirection = false; + lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection = false; + theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection = false; //<-not used in case of "GetUpAndTextDir_complyingWithCallerSpecifiedUpVector" + if (text != null && text != "" && (textDrawingIsSkipped_dueToLineIsTooShort == false)) + { + lineNeedsA_perpNormalizedVector_intoADefinedDirection = true; + lineNeedsA_textDirection = true; + if (lineIsSoShortThatItDoesntHaveADefinedAmplitude) + { + theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection = true; + } + } + else + { + //-> line doesn't have text: + if (UtilitiesDXXL_LineStyles.CheckIfLineStyleNeedsDefinedAmplitudeForSubLineCreation(style)) + { + lineNeedsA_perpNormalizedVector_intoADefinedDirection = true; + } + else + { + if (isThinLine) + { + //thin lines: + if (flattenThickRoundLineIntoAmplitudePlane && uses_endPlates) + { + //-> only endPlates use this: + lineNeedsA_perpNormalizedVector_intoADefinedDirection = true; + } + } + else + { + //thick lines: + if (flattenThickRoundLineIntoAmplitudePlane) + { + lineNeedsA_perpNormalizedVector_intoADefinedDirection = true; + } + else + { + lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection = true; + //-> used to get the cylindrical hull line anchors + } + } + } + } + } + + static void GetUpAndTextDir_accordingToSubCaseSpecification(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, Vector3 lineStartPos, Vector3 line_startToEnd, InternalDXXL_Plane preferredAmplitudePlane, Vector3 customAmplitudeAndTextDir, bool lineNeedsA_perpNormalizedVector_intoADefinedDirection, bool lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection, bool lineNeedsA_textDirection, bool theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, bool lineIsSoShortThatItDoesntHaveADefinedAmplitude, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D) + { + if (lineNeedsA_perpNormalizedVector_intoADefinedDirection) + { + Vector3 observerCamForward_normalized; + Vector3 observerCamUp_normalized; + Vector3 observerCamRight_normalized; + Vector3 cam_to_lineCenter; + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, lineStartPos, line_startToEnd, cameraFrom_DrawScreenspaceCall); + + if (preferredAmplitudePlane != null) + { + //"preferredAmplitudePlane" has been defined + //"preferredAmplitudePlane" is stronger than "customAmplitudeAndTextDir": + //->if a "preferredAmplitudePlane" is defined then "customAmplitudeAndTextDir" gets ignored. + GetUpAndTextDir_insideAmplitudePlane(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, preferredAmplitudePlane, lineNeedsA_textDirection, theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, cameraFrom_DrawScreenspaceCall, drawnLineIsFrom_DrawBasics2D, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + + //bool userHasSpecifiedAn_amplitudeUpVector = (UtilitiesDXXL_Math.IsDefaultVector(customAmplitudeAndTextDir) == false); + //if (userHasSpecifiedAn_amplitudeUpVector) + //{ + // //-> user has specified an amplitudePlane AND an amplitudeUpVector + // //-> this case is not expected here, but a partial implementation (that at least handles the "*_independentFromTooShortLineDir_*"-cases) already exists in "UtilitiesDXXL_TextDirAndUpCalculation.GetTextDirAndUpNormalized_whileUserHas_notSpecifiedDir_but_specifiedUp" + //} + } + else + { + //-> no amplitudePlane is specified + bool userHasSpecifiedAn_amplitudeUpVector = (UtilitiesDXXL_Math.IsDefaultVector(customAmplitudeAndTextDir) == false); + if (userHasSpecifiedAn_amplitudeUpVector) + { + GetUpAndTextDir_complyingWithCallerSpecifiedUpVector(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineIsSoShortThatItDoesntHaveADefinedAmplitude, lineStartPos, line_startToEnd, customAmplitudeAndTextDir, lineNeedsA_textDirection, theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + else + { + //-> no "amplitudePlane" and no "customAmplitudeAndTextDir-vector" dictate the amplitude direction. + //-> drawnLine.up and textDir can be freely chosen on the base of the "DrawBasics.cameraForAutomaticOrientation"-viewDirection (as long as they are aligned to the drawnLine) + GetUpAndTextDir_withoutCallerSpecifiedPreference_accordingToAutomaticAmplitudeAndTextAlignmentSettings(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, lineNeedsA_textDirection, theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + } + } + else + { + //-> line doesn't need a perpNormalizedVector_intoADefinedDirection + //-> line doesn't need a textDir + textDir_normalized = default(Vector3); + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + GetArbitraryUpDir(out amplitudeUp_normalized, line_startToEnd, lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection); + } + } + + static void GetUpAndTextDir_insideAmplitudePlane(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, Vector3 lineStartPos, Vector3 line_startToEnd, InternalDXXL_Plane preferredAmplitudePlane, bool lineNeedsA_textDirection, bool theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, Camera cameraFrom_DrawScreenspaceCall, bool drawnLineIsFrom_DrawBasics2D, Vector3 observerCamForward_normalized, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter) + { + if (theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection) + { + //-> line is too short to have any direction preferences: That means that any directions can be chosen, as long as they lie inside the plane. + //-> "DrawBasics.automaticTextDirectionOfLines == towardsLineEnd" has no effect, since there is no lineDirection that could be used -> The only remaining option here is "DrawBasics.automaticTextDirectionOfLines == leftToRightInScreen" + + if (cameraFrom_DrawScreenspaceCall != null) + { + //-> The call came from "DrawScreenspace.*()" + amplitudeUp_normalized = observerCamUp_normalized; + textDir_normalized = observerCamRight_normalized; + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + else + { + if (drawnLineIsFrom_DrawBasics2D) + { + //-> The call came from "DrawBasics2D.*()" + amplitudeUp_normalized = Vector3.up; + textDir_normalized = Vector3.right; + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + else + { + if (DrawBasics.automaticAmplitudeAndTextAlignment == DrawBasics.AutomaticAmplitudeAndTextAlignment.vertical) + { + GetUpAndTextDir_insideAmplitudePlane_independentFromTooShortLineDir_alignedToVertical(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, preferredAmplitudePlane, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + else + { + GetUpAndTextDir_insideAmplitudePlane_independentFromTooShortLineDir_alignedToObserverCam(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, preferredAmplitudePlane, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + } + } + } + else + { + //-> drawnLine is guaranteed longer than zero/longer than minLengthThreshold here + //-> textDir may or may not be required + GetUpAndTextDir_insideAmplitudePlane_forNonShortLine(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, preferredAmplitudePlane, lineNeedsA_textDirection, theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, cameraFrom_DrawScreenspaceCall, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter, false); + } + } + + static void GetUpAndTextDir_insideAmplitudePlane_independentFromTooShortLineDir_alignedToVertical(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, InternalDXXL_Plane preferredAmplitudePlane, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter) + { + bool thePlaneIsHorizontal = InternalDXXL_Plane.IsHorizontal(preferredAmplitudePlane); + if (thePlaneIsHorizontal) + { + bool viewDirCamToLine_isHorizontal = UtilitiesDXXL_Math.ApproximatelyZero(cam_to_lineCenter.y); + if (viewDirCamToLine_isHorizontal) + { + //-> the camera is looking "inside/along" the (horiz)plane, so it cannot see any vector inside the plane + //-> up and textDir can be freely chosen, as long as they lie in the plane + GetUpAndTextDir_insideHorizPlane_independentFromTooShortLineDir_independentFromObserverCamDir(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled); + } + else + { + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(cam_to_lineCenter) < 0.001f) + { + GetUpAndTextDir_insideHorizPlane_independentFromTooShortLineDir_independentFromObserverCamDir(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled); + } + else + { + Vector3 observerCamUp_projectedAlongViewDir_ontoAmplitudePlane_notNormalized = preferredAmplitudePlane.Get_projectionOfVectorOntoPlane_alongCustomDir(observerCamUp_normalized, cam_to_lineCenter); + Vector3 observerCamUp_projectedAlongViewDir_ontoAmplitudePlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(observerCamUp_projectedAlongViewDir_ontoAmplitudePlane_notNormalized); + + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(observerCamUp_projectedAlongViewDir_ontoAmplitudePlane_normalized)) + { + UtilitiesDXXL_Log.PrintErrorCode("16-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(observerCamUp_normalized) + "-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(cam_to_lineCenter) + "-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(preferredAmplitudePlane.normalDir)); + GetUpAndTextDir_insideHorizPlane_independentFromTooShortLineDir_independentFromObserverCamDir(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled); + } + else + { + //->"amplitudeUp_normalized" is flat inside horizPlane -> it's y is zero + Vector3 aNormalizedVector_definingTheTextAlignment = new Vector3(observerCamUp_projectedAlongViewDir_ontoAmplitudePlane_normalized.z, 0.0f, -observerCamUp_projectedAlongViewDir_ontoAmplitudePlane_normalized.x); //-> turns "amplitudeUp_normalized" by 90deg around the y-axis + + //line is so short that alignment "automaticTextDirectionOfLines == towardsLineEnd" is not possible, therefore using "FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen" instead of "FlipNormalizedUpAndTextDir_toFit_automaticTextDirection" + FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen_viaUpDirDictatesVertInsideScreenApproximation(out amplitudeUp_normalized, out textDir_normalized, observerCamUp_projectedAlongViewDir_ontoAmplitudePlane_normalized, aNormalizedVector_definingTheTextAlignment, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + } + } + } + else + { + GetUpAndTextDir_insideNonHorizontalAmplitudePlane_viaProjectionOfVerticalGlobalUpOntoPlane(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, preferredAmplitudePlane, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + } + + static void GetUpAndTextDir_insideAmplitudePlane_independentFromTooShortLineDir_alignedToObserverCam(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, InternalDXXL_Plane preferredAmplitudePlane, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter) + { + //-> "cam_to_lineCenter" is allowed to be zero here. It will lead to "camViewDir_isApproxInsideAmplitudePlane" and is then not further used. + float absDotProductResult_of_camToLine_and_amplitudePlaneNormal = Mathf.Abs(Vector3.Dot(cam_to_lineCenter, preferredAmplitudePlane.normalDir)); + bool camViewDir_isApproxInsideAmplitudePlane = (absDotProductResult_of_camToLine_and_amplitudePlaneNormal < absDotProductResult_ofTwoApproxNormalizedVectors_belowWhichVectorsAreConsideredPerp); + if (camViewDir_isApproxInsideAmplitudePlane) + { + //-> the camera is looking "inside/along" the plane, so it cannot see any vector inside the plane + //-> up and textDir can be freely chosen, as long as they lie in the plane + //-> it doesn't matter which vectors inside the plane are used because the camera cannot see any of them + //-> fallback to "automaticAmplitudeAndTextAlignment == vertical" + + bool thePlaneIsHorizontal = InternalDXXL_Plane.IsHorizontal(preferredAmplitudePlane); + if (thePlaneIsHorizontal) + { + GetUpAndTextDir_insideHorizPlane_independentFromTooShortLineDir_independentFromObserverCamDir(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled); + } + else + { + //fallback to alignVertical: + GetUpAndTextDir_insideNonHorizontalAmplitudePlane_viaProjectionOfVerticalGlobalUpOntoPlane(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, preferredAmplitudePlane, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + } + else + { + //-> camToLineCenter is NOT inside the amplitudePlane + //-> no bistable "projection is maybe zero" is expected here, because the "camViewDir_isApproxInsideAmplitudePlane"-calulation dotProduct has an anglePadding. + + //->"cam_to_lineCenter" is safely longer than 0 here and can therefore be used as projectionDir without problems + Vector3 camUp_projectedAlongCamToLineCenter_ontoAmplitudePlane_notNormalized = preferredAmplitudePlane.Get_projectionOfVectorOntoPlane_alongCustomDir(observerCamUp_normalized, cam_to_lineCenter); + Vector3 aNormalizedVector_definingTheUpAlignment = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(camUp_projectedAlongCamToLineCenter_ontoAmplitudePlane_notNormalized); + + Vector3 aVector_definingTheTextAlignment = Vector3.Cross(aNormalizedVector_definingTheUpAlignment, preferredAmplitudePlane.normalDir); + Vector3 aNormalizedVector_definingTheTextAlignment = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(aVector_definingTheTextAlignment); + + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(aNormalizedVector_definingTheTextAlignment)) //<- this implicitly also checks if "aNormalizedVector_definingTheUpAlignment" has been successfully normalized + { + UtilitiesDXXL_Log.PrintErrorCode("18-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(preferredAmplitudePlane.normalDir) + "-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(observerCamUp_normalized) + "-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(cam_to_lineCenter)); + GetUpAndTextDir_insideAmplitudePlane_independentFromTooShortLineDir_independentFromObserverCamDir(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, preferredAmplitudePlane); + } + else + { + //line is so short that alignment "automaticTextDirectionOfLines == towardsLineEnd" is not possible, therefore using "FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen" instead of "FlipNormalizedUpAndTextDir_toFit_automaticTextDirection" + FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen_viaUpDirDictatesVertInsideScreenApproximation(out amplitudeUp_normalized, out textDir_normalized, aNormalizedVector_definingTheUpAlignment, aNormalizedVector_definingTheTextAlignment, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + } + } + + static void GetUpAndTextDir_insideHorizPlane_independentFromTooShortLineDir_independentFromObserverCamDir(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled) + { + amplitudeUp_normalized = Vector3.forward; + textDir_normalized = Vector3.right; + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + + static void GetUpAndTextDir_insideAmplitudePlane_independentFromTooShortLineDir_independentFromObserverCamDir(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, InternalDXXL_Plane preferredAmplitudePlane) + { + Vector3 arbitraryVector_insideThePlane_notNormalized = preferredAmplitudePlane.Get_projectionOfVectorOntoPlane(UtilitiesDXXL_Math.arbitrarySeldomDir_normalized_precalced); + amplitudeUp_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(arbitraryVector_insideThePlane_notNormalized); + textDir_normalized = Vector3.Cross(amplitudeUp_normalized, preferredAmplitudePlane.normalDir).normalized; + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + + static InternalDXXL_Line intersectionLine_ofTwoPlanes = new InternalDXXL_Line(); + static void GetUpAndTextDir_insideNonHorizontalAmplitudePlane_viaProjectionOfVerticalGlobalUpOntoPlane(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, InternalDXXL_Plane preferredAmplitudePlane, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter) + { + //-> this function is only called from places that need textDir + + Vector3 projection_ofGlobalUpVector_perpOntoAmplitudePlane_notNormalized = preferredAmplitudePlane.Get_projectionOfVectorOntoPlane(Vector3.up); + Vector3 aNormalizedVector_definingTheUpAlignment = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(projection_ofGlobalUpVector_perpOntoAmplitudePlane_notNormalized); + + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(aNormalizedVector_definingTheUpAlignment)) + { + UtilitiesDXXL_Log.PrintErrorCode("17-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(preferredAmplitudePlane.normalDir)); + GetUpAndTextDir_insideHorizPlane_independentFromTooShortLineDir_independentFromObserverCamDir(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled); + } + else + { + InternalDXXL_Plane.Calc_intersectionLine_ofTwoPlanes(ref intersectionLine_ofTwoPlanes, preferredAmplitudePlane, InternalDXXL_Plane.horizPlane_throughZeroOrigin); + + //-> this function is only called from places where the line is so short that alignment "automaticTextDirectionOfLines == towardsLineEnd" is not possible, therefore using "FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen" instead of "FlipNormalizedUpAndTextDir_toFit_automaticTextDirection" + FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen_viaUpDirDictatesVertInsideScreenApproximation(out amplitudeUp_normalized, out textDir_normalized, aNormalizedVector_definingTheUpAlignment, intersectionLine_ofTwoPlanes.direction_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + } + + public static void GetUpAndTextDir_insideAmplitudePlane_forNonShortLine(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, Vector3 lineStartPos, Vector3 line_startToEnd, InternalDXXL_Plane preferredAmplitudePlane, bool lineNeedsA_textDirection, bool theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, Camera cameraFrom_DrawScreenspaceCall, Vector3 observerCamForward_normalized, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter, bool isFallbackFrom_GetUpAndTextDir_withoutCallerSpecifiedPreference) + { + Vector3 aLine_perpToDrawnLine_insideAmplitudePlane_notNormalized = Vector3.Cross(line_startToEnd, preferredAmplitudePlane.normalDir); + Vector3 aLine_perpToDrawnLine_insideAmplitudePlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(aLine_perpToDrawnLine_insideAmplitudePlane_notNormalized); + + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(aLine_perpToDrawnLine_insideAmplitudePlane_normalized)) + { + //-> cross product result could not be normalized + //-> the line is perp to plane + //-> the condition that the upVector should lie in the specified plane is already met. + //-> EVERY perpToLine-vector lies inside the specified plane + //-> any fallback upVector can be chosen, as long as it lies inside the plane. + //-> textDir vector: impossible to put into plane, since it should be perp to plane + + if (isFallbackFrom_GetUpAndTextDir_withoutCallerSpecifiedPreference) + { + //the fallback came with a vert line and the xy-plane: How can this be perpToEachOther? + //UtilitiesDXXL_Log.PrintErrorCode("21-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(lineStartPos) + "-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(line_startToEnd) + "-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(preferredAmplitudePlane.normalDir)); + //<- "UtilitiesDXXL_LineCircled.LineCircledBelow180Deg(turnAngleDeg=approxZero)" once triggered this before widening the span that counts as zero. + //<- also after that "UtilitiesDXXL_LineCircled.LineCircledBelow180Deg(turnAngleDeg=approxZero)" triggered it by supplying "line_startToEnd = 0,0,0". Therefore decision: Omit error code and accept using the fallback sometimes. + + //this fallback doesn't align to observerCam and can appear mirrorInverted: + amplitudeUp_normalized = Vector3.left; + textDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(line_startToEnd); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(textDir_normalized)) + { + textDir_normalized = Vector3.up; + } + + if (textDir_normalized.y < 0.0f) { textDir_normalized = (-textDir_normalized); } + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + else + { + GetUpAndTextDir_withoutCallerSpecifiedPreference_accordingToAutomaticAmplitudeAndTextAlignmentSettings(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, lineNeedsA_textDirection, theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + //<- this fallback will meet the required criteria: + //-> amplitudeUp will be inside the "preferredAmplitudePlane", since perpToLine-vector does + //-> textDir will be along the line. Since it is impossible to put it into the plane the fallback at least makes sure that it is nonMirrored readable in the observerCam + } + } + else + { + //line is not short and not perp to plane: + if (lineNeedsA_textDirection) + { + lengthOfDrawnLine_isFilled = true; + Vector3 lineDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(line_startToEnd, out lengthOfDrawnLine); + FlipNormalizedUpAndTextDir_toFit_automaticTextDirection(out amplitudeUp_normalized, out textDir_normalized, aLine_perpToDrawnLine_insideAmplitudePlane_normalized, lineDir_normalized, false, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + else + { + amplitudeUp_normalized = aLine_perpToDrawnLine_insideAmplitudePlane_normalized; + textDir_normalized = default(Vector3); + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + } + } + + static void GetUpAndTextDir_withoutCallerSpecifiedPreference_accordingToAutomaticAmplitudeAndTextAlignmentSettings(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, Vector3 lineStartPos, Vector3 line_startToEnd, bool lineNeedsA_textDirection, bool theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, Vector3 observerCamForward_normalized, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter) + { + if (theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection) + { + //-> only autoEnlargedText may use this: + //-> even less restrictions for choosing the up/textDir: Because here the directions don't even have to be aligned along the drawnLine (-> now "DrawBasics.cameraForAutomaticOrientation" can really choose freely) + + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + + if (DrawBasics.automaticAmplitudeAndTextAlignment == DrawBasics.AutomaticAmplitudeAndTextAlignment.vertical) + { + GetUpAndTextDir_withoutCallerSpecifiedPreference_independentFromTooShortLineDir_alignedVertical(out amplitudeUp_normalized, out textDir_normalized, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + else + { + //align to camera: + amplitudeUp_normalized = observerCamUp_normalized; + textDir_normalized = observerCamRight_normalized; + } + } + else + { + //-> drawnLine is guaranteed longer than zero/longer than minLengthThreshold here + //-> textDir may or may not be required + if (DrawBasics.automaticAmplitudeAndTextAlignment == DrawBasics.AutomaticAmplitudeAndTextAlignment.vertical) + { + GetUpAndTextDir_withoutCallerSpecifiedPreference_forNonShortLine_alignedVertical(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, lineNeedsA_textDirection, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + else + { + GetUpAndTextDir_withoutCallerSpecifiedPreference_forNonShortLine_alignedToObserverCam(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, lineNeedsA_textDirection, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + } + } + + public static void GetUpAndTextDir_withoutCallerSpecifiedPreference_independentFromTooShortLineDir_alignedVertical(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, Vector3 observerCamForward_normalized, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter) + { + //align vertical in global space: + amplitudeUp_normalized = Vector3.up; + + //-> textDir: has to lie inside horizPlane + //-> textDir.y is always 0 + + if (Mathf.Abs(observerCamRight_normalized.y) < 0.0001f) + { + //most common case: + //-> observerCam is not tilted sidewards + textDir_normalized = observerCamRight_normalized; + } + else + { + //-> observerCam is tilted sidewards + Vector3 camRight_projectedInto_horizPlane_notNormalized = InternalDXXL_Plane.horizPlane_throughZeroOrigin.Get_projectionOfVectorOntoPlane(observerCamRight_normalized); + Vector3 camRight_projectedInto_horizPlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(camRight_projectedInto_horizPlane_notNormalized); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(camRight_projectedInto_horizPlane_normalized)) + { + //very rare case + //-> the observerCam is tilted to the side by 90 degree (and has no other tilts that prevents it from looking inside the horizPlane(=no y-rotation)) + //-> known issue: This projection to "camRight_projectedInto_horizPlane_notNormalized" may not be reproducably zero, due to float calculation imprecsion. This leads to this thread not beeing reached. + Quaternion rotation_fromDrawnLineUp_to_textDir = Quaternion.AngleAxis(-90.0f, observerCamForward_normalized); + textDir_normalized = rotation_fromDrawnLineUp_to_textDir * amplitudeUp_normalized; + } + else + { + //line is too short to have a direction, so "FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen" can be called instead of "FlipNormalizedUpAndTextDir_toFit_automaticTextDirection": + FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen_viaUpDirDictatesVertInsideScreenApproximation(out amplitudeUp_normalized, out textDir_normalized, amplitudeUp_normalized, camRight_projectedInto_horizPlane_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + } + } + + static void GetUpAndTextDir_withoutCallerSpecifiedPreference_forNonShortLine_alignedVertical(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, Vector3 lineStartPos, Vector3 line_startToEnd, bool lineNeedsA_textDirection, Vector3 observerCamForward_normalized, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter) + { + Vector3 line_startToEnd_approxNormalized = UtilitiesDXXL_Math.GetApproxNormalized_afterScalingIntoRegionOfFloatPrecicion(line_startToEnd); + float absDotProductResult_of_lineDir_and_globalRight = Mathf.Abs(Vector3.Dot(line_startToEnd_approxNormalized, Vector3.right)); + float absDotProductResult_of_lineDir_and_globalForward = Mathf.Abs(Vector3.Dot(line_startToEnd_approxNormalized, Vector3.forward)); + bool lineItselfIsVerticalInGlobalSpace = ((absDotProductResult_of_lineDir_and_globalRight < absDotProductResult_ofTwoApproxNormalizedVectors_belowWhichVectorsAreConsideredPerp) && (absDotProductResult_of_lineDir_and_globalForward < absDotProductResult_ofTwoApproxNormalizedVectors_belowWhichVectorsAreConsideredPerp)); + //<- The dot product returns a stable result, because both initialVectors are already approx normalized. + //<- If there is still an edge case that produces falsePositive-parallelDetection, then it is no big problem, because the worst thing that can happen, is that the text gets aligned to xy-plane instead + + if (lineItselfIsVerticalInGlobalSpace) + { + //-> fallback to alignToCamera: + //GetUpAndTextDir_withoutCallerSpecifiedPreference_forNonShortLine_alignedToObserverCam(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, lineNeedsA_textDirection, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + + //-> fallback to inside-xyPlane: + InternalDXXL_Plane preferredAmplitudePlane = UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero; + GetUpAndTextDir_insideAmplitudePlane_forNonShortLine(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, preferredAmplitudePlane, lineNeedsA_textDirection, false, null, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter, true); + } + else + { + plane_perpToLine.Recreate(lineStartPos, line_startToEnd); + Vector3 amplitudeUp_notNormalized = plane_perpToLine.Get_projectionOfVectorOntoPlane(Vector3.up); + amplitudeUp_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(amplitudeUp_notNormalized); + + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(amplitudeUp_normalized)) + { + UtilitiesDXXL_Log.PrintErrorCode("14-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(line_startToEnd)); + } + + if (lineNeedsA_textDirection) + { + lengthOfDrawnLine_isFilled = true; + Vector3 lineDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(line_startToEnd, out lengthOfDrawnLine); + if (DrawBasics.automaticTextDirectionOfLines == DrawBasics.AutomaticTextDirectionOfLines.towardsLineEnd) + { + textDir_normalized = lineDir_normalized; + Vector3 aVector_perpToDrawnLine_intoTheDirectionOf_amplitudeUpIfTextShouldBeReadable_notNormalized = Vector3.Cross(cam_to_lineCenter, textDir_normalized); + //"aVector_perpToDrawnLine_intoTheDirectionOf_amplitudeUpIfTextShouldBeReadable_notNormalized" can become zero, but it is not a big problem, because this means that the drawnLine is parallel to camViewDir, so the text will anyway not be readable and can therefore go into the wrong opposite direction. + if (UtilitiesDXXL_Math.Check_ifVectorsPointAwayFromEachOther_perpCountsAsPointingAwayFromEachOther(amplitudeUp_normalized, aVector_perpToDrawnLine_intoTheDirectionOf_amplitudeUpIfTextShouldBeReadable_notNormalized)) + { + amplitudeUp_normalized = (-amplitudeUp_normalized); + } + } + else + { + //Text dir: leftToRightInScreen + //-> amplitudeUp(plane) is aligned to the "vertical"-setting, but the upDir and textDir now gets flipped to comply with "leftToRightInScreen" + FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen_viaUpDirDictatesVertInsideScreenApproximation(out amplitudeUp_normalized, out textDir_normalized, amplitudeUp_normalized, lineDir_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + } + else + { + textDir_normalized = default(Vector3); + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + } + } + + static void GetUpAndTextDir_withoutCallerSpecifiedPreference_forNonShortLine_alignedToObserverCam(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, Vector3 lineStartPos, Vector3 line_startToEnd, bool lineNeedsA_textDirection, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter) + { + //-> drawnLine is guaranteed longer than zero/longer than minLengthThreshold here + + Vector3 aVector_perpToCamViewDir_perpToLine_toTheSideWhereUpShouldPointForNonMirroredCamReadabilityInCaseTextTowardsLineEnd_notNormalized = Vector3.Cross(cam_to_lineCenter, line_startToEnd); + Vector3 aVector_perpToCamViewDir_perpToLine_toTheSideWhereUpShouldPointForNonMirroredCamReadabilityInCaseTextTowardsLineEnd_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(aVector_perpToCamViewDir_perpToLine_toTheSideWhereUpShouldPointForNonMirroredCamReadabilityInCaseTextTowardsLineEnd_notNormalized); + + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(aVector_perpToCamViewDir_perpToLine_toTheSideWhereUpShouldPointForNonMirroredCamReadabilityInCaseTextTowardsLineEnd_normalized)) + { + //-> The drawnLine is approx parallel to cameras view direction: + plane_perpToLine.Recreate(lineStartPos, line_startToEnd); + Vector3 amplitudeUp_notNormalized = plane_perpToLine.Get_projectionOfVectorOntoPlane(observerCamUp_normalized); //-> Also for perspective cams with their warped viewField: A "cam.transform.up"-vector always appears as vertical inside screen, independent where in the scene it is placed or if it appears in the warped carner of the perspective screen. + amplitudeUp_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(amplitudeUp_notNormalized); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(amplitudeUp_normalized)) + { + UtilitiesDXXL_Log.PrintErrorCode("15-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(line_startToEnd) + "-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(observerCamUp_normalized)); + } + + if (lineNeedsA_textDirection) + { + //-> no flipping of the direction because the text is anyway not readable in the screen (since the line is parallel to camViewDir) + lengthOfDrawnLine_isFilled = true; + textDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(line_startToEnd, out lengthOfDrawnLine); + } + else + { + textDir_normalized = default(Vector3); + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + } + else + { + //-> Note for perspective cameras: "aVector_perpToCamViewDir_perpToLine_toTheSideWhereUpShouldPointForNonMirroredCamReadabilityInCaseTextTowardsLineEnd_normalized" is not "perp to the screenPlane", but it is "perp to the view dir". + if (lineNeedsA_textDirection) + { + lengthOfDrawnLine_isFilled = true; + Vector3 lineDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(line_startToEnd, out lengthOfDrawnLine); + FlipNormalizedUpAndTextDir_toFit_automaticTextDirection(out amplitudeUp_normalized, out textDir_normalized, aVector_perpToCamViewDir_perpToLine_toTheSideWhereUpShouldPointForNonMirroredCamReadabilityInCaseTextTowardsLineEnd_normalized, lineDir_normalized, true, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + else + { + amplitudeUp_normalized = aVector_perpToCamViewDir_perpToLine_toTheSideWhereUpShouldPointForNonMirroredCamReadabilityInCaseTextTowardsLineEnd_normalized; + textDir_normalized = default(Vector3); + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + } + } + + static void GetUpAndTextDir_complyingWithCallerSpecifiedUpVector(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, bool lineIsSoShortThatItDoesntHaveADefinedAmplitude, Vector3 lineStartPos, Vector3 line_startToEnd, Vector3 customAmplitudeAndTextDir, bool lineNeedsA_textDirection, bool theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, Vector3 observerCamForward_normalized, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter) + { + //-> The user has specifed a custom amplitude dir via vector parameter + //-> The user-specifed "customAmplitudeAndTextDir"-Vector dictates the drawnLine.up-direction + //-> The user-specifed "customAmplitudeAndTextDir"-Vector is not guaranteed to be normalized + //-> "theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection" does not apply here + + if (lineIsSoShortThatItDoesntHaveADefinedAmplitude) + { + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + GetUpAndTextDir_complyingWithCallerSpecifiedUpVector_independentFromTooShortLineDir(out amplitudeUp_normalized, out textDir_normalized, customAmplitudeAndTextDir, lineNeedsA_textDirection, cam_to_lineCenter); + } + else + { + GetUpAndTextDir_complyingWithCallerSpecifiedUpVector_forNonShortLine(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, customAmplitudeAndTextDir, lineNeedsA_textDirection, theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + } + + static void GetUpAndTextDir_complyingWithCallerSpecifiedUpVector_independentFromTooShortLineDir(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, Vector3 customAmplitudeAndTextDir, bool lineNeedsA_textDirection, Vector3 cam_to_lineCenter) + { + amplitudeUp_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(customAmplitudeAndTextDir); + if (lineNeedsA_textDirection) + { + //-> only enlarged text may use this... + //-> textDir doesn't have any requirements except for beeing perp to "amplitudeUp" + + Vector3 textDir_ifTextShouldBeNonMirroredReadableInCamScreen_notNormalized = Vector3.Cross(amplitudeUp_normalized, cam_to_lineCenter); + Vector3 textDir_ifTextShouldBeNonMirroredReadableInCamScreen_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(textDir_ifTextShouldBeNonMirroredReadableInCamScreen_notNormalized); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(textDir_ifTextShouldBeNonMirroredReadableInCamScreen_normalized)) + { + //-> amplitudeUp is parallel to cam view dir + //-> text anyway not seen in camera + textDir_normalized = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(amplitudeUp_normalized); + } + else + { + textDir_normalized = textDir_ifTextShouldBeNonMirroredReadableInCamScreen_normalized; + } + } + else + { + textDir_normalized = default(Vector3); + } + } + + static void GetUpAndTextDir_complyingWithCallerSpecifiedUpVector_forNonShortLine(out Vector3 amplitudeUp_normalized, out Vector3 textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, Vector3 lineStartPos, Vector3 line_startToEnd, Vector3 customAmplitudeAndTextDir, bool lineNeedsA_textDirection, bool theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, Vector3 observerCamForward_normalized, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter) + { + //-> drawnLine is guaranteed longer than zero/longer than minLengthThreshold here + plane_perpToLine.Recreate(lineStartPos, line_startToEnd); + Vector3 projection_ofCustomUpVector_alongLineDir_onto_perpToLinePlane_notNormalized = plane_perpToLine.Get_projectionOfVectorOntoPlane(customAmplitudeAndTextDir); + Vector3 projection_ofCustomUpVector_alongLineDir_onto_perpToLinePlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(projection_ofCustomUpVector_alongLineDir_onto_perpToLinePlane_notNormalized); + if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(projection_ofCustomUpVector_alongLineDir_onto_perpToLinePlane_normalized)) + { + //user-specified upVector is approx parallel to line: + GetUpAndTextDir_withoutCallerSpecifiedPreference_accordingToAutomaticAmplitudeAndTextAlignmentSettings(out amplitudeUp_normalized, out textDir_normalized, out lengthOfDrawnLine, out lengthOfDrawnLine_isFilled, lineStartPos, line_startToEnd, lineNeedsA_textDirection, theOnlyThingThatTheLineNeeds_is_upAndTextDirForAnEnlargedText_andThoseDirsAreNotAlignedAlongTheLineBecauseTheLineIsTooShortToHaveADefinedDirection, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter); + } + else + { + //user-specified upVector is not parallel to line: + amplitudeUp_normalized = projection_ofCustomUpVector_alongLineDir_onto_perpToLinePlane_normalized; + //<- does not get flipInverted_toFit_automaticTextDirection, also if it leads to upSideDown-texts, because user has specified the direction + + if (lineNeedsA_textDirection) + { + lengthOfDrawnLine_isFilled = true; + Vector3 lineDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(line_startToEnd, out lengthOfDrawnLine); + FlipNormalizedTextDir_toBeNonMirroredReadable_forFixedAmplitudeUpDir(out textDir_normalized, lineDir_normalized, amplitudeUp_normalized, cam_to_lineCenter); + } + else + { + textDir_normalized = default(Vector3); + lengthOfDrawnLine_isFilled = false; + lengthOfDrawnLine = 0.0f; + } + } + } + + static void GetArbitraryUpDir(out Vector3 amplitudeUp_normalized, Vector3 line_startToEnd, bool lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection) + { + if (lineNeedsA_perpNormalizedVector_intoAnArbitraryDirection) + { + //-> line is thick and needs the arbitraryUpVector for obtaining the non-flattened thickening hullLines + //-> In other words: used for thick-nonFlat-Lines to get the cylindrical hull line anchors + //-> drawnLine is guaranteed longer than zero/longer than minLengthThreshold here + amplitudeUp_normalized = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(line_startToEnd); + } + else + { + amplitudeUp_normalized = default(Vector3); + } + } + + static void FlipNormalizedUpAndTextDir_toFit_automaticTextDirection(out Vector3 amplitudeUp_normalized_postFlip, out Vector3 textDir_normalized_postFlip, Vector3 amplitudeUp_normalized_preFlip, Vector3 textDir_normalized_preFlip, bool amplitudeUp_preFlip_pointsAlreadyToTheSideWhereTextIsUnmirroredReadableInCaseTextTowardsLineEnd, Vector3 cameraUp_normalized, Vector3 cameraRight_normalized, Vector3 cam_to_lineCenter) + { + if (DrawBasics.automaticTextDirectionOfLines == DrawBasics.AutomaticTextDirectionOfLines.towardsLineEnd) + { + //-> The case "line is vert inside screen" has no special treatment here, because the problem of bistable jittering text direction doesn't exist for "textDirection == towardsLineEnd", because in this case the text direction doesn't flip when passing the verticalDirection. + textDir_normalized_postFlip = textDir_normalized_preFlip; //-> lineDir is used without any flipInverting + if (amplitudeUp_preFlip_pointsAlreadyToTheSideWhereTextIsUnmirroredReadableInCaseTextTowardsLineEnd) + { + amplitudeUp_normalized_postFlip = amplitudeUp_normalized_preFlip; + } + else + { + FlipNormalizedUp_toBeNonMirroredReadable_withA_fixedTextDir(out amplitudeUp_normalized_postFlip, amplitudeUp_normalized_preFlip, textDir_normalized_postFlip, cam_to_lineCenter); + } + } + else + { + //textDir fromLeftToRight_inScreen: + FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen_viaUpDirDictatesVertInsideScreenApproximation(out amplitudeUp_normalized_postFlip, out textDir_normalized_postFlip, amplitudeUp_normalized_preFlip, textDir_normalized_preFlip, cameraUp_normalized, cameraRight_normalized, cam_to_lineCenter); + } + } + + static void FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen_viaTextDirDictatesVertInsideScreenApproximation(out Vector3 amplitudeUp_normalized_postFlip, out Vector3 textDir_normalized_postFlip, Vector3 amplitudeUp_normalized_preFlip, Vector3 textDir_normalized_preFlip, Vector3 cameraUp_normalized, Vector3 cameraRight_normalized, Vector3 cam_to_lineCenter) + { + //This "_viaTextDirDictates"-variant has: + //-> Advantage compared to "_viaUpDirDictates"-variant: lines that are verticalInGlobalSpace are better detected as "drawnLine_isApproxVertical_insideScreen" + //-> Disadvantage compared to "_viaUpDirDictates"-variant: The resulting texts may be upSideDown(though at least non-mirrored) even for lines that are quite horizontalInScreenSpace + + //-> camRight always appears as horizLineInScreen, no matter where in the scene it is placed or in which corner of a warping perspective camera it appears + float dotProductResult_of_textDirPreFlip_and_camRight = Vector3.Dot(textDir_normalized_preFlip, cameraRight_normalized); + //<- The dot product returns a stable result, because both initialVectors are already normalized. + float absDotProductResult_of_textDirPreFlip_and_camRight = Mathf.Abs(dotProductResult_of_textDirPreFlip_and_camRight); + bool drawnLine_isApproxVertical_insideScreen = absDotProductResult_of_textDirPreFlip_and_camRight < absDotProductResult_ofTwoApproxNormalizedVectors_belowWhichVectorsAreConsideredPerp; + if (drawnLine_isApproxVertical_insideScreen) + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(textDir_normalized_preFlip, cameraUp_normalized)) + { + textDir_normalized_postFlip = textDir_normalized_preFlip; + } + else + { + textDir_normalized_postFlip = (-textDir_normalized_preFlip); + } + } + else + { + if (dotProductResult_of_textDirPreFlip_and_camRight > 0.0f) + { + textDir_normalized_postFlip = textDir_normalized_preFlip; + } + else + { + textDir_normalized_postFlip = (-textDir_normalized_preFlip); + } + } + FlipNormalizedUp_toBeNonMirroredReadable_withA_fixedTextDir(out amplitudeUp_normalized_postFlip, amplitudeUp_normalized_preFlip, textDir_normalized_postFlip, cam_to_lineCenter); + } + + static void FlipNormalizedUpAndTextDir_toFit_textDirFromLeftToRightInsideScreen_viaUpDirDictatesVertInsideScreenApproximation(out Vector3 amplitudeUp_normalized_postFlip, out Vector3 textDir_normalized_postFlip, Vector3 amplitudeUp_normalized_preFlip, Vector3 textDir_normalized_preFlip, Vector3 cameraUp_normalized, Vector3 cameraRight_normalized, Vector3 cam_to_lineCenter) + { + //This "_viaUpDirDictates"-variant has: + //-> Disadvantage compared to "_viaTextDirDictates"-variant: Cannot detect lines that are vertInsideScreen very well, especially not for perspective cameras + //-> Advantage compared to "_viaTextDirDictates"-variant: But in most cases a resulting upSideDown-text is restricted to a smaller deviation of the lineDir from screenSpaceVert + //-> The solution that would have fully proper detection would be to first project the drawnLines onto the observerCameraPlane and execute the flipping after that. Though this seems too expensive, at least as long as the current implementation is acceptable. + + //A zero-result-dotProduct here does not mean that upDirPreFlip und camUp are perpInsideScreen: + //-> camUp always appears as vertLineInScreen, no matter where in the scene it is placed or in which corner of a warping perspective camera it appears + //-> perpendicularityInGlobalSpace doesn't translate to perpendicularityInScreenSpace, as long as lineDir and lineUp are both parallel to the screenPlane + //-> even if the zero-result-dotProduct indicates (in some cases) a perpendicularityInScreenspace, then a perpendicularityInScreenspace of lineUp and lineDir is still not guaranteed + //-> vertLines_inGlobalSpace appear as vertLines_inScreenSpace only for (non-z-turned)orthographic-cameras, but not for perspective cameras + float dotProductResult_of_upDirPreFlip_and_camUp = Vector3.Dot(amplitudeUp_normalized_preFlip, cameraUp_normalized); + //<- The dot product returns a stable result, because both initialVectors are already normalized. + float absDotProductResult_of_upDirPreFlip_and_camUp = Mathf.Abs(dotProductResult_of_upDirPreFlip_and_camUp); + bool drawnLine_isApproxVertical_insideScreen = absDotProductResult_of_upDirPreFlip_and_camUp < absDotProductResult_ofTwoApproxNormalizedVectors_belowWhichVectorsAreConsideredPerp; + + if (drawnLine_isApproxVertical_insideScreen) + { + //-> This cares for the "bistable case" of vertical lines, where the text direction can "flicker" because (due to float calculation imprecision) it cannot decide wheater to go upward or downward. + //-> In other words: The fallback here does this: Lines that are "almost" vertical count also as vertical, to prevent the flickering of text (who ongoingly changes it's direction because it cannot decide between "toUp" or "toDown" due to float calculation imprecision) in the common case of vertical(inWorldSpace) lines and vertical cameras. + //-> The fallback here is, that the text always goes upward in the screen (meaning: same behaviour as "automaticTextDirectionOfLines == towardsLineEnd"), while the "swap" to going downward is not at "exactly vertical line" but at "line angle has to differ from vertical by at least the angle that 'dotProductResult_ofTwoNormalizedVectors_belowWhichVectorsAreConsideredPerp' represents" + //-> In many cases this thread will not be reached, because as described above the zero-result-dotProduct doesn't detect the common vertLines_inGlobalSpace-case well. + //-> The lines that come from DrawScreenspace use this regularly, since in this case the zero-result-dotProduct works precisely. + //-> vertLines_inGlobalSpace for orthographic cameras (that have no z- and no x-rotation) arrive here. + + //-> an undefined bistable result of the dotProduct is not expected, since already before it was checked that "lineDir_normalized" is almost parallel to "cam.up". But if it happens it is no big problem, because the worst case is that the text is going downward(still non-mirrored and readable) instead of the wanted upward. + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(textDir_normalized_preFlip, cameraUp_normalized)) + { + textDir_normalized_postFlip = textDir_normalized_preFlip; + } + else + { + textDir_normalized_postFlip = (-textDir_normalized_preFlip); + } + FlipNormalizedUp_toBeNonMirroredReadable_withA_fixedTextDir(out amplitudeUp_normalized_postFlip, amplitudeUp_normalized_preFlip, textDir_normalized_postFlip, cam_to_lineCenter); + } + else + { + //textDir fromLeftToRight_inScreen - and line is not vertical inside screen + + //this ensures that "amplitudeUp_normalized" (approx)always goes upward inside the screen: + if (dotProductResult_of_upDirPreFlip_and_camUp > 0.0f) + { + amplitudeUp_normalized_postFlip = amplitudeUp_normalized_preFlip; + } + else + { + amplitudeUp_normalized_postFlip = (-amplitudeUp_normalized_preFlip); + } + FlipNormalizedTextDir_toBeNonMirroredReadable_forFixedAmplitudeUpDir(out textDir_normalized_postFlip, textDir_normalized_preFlip, amplitudeUp_normalized_postFlip, cam_to_lineCenter); + } + } + + static void FlipNormalizedUp_toBeNonMirroredReadable_withA_fixedTextDir(out Vector3 amplitudeUp_normalized_postFlip, Vector3 amplitudeUp_normalized_preFlip, Vector3 fixed_textDir_normalized, Vector3 cam_to_lineCenter) + { + Vector3 amplitudeUp_ifTextShouldBeNonMirroredReadableInCamScreen_notNormalized = Vector3.Cross(cam_to_lineCenter, fixed_textDir_normalized); + //-> "amplitudeUp_ifTextShouldBeNonMirroredReadableInCamScreen_notNormalized" may become zero in seldom edge cases + //-> but this is not a problem, because in such cases the text would anyway be almost parallel to camViewDir so it is not a big problem if the text will be displayed as mirrored. + + //-> concerning the following dotProduct inside "Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir": It is very unlikely or even impossible that the two vectors become perp. And even if: The worst problem it could produce is that the text is displayed mirrored, so no big problem. + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(amplitudeUp_normalized_preFlip, amplitudeUp_ifTextShouldBeNonMirroredReadableInCamScreen_notNormalized)) + { + amplitudeUp_normalized_postFlip = amplitudeUp_normalized_preFlip; + } + else + { + amplitudeUp_normalized_postFlip = (-amplitudeUp_normalized_preFlip); + } + } + + public static void FlipNormalizedTextDir_toBeNonMirroredReadable_forFixedAmplitudeUpDir(out Vector3 textDir_normalized_postFlip, Vector3 textDir_normalized_preFlip, Vector3 fixed_amplitudeUp_normalized, Vector3 cam_to_lineCenter) + { + if (DrawBasics.automaticTextDirectionOfLines == DrawBasics.AutomaticTextDirectionOfLines.towardsLineEnd) + { + textDir_normalized_postFlip = textDir_normalized_preFlip; + } + else + { + //textDir fromLeftToRight in screen: + Vector3 textDir_ifTextShouldBeNonMirroredReadableInCamScreen_notNormalized_notParallelToLine = Vector3.Cross(fixed_amplitudeUp_normalized, cam_to_lineCenter); + //crossProduct or dotProduct result of 0 is not a big problem here, because that means that either the upVector or the lineDir are along camera view dir: So the text will anyway not be seen an the correct "direction flipping" of the textDir doesn't matter in such cases. + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(textDir_ifTextShouldBeNonMirroredReadableInCamScreen_notNormalized_notParallelToLine, textDir_normalized_preFlip)) + { + textDir_normalized_postFlip = textDir_normalized_preFlip; + } + else + { + textDir_normalized_postFlip = (-textDir_normalized_preFlip); + } + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.cs.meta new file mode 100644 index 0000000..4dc4f4d --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 16f2462a416249349ba54b5cb4a45052 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineCircled.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineCircled.cs new file mode 100644 index 0000000..c667960 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineCircled.cs @@ -0,0 +1,1214 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_LineCircled + { + static InternalDXXL_Plane plane_inWhichArbitraryTurnAxis_preferrablyLies = new InternalDXXL_Plane(Vector3.zero, new Vector3(1.129872f, 0.7129881f, 0.0f)); //=seldom plane which contains z-axis + public static void LineCircled(Vector3 circleCenter, Vector3 circleCenter_to_start, Vector3 circleCenter_to_end, Color color, float forceRadius, float width, string text, bool useReflexAngleOver180deg, bool skipFallbackDisplayOfZeroAngles, bool flattenThickRoundLineIntoCirclePlane, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(forceRadius, "forceRadius")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter, "circleCenter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter_to_start, "circleCenter_to_start")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter_to_end, "circleCenter_to_end")) { return; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(circleCenter_to_start)) + { + UtilitiesDXXL_DrawBasics.PointFallback(circleCenter, "[ LineCircled with startVectorLength of 0]
" + text, color, width, durationInSec, hiddenByNearerObjects); + return; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(circleCenter_to_end)) + { + UtilitiesDXXL_DrawBasics.PointFallback(circleCenter, "[ LineCircled with endVectorLength of 0]
" + text, color, width, durationInSec, hiddenByNearerObjects); + return; + } + + Vector3 circleCenter_to_start_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(circleCenter_to_start); + Vector3 circleCenter_towards_end_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(circleCenter_to_end); + float turnAngleDeg = Vector3.Angle(circleCenter_to_start_normalized, circleCenter_towards_end_normalized); + Vector3 turnAxis = Vector3.Cross(circleCenter_to_start_normalized, circleCenter_towards_end_normalized); + if (UtilitiesDXXL_Math.ApproximatelyZero(forceRadius) == false) + { + circleCenter_to_start = circleCenter_to_start_normalized * Mathf.Abs(forceRadius); + } + Vector3 startPos = circleCenter + circleCenter_to_start; + + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(turnAxis) < 0.0001f) + { + // -> turnAngleDeg is "0°" or "180°" + Vector3 arbitraryTurnAxis = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(circleCenter_to_start, plane_inWhichArbitraryTurnAxis_preferrablyLies); + if (arbitraryTurnAxis.z < 0.0f) { arbitraryTurnAxis = -arbitraryTurnAxis; } //-> 2D circledLines need turnAxis along positiveZ + + if (turnAngleDeg < 90.0f) + { + LineCircled(startPos, circleCenter, arbitraryTurnAxis, 0.0f, color, width, "[ LineCircled with 'toStart' and 'toEnd' vectors roughly along same direction (segment angle is 0°) => arbitrary turn axis]
" + text, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + else + { + LineCircled(startPos, circleCenter, arbitraryTurnAxis, 180.0f, color, width, "[ LineCircled with 'toStart' and 'toEnd' vectors roughly along opposite directions (segment angle is 180°) => arbitrary turn axis]
" + text, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + } + else + { + if (useReflexAngleOver180deg) + { + Vector3 usedTurnAxis = -turnAxis; + float usedTurnAngleDeg = 360.0f - turnAngleDeg; + LineCircled(startPos, circleCenter, usedTurnAxis, usedTurnAngleDeg, color, width, text, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + else + { + LineCircled(startPos, circleCenter, turnAxis, turnAngleDeg, color, width, text, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + } + } + + static InternalDXXL_Line turnAxis_ofLineCircled = new InternalDXXL_Line(); + public static void LineCircled(Vector3 startPos, Vector3 turnAxis_origin, Vector3 turnAxis_direction, float turnAngleDegCC, Color color, float width, string text, bool skipFallbackDisplayOfZeroAngles, bool flattenThickRoundLineIntoCirclePlane, float durationInSec, bool hiddenByNearerObjects, bool skipTextMirrorInvertedFlipCheck, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, bool drawSeparateFullCircle_forAnglesBiggerThan360 = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(turnAngleDegCC, "turnAngleDegCC")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(minAngleDeg_withoutTextLineBreak, "minAngleDeg_withoutTextLineBreak")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPos, "startPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(turnAxis_origin, "turnAxis_origin")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(turnAxis_direction, "turnAxis_direction")) { return; } + + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + + if (UtilitiesDXXL_Math.ApproximatelyZero(turnAxis_direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(turnAxis_origin, "[ LineCircled with turnAxis_direction_length of 0]
" + text, color, width, durationInSec, hiddenByNearerObjects); + return; + } + + turnAxis_ofLineCircled.Recreate(turnAxis_origin, turnAxis_direction, false); + Vector3 circleCenter = turnAxis_ofLineCircled.Get_perpProjectionOfPoint_ontoThisLine(startPos); + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(startPos, circleCenter)) + { + UtilitiesDXXL_DrawBasics.PointFallback(circleCenter, "[ LineCircled with startPos on turnAxis]
" + text, color, width, durationInSec, hiddenByNearerObjects); + return; + } + + float unlooped_turnAngleDegCC = turnAngleDegCC; + bool unloopedAngleIsOutside_m360_to_p360 = CheckIfAngleIsOutside_m360_to_p360(unlooped_turnAngleDegCC); + if (drawSeparateFullCircle_forAnglesBiggerThan360) //-> endless regression loops are actually already prevented by "turnAngleDegCC_ofAdditional360degRing = 360.0f", but it's better to additionally protect against float calculation/comparison imprecsion herewith + { + if (unloopedAngleIsOutside_m360_to_p360) + { + float turnAngleDegCC_ofAdditional360degRing = 360.0f; + string text_ofAdditional360degRing = null; + bool drawSeparateFullCircle_forAnglesBiggerThan360_onceMore = false; + LineCircled(startPos, turnAxis_origin, turnAxis_direction, turnAngleDegCC_ofAdditional360degRing, color, width, text_ofAdditional360degRing, true, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects, skipTextMirrorInvertedFlipCheck, minAngleDeg_withoutTextLineBreak, textAnchor, drawSeparateFullCircle_forAnglesBiggerThan360_onceMore); + } + } + + turnAngleDegCC = LoopAngleIntoSpanFrom_m360_to_p360(unlooped_turnAngleDegCC); + Vector3 circleCenter_to_start = startPos - circleCenter; + if (UtilitiesDXXL_Math.ApproximatelyZero(turnAngleDegCC)) + { + if (unloopedAngleIsOutside_m360_to_p360) + { + //-> multiples of 360° arrive here, like +/-720° or +/-1080° + turnAngleDegCC = 359.99f * Mathf.Sign(unlooped_turnAngleDegCC); + } + else + { + if (skipFallbackDisplayOfZeroAngles == false) + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorFrom(circleCenter, circleCenter_to_start, color, width, "[ LineCircled with angle of 0°]
" + text, 0.17f, false, false, default(Vector3), false, 0.02f, false, 0.0f, durationInSec, hiddenByNearerObjects); + DrawBasics.VectorFrom(circleCenter, turnAxis_ofLineCircled.direction_normalized, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.6f), 0.0f, "[turnAxis]", 0.17f, false, false, default(Vector3), false, 0.02f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + return; + } + } + + Vector3 circleCenter_towards_end_normalized = circleCenter_to_start; //-> silencing the compiler who seems to not realize that it will always get filled via the out-parameters before it is used + float usedRadius; + if (turnAngleDegCC >= 180.0f) + { + usedRadius = LineCircledBelow180Deg(circleCenter, circleCenter_to_start, out circleCenter_towards_end_normalized, 90.0f, turnAxis_ofLineCircled.direction_normalized, color, 0.0f, width, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects); + LineCircledBelow180Deg(circleCenter, -circleCenter_to_start, out circleCenter_towards_end_normalized, -90.0f, turnAxis_ofLineCircled.direction_normalized, color, 0.0f, width, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects); + LineCircledBelow180Deg(circleCenter, -circleCenter_to_start, out circleCenter_towards_end_normalized, turnAngleDegCC - 180.0f, turnAxis_ofLineCircled.direction_normalized, color, 0.0f, width, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects); + } + else + { + if (turnAngleDegCC <= (-180.0f)) + { + usedRadius = LineCircledBelow180Deg(circleCenter, circleCenter_to_start, out circleCenter_towards_end_normalized, -90.0f, turnAxis_ofLineCircled.direction_normalized, color, 0.0f, width, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects); + LineCircledBelow180Deg(circleCenter, -circleCenter_to_start, out circleCenter_towards_end_normalized, 90.0f, turnAxis_ofLineCircled.direction_normalized, color, 0.0f, width, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects); + LineCircledBelow180Deg(circleCenter, -circleCenter_to_start, out circleCenter_towards_end_normalized, turnAngleDegCC + 180.0f, turnAxis_ofLineCircled.direction_normalized, color, 0.0f, width, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects); + } + else + { + usedRadius = LineCircledBelow180Deg(circleCenter, circleCenter_to_start, out circleCenter_towards_end_normalized, turnAngleDegCC, turnAxis_ofLineCircled.direction_normalized, color, 0.0f, width, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects); + } + } + + TryDraw_textAtLineCircled(color, width, text, usedRadius, circleCenter, turnAxis_direction, circleCenter_to_start, circleCenter_towards_end_normalized, turnAngleDegCC, minAngleDeg_withoutTextLineBreak, textAnchor, skipTextMirrorInvertedFlipCheck, durationInSec, hiddenByNearerObjects); + } + + public static void CircleSegment(Vector3 circleCenter, Vector3 circleCenter_to_startPosOnPerimeter, Vector3 circleCenter_to_endPosOnPerimeter, Color color, float forceRadius, float fillDensity, string text, bool useReflexAngleOver180deg, float radiusPortionWhereDrawFillStarts, bool skipFallbackDisplayOfZeroAngles, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(forceRadius, "forceRadius")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter, "circleCenter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter_to_startPosOnPerimeter, "circleCenter_to_startPosOnPerimeter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter_to_endPosOnPerimeter, "circleCenter_to_endPosOnPerimeter")) { return; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(circleCenter_to_startPosOnPerimeter)) + { + UtilitiesDXXL_DrawBasics.PointFallback(circleCenter, "[ CircleSegment with circleCenter_to_startPosOnPerimeter-length of 0]
" + text, color, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(circleCenter_to_endPosOnPerimeter)) + { + UtilitiesDXXL_DrawBasics.PointFallback(circleCenter, "[ CircleSegment with circleCenter_to_endPosOnPerimeter-length of 0]
" + text, color, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + Vector3 circleCenter_towards_startPosOnPerimeter_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(circleCenter_to_startPosOnPerimeter); + Vector3 circleCenter_towards_endPosOnPerimeter_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(circleCenter_to_endPosOnPerimeter); + float turnAngleDeg = Vector3.Angle(circleCenter_towards_startPosOnPerimeter_normalized, circleCenter_towards_endPosOnPerimeter_normalized); + Vector3 turnAxis = Vector3.Cross(circleCenter_towards_startPosOnPerimeter_normalized, circleCenter_towards_endPosOnPerimeter_normalized); + if (UtilitiesDXXL_Math.ApproximatelyZero(forceRadius) == false) + { + circleCenter_to_startPosOnPerimeter = circleCenter_towards_startPosOnPerimeter_normalized * Mathf.Abs(forceRadius); + } + Vector3 startPosOnPerimeter = circleCenter + circleCenter_to_startPosOnPerimeter; + + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(turnAxis) < 0.0001f) + { + // -> turnAngleDeg is "0°" or "180°" + Vector3 arbitraryTurnAxis = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(circleCenter_to_startPosOnPerimeter, plane_inWhichArbitraryTurnAxis_preferrablyLies); + if (arbitraryTurnAxis.z < 0.0f) { arbitraryTurnAxis = -arbitraryTurnAxis; } //-> 2D circledLines need turnAxis along positiveZ + + if (turnAngleDeg < 90.0f) + { + CircleSegment(startPosOnPerimeter, circleCenter, arbitraryTurnAxis, 0.0f, color, "[ CircleSegment with 'toStart' and 'toEnd' vectors roughly along same direction (segment angle is 0°) => arbitrary turn axis]
" + text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + else + { + CircleSegment(startPosOnPerimeter, circleCenter, arbitraryTurnAxis, 180.0f, color, "[ CircleSegment with 'toStart' and 'toEnd' vectors roughly along opposite directions (segment angle is 180°) => arbitrary turn axis]
" + text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + } + else + { + if (useReflexAngleOver180deg) + { + Vector3 usedTurnAxis = -turnAxis; + float usedTurnAngleDeg = 360.0f - turnAngleDeg; + CircleSegment(startPosOnPerimeter, circleCenter, usedTurnAxis, usedTurnAngleDeg, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + else + { + CircleSegment(startPosOnPerimeter, circleCenter, turnAxis, turnAngleDeg, color, text, radiusPortionWhereDrawFillStarts, skipFallbackDisplayOfZeroAngles, fillDensity, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + } + } + } + + public static void CircleSegment(Vector3 startPosOnPerimeter, Vector3 centerOfCircle, Vector3 normalOfCircle, float turnAngleDegCC, Color color, string text, float radiusPortionWhereDrawFillStarts, bool skipFallbackDisplayOfZeroAngles, float fillDensity, float durationInSec, bool hiddenByNearerObjects, bool skipTextMirrorInvertedFlipCheck, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, bool drawSeparateFullCircle_forAnglesBiggerThan360 = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(turnAngleDegCC, "turnAngleDegCC")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radiusPortionWhereDrawFillStarts, "radiusPortionWhereDrawFillStarts")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(fillDensity, "fillDensity")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(minAngleDeg_withoutTextLineBreak, "minAngleDeg_withoutTextLineBreak")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPosOnPerimeter, "startPosOnPerimeter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerOfCircle, "centerOfCircle")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normalOfCircle, "normalOfCircle")) { return; } + + if (radiusPortionWhereDrawFillStarts >= 1.0f) + { + LineCircled(startPosOnPerimeter, centerOfCircle, normalOfCircle, turnAngleDegCC, color, 0.0f, text, skipFallbackDisplayOfZeroAngles, false, durationInSec, hiddenByNearerObjects, skipTextMirrorInvertedFlipCheck, minAngleDeg_withoutTextLineBreak, textAnchor, drawSeparateFullCircle_forAnglesBiggerThan360); + return; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(normalOfCircle)) + { + UtilitiesDXXL_DrawBasics.PointFallback(centerOfCircle, "[ CircleSegment with normalOfCircle-length of 0]
" + text, color, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + turnAxis_ofLineCircled.Recreate(centerOfCircle, normalOfCircle, false); + Vector3 circleCenter = turnAxis_ofLineCircled.Get_perpProjectionOfPoint_ontoThisLine(startPosOnPerimeter); + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(startPosOnPerimeter, circleCenter)) + { + UtilitiesDXXL_DrawBasics.PointFallback(circleCenter, "[ CircleSegment with perimeter start position on circle center]
" + text, color, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + float unlooped_turnAngleDegCC = turnAngleDegCC; + bool unloopedAngleIsOutside_m360_to_p360 = CheckIfAngleIsOutside_m360_to_p360(unlooped_turnAngleDegCC); + bool applyOffsetForRadialLinesToIndicateAnglesOver360deg = false; + if (drawSeparateFullCircle_forAnglesBiggerThan360) //-> endless regression loops are actually already prevented by "turnAngleDegCC_ofAdditional360degRing = 360.0f", but it's better to additionally protect against float calculation/comparison imprecsion herewith + { + if (unloopedAngleIsOutside_m360_to_p360) + { + float turnAngleDegCC_ofAdditional360degRing = 360.0f; + string text_ofAdditional360degRing = null; + bool drawSeparateFullCircle_forAnglesBiggerThan360_onceMore = false; + CircleSegment(startPosOnPerimeter, centerOfCircle, normalOfCircle, turnAngleDegCC_ofAdditional360degRing, color, text_ofAdditional360degRing, radiusPortionWhereDrawFillStarts, true, fillDensity, durationInSec, hiddenByNearerObjects, skipTextMirrorInvertedFlipCheck, minAngleDeg_withoutTextLineBreak, textAnchor, drawSeparateFullCircle_forAnglesBiggerThan360_onceMore); + applyOffsetForRadialLinesToIndicateAnglesOver360deg = true; + } + } + + turnAngleDegCC = LoopAngleIntoSpanFrom_m360_to_p360(unlooped_turnAngleDegCC); + Vector3 circleCenter_to_startPosOnPerimeter = startPosOnPerimeter - circleCenter; + if (UtilitiesDXXL_Math.ApproximatelyZero(turnAngleDegCC)) + { + if (unloopedAngleIsOutside_m360_to_p360) + { + //-> multiples of 360° arrive here, like +/-720° or +/-1080° + turnAngleDegCC = 359.99f * Mathf.Sign(unlooped_turnAngleDegCC); + } + else + { + if (skipFallbackDisplayOfZeroAngles == false) + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorFrom(circleCenter, circleCenter_to_startPosOnPerimeter, color, 0.0f, "[ CircleSegment with angle of 0°]
" + text, 0.17f, false, false, default(Vector3), false, 0.02f, false, 0.0f, durationInSec, hiddenByNearerObjects); + DrawBasics.VectorFrom(circleCenter, turnAxis_ofLineCircled.direction_normalized, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.6f), 0.0f, "[normal of circle]", 0.17f, false, false, default(Vector3), false, 0.02f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + return; + } + } + + Vector3 circleCenter_towards_endPosOnPerimeter_normalized = circleCenter_to_startPosOnPerimeter; //-> silencing the compiler who seems to not realize that it will always get filled via the out-parameters before it is used + float radiusOfRoundOuterBoundaryLine; + if (turnAngleDegCC >= 180.0f) + { + radiusOfRoundOuterBoundaryLine = CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, true, true, circleCenter, circleCenter_to_startPosOnPerimeter, out circleCenter_towards_endPosOnPerimeter_normalized, 90.0f, turnAxis_ofLineCircled.direction_normalized, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, hiddenByNearerObjects); + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, true, false, circleCenter, -circleCenter_to_startPosOnPerimeter, out circleCenter_towards_endPosOnPerimeter_normalized, -90.0f, turnAxis_ofLineCircled.direction_normalized, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, hiddenByNearerObjects); + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, false, true, circleCenter, -circleCenter_to_startPosOnPerimeter, out circleCenter_towards_endPosOnPerimeter_normalized, turnAngleDegCC - 180.0f, turnAxis_ofLineCircled.direction_normalized, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, hiddenByNearerObjects); + } + else + { + if (turnAngleDegCC <= (-180.0f)) + { + radiusOfRoundOuterBoundaryLine = CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, true, true, circleCenter, circleCenter_to_startPosOnPerimeter, out circleCenter_towards_endPosOnPerimeter_normalized, -90.0f, turnAxis_ofLineCircled.direction_normalized, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, hiddenByNearerObjects); + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, true, false, circleCenter, -circleCenter_to_startPosOnPerimeter, out circleCenter_towards_endPosOnPerimeter_normalized, 90.0f, turnAxis_ofLineCircled.direction_normalized, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, hiddenByNearerObjects); + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, false, true, circleCenter, -circleCenter_to_startPosOnPerimeter, out circleCenter_towards_endPosOnPerimeter_normalized, turnAngleDegCC + 180.0f, turnAxis_ofLineCircled.direction_normalized, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, hiddenByNearerObjects); + } + else + { + radiusOfRoundOuterBoundaryLine = CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, true, true, circleCenter, circleCenter_to_startPosOnPerimeter, out circleCenter_towards_endPosOnPerimeter_normalized, turnAngleDegCC, turnAxis_ofLineCircled.direction_normalized, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, hiddenByNearerObjects); + } + } + + TryDraw_textAtLineCircled(color, 0.0f, text, radiusOfRoundOuterBoundaryLine, circleCenter, normalOfCircle, circleCenter_to_startPosOnPerimeter, circleCenter_towards_endPosOnPerimeter_normalized, turnAngleDegCC, minAngleDeg_withoutTextLineBreak, textAnchor, skipTextMirrorInvertedFlipCheck, durationInSec, hiddenByNearerObjects); + } + + static void TryDraw_textAtLineCircled(Color color, float widthOfOuterBoundaryLine, string text, float radiusOfRoundOuterBoundaryLine, Vector3 circleCenter, Vector3 turnAxis_direction, Vector3 circleCenter_to_start, Vector3 circleCenter_towards_endPosOnPerimeter_normalized, float turnAngleDegCC, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, bool skipTextMirrorInvertedFlipCheck, float durationInSec, bool hiddenByNearerObjects) + { + if (text != null && text != "") + { + float textRadius = 1.05f * radiusOfRoundOuterBoundaryLine + 0.5f * widthOfOuterBoundaryLine; + float textSize = 0.1f * radiusOfRoundOuterBoundaryLine; + GetTextsInitialDirAndUpVectors(out Vector3 textsInitialDir, out Vector3 textsInitialUp, turnAxis_direction, turnAngleDegCC, circleCenter, circleCenter_to_start, circleCenter_towards_endPosOnPerimeter_normalized, skipTextMirrorInvertedFlipCheck); + float autoLineBreakAngleDeg = Mathf.Abs(turnAngleDegCC); + if (minAngleDeg_withoutTextLineBreak > 0.0f) + { + autoLineBreakAngleDeg = Mathf.Max(autoLineBreakAngleDeg, minAngleDeg_withoutTextLineBreak); + } + + //"autoFlipToPreventMirrorInverted" is disabled here, because: + //-> The problem is already solved by "GetTextsInitialDirAndUpVectors()". The solutions may be exchangeable. The difference is: The solution in "GetTextsInitialDirAndUpVectors" mounts the flippedText at the lineEnd, while the solution via "autoFlipToPreventMirrorInverted" mounts the flippedText text at lineStart. + //-> Advantage of the "GetTextsInitialDirAndUpVectors()"-solution: For circledLines that span only a small angle: The text "starts" at the line and the textEnd prodrudes over the line end, instead of the text starting somewhere away from the line and the "ends" at the line. + //-> Disadvantage of the "GetTextsInitialDirAndUpVectors()"-solution: For circledLines that have a bigger angle span: If the text gets autoFlipped then it is mounted at the lineEnd and therefore may confuse the human observer, wheather there is the lineStart or lineEnd. + bool autoFlipToPreventMirrorInverted = false; + UtilitiesDXXL_Text.WriteOnCircle(text, circleCenter, textRadius, color, textSize, textsInitialDir, textsInitialUp, textAnchor, autoLineBreakAngleDeg, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, false, false, false); + } + } + + static void GetTextsInitialDirAndUpVectors(out Vector3 textsInitialDir, out Vector3 textsInitialUp, Vector3 turnAxis_direction, float turnAngleDegCC, Vector3 circleCenter, Vector3 circleCenter_to_start, Vector3 circleCenter_towards_end_normalized, bool skipTextMirrorInvertedFlipCheck) + { + if (skipTextMirrorInvertedFlipCheck) + { + textsInitialUp = circleCenter_to_start; + textsInitialDir = Vector3.Cross(textsInitialUp, turnAxis_direction); + } + else + { + Vector3 turnAxis_flippedSoThatLookingAlongThisAlwaysResultsInClockwiseRotation; + if (turnAngleDegCC > 0.0f) + { + //counter clockwise: + turnAxis_flippedSoThatLookingAlongThisAlwaysResultsInClockwiseRotation = (-turnAxis_direction); + } + else + { + //clockwise: + turnAxis_flippedSoThatLookingAlongThisAlwaysResultsInClockwiseRotation = turnAxis_direction; + } + + UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, circleCenter, Vector3.zero, null); + bool textFromCircleStart_wouldResultInMirrorInvertedText = UtilitiesDXXL_Math.Check_ifVectorsPointAwayFromEachOther_perpCountsAsPointingInSameDir(turnAxis_flippedSoThatLookingAlongThisAlwaysResultsInClockwiseRotation, cam_to_lineCenter); + if (textFromCircleStart_wouldResultInMirrorInvertedText) + { + textsInitialUp = circleCenter_towards_end_normalized; + textsInitialDir = Vector3.Cross(textsInitialUp, (-turnAxis_flippedSoThatLookingAlongThisAlwaysResultsInClockwiseRotation)); + } + else + { + textsInitialUp = circleCenter_to_start; + textsInitialDir = Vector3.Cross(textsInitialUp, turnAxis_flippedSoThatLookingAlongThisAlwaysResultsInClockwiseRotation); + } + } + } + + public static void VectorCircled(Vector3 circleCenter, Vector3 circleCenter_to_start, Vector3 circleCenter_to_end, Color color, float forceRadius, float lineWidth, string text, bool useReflexAngleOver180deg, float coneLength, bool skipFallbackDisplayOfZeroAngles, bool pointerAtBothSides, bool flattenThickRoundLineIntoCirclePlane, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(forceRadius, "forceRadius")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter, "circleCenter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter_to_start, "circleCenter_to_start")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter_to_end, "circleCenter_to_end")) { return; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(circleCenter_to_start)) + { + UtilitiesDXXL_DrawBasics.PointFallback(circleCenter, "[ VectorCircled with startVectorLength of 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + return; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(circleCenter_to_end)) + { + UtilitiesDXXL_DrawBasics.PointFallback(circleCenter, "[ VectorCircled with endVectorLength of 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + return; + } + + Vector3 circleCenter_to_start_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(circleCenter_to_start); + Vector3 circleCenter_towards_end_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(circleCenter_to_end); + float turnAngleDeg = Vector3.Angle(circleCenter_to_start_normalized, circleCenter_towards_end_normalized); + Vector3 turnAxis = Vector3.Cross(circleCenter_to_start_normalized, circleCenter_towards_end_normalized); + if (UtilitiesDXXL_Math.ApproximatelyZero(forceRadius) == false) + { + circleCenter_to_start = circleCenter_to_start_normalized * Mathf.Abs(forceRadius); + } + + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(turnAxis) < 0.0001f) + { + // -> turnAngleDeg is "0°" or "180°" + Vector3 arbitraryTurnAxis = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(circleCenter_to_start, plane_inWhichArbitraryTurnAxis_preferrablyLies); + if (arbitraryTurnAxis.z < 0.0f) { arbitraryTurnAxis = -arbitraryTurnAxis; } //-> 2D circledLines need turnAxis along positiveZ + + if (turnAngleDeg < 90.0f) + { + VectorCircled(circleCenter + circleCenter_to_start, circleCenter, arbitraryTurnAxis, 0.0f, color, lineWidth, "[ VectorCircled with vectors roughly along same direction (covered angle is 0°) => arbitrary turn axis]
" + text, coneLength, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects, 1.0f); + } + else + { + VectorCircled(circleCenter + circleCenter_to_start, circleCenter, arbitraryTurnAxis, 180.0f, color, lineWidth, "[ VectorCircled with vectors roughly along opposite directions (covered angle is 180°) => arbitrary turn axis]
" + text, coneLength, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects, 1.0f); + } + } + else + { + if (useReflexAngleOver180deg) + { + Vector3 usedTurnAxis = -turnAxis; + float usedTurnAngleDeg = 360.0f - turnAngleDeg; + VectorCircled(circleCenter + circleCenter_to_start, circleCenter, usedTurnAxis, usedTurnAngleDeg, color, lineWidth, text, coneLength, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects, 1.0f); + } + else + { + VectorCircled(circleCenter + circleCenter_to_start, circleCenter, turnAxis, turnAngleDeg, color, lineWidth, text, coneLength, skipFallbackDisplayOfZeroAngles, pointerAtBothSides, flattenThickRoundLineIntoCirclePlane, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, hiddenByNearerObjects, 1.0f); + } + } + } + + static InternalDXXL_Line turnAxis_ofVectorCircled = new InternalDXXL_Line(); + public static void VectorCircled(Vector3 startPos, Vector3 turnAxis_origin, Vector3 turnAxis_direction, float turnAngleDegCC, Color color, float lineWidth, string text, float coneLength, bool skipFallbackDisplayOfZeroAngles, bool pointerAtBothSides, bool flattenThickRoundLineIntoCirclePlane, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec, bool hiddenByNearerObjects, float alphaFactorForPointers) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(turnAngleDegCC, "turnAngleDegCC")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth, "lineWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(coneLength, "coneLength")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPos, "startPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(turnAxis_origin, "turnAxis_origin")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(turnAxis_direction, "turnAxis_direction")) { return; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(turnAxis_direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(turnAxis_origin, "[ VectorCircled with turnAxis_direction_length of 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + return; + } + + turnAxis_ofVectorCircled.Recreate(turnAxis_origin, turnAxis_direction, false); + Vector3 circleCenter = turnAxis_ofVectorCircled.Get_perpProjectionOfPoint_ontoThisLine(startPos); + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(startPos, circleCenter)) + { + UtilitiesDXXL_DrawBasics.PointFallback(circleCenter, "[ VectorCircled with startPos on turnAxis]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + return; + } + + float unlooped_turnAngleDegCC = turnAngleDegCC; + bool unloopedAngleIsOutside_m360_to_p360 = CheckIfAngleIsOutside_m360_to_p360(unlooped_turnAngleDegCC); + if (unloopedAngleIsOutside_m360_to_p360) + { + float turnAngleDegCC_ofAdditional360degRing = 360.0f; + string text_ofAdditional360degRing = null; + bool drawSeparateFullCircle_forAnglesBiggerThan360_onceMore = false; + LineCircled(startPos, circleCenter, turnAxis_ofVectorCircled.direction_normalized, turnAngleDegCC_ofAdditional360degRing, color, lineWidth, text_ofAdditional360degRing, true, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects, true, minAngleDeg_withoutTextLineBreak, textAnchor, drawSeparateFullCircle_forAnglesBiggerThan360_onceMore); + } + + Vector3 circleCenter_to_start = startPos - circleCenter; + turnAngleDegCC = LoopAngleIntoSpanFrom_m360_to_p360(turnAngleDegCC); + if (UtilitiesDXXL_Math.ApproximatelyZero(turnAngleDegCC)) + { + if (unloopedAngleIsOutside_m360_to_p360) + { + //-> multiples of 360° arrive here, like +/-720° or +/-1080° + turnAngleDegCC = 359.99f * Mathf.Sign(unlooped_turnAngleDegCC); + } + else + { + if (skipFallbackDisplayOfZeroAngles == false) + { + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorFrom(circleCenter, circleCenter_to_start, color, lineWidth, "[ VectorCircled with angle of 0°]
" + text, 0.17f, false, false, default(Vector3), false, 0.02f, false, 0.0f, durationInSec, hiddenByNearerObjects); + DrawBasics.VectorFrom(circleCenter, turnAxis_ofVectorCircled.direction_normalized, UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.6f), 0.0f, "[turnAxis]", 0.17f, false, false, default(Vector3), false, 0.02f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + return; + } + } + + lineWidth = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth); + if (lineWidth < DrawBasics.thinestPossibleNonZeroWidthLine) { lineWidth = 0.0f; } + bool isThinLine = UtilitiesDXXL_Math.ApproximatelyZero(lineWidth); + float absTurnAngleDeg = Mathf.Abs(turnAngleDegCC); + float turnAngleSign = Mathf.Sign(turnAngleDegCC); + float radius = circleCenter_to_start.magnitude; + float perimeterOf360deg = 2.0f * radius * Mathf.PI; + + if (DrawBasics.coneLength_interpretation_forCircledVectors == DrawBasics.LengthInterpretation.relativeToLineLength) { coneLength = radius * coneLength; } + coneLength = Mathf.Abs(coneLength); + float minConeLength = (0.01f * absTurnAngleDeg / 360.0f) * perimeterOf360deg; + float maxConeLength = (0.45f * absTurnAngleDeg / 360.0f) * perimeterOf360deg; + float maxConeLength_asAngleDeg = 45.0f; + float maxConeLength_fromAngleLimit = (maxConeLength_asAngleDeg / 360.0f) * perimeterOf360deg; + maxConeLength = Mathf.Min(maxConeLength, maxConeLength_fromAngleLimit); + coneLength = Mathf.Clamp(coneLength, minConeLength, maxConeLength); + float coneLength_asAngleDeg = 360.0f * (coneLength / perimeterOf360deg); + + float coneAngleDeg = 25.0f; + if (isThinLine == false) + { + float coneSize_to_lineWidth_scaler = 1.0f; + float minConeAngleDeg = 2.0f * Mathf.Rad2Deg * Mathf.Atan(coneSize_to_lineWidth_scaler * lineWidth / coneLength); + coneAngleDeg = Mathf.Max(coneAngleDeg, minConeAngleDeg); + } + + float shorteningOf_straightLineInsideCone = 0.0f; + if (isThinLine == false) + { + shorteningOf_straightLineInsideCone = (0.5f * lineWidth) / Mathf.Tan(Mathf.Deg2Rad * 0.5f * coneAngleDeg); + shorteningOf_straightLineInsideCone = 2.0f * shorteningOf_straightLineInsideCone; //solves: curvedLine is not parallel/aligned to coneDir and therefore intersects the coneSurface + shorteningOf_straightLineInsideCone = Mathf.Min(shorteningOf_straightLineInsideCone, 0.85f * coneLength); + } + float shorteningOf_straightLineInsideCone_asAngleDeg = 360.0f * (shorteningOf_straightLineInsideCone / perimeterOf360deg); + + float turnAngleDeg_ofUnconedPart = turnAngleDegCC - (turnAngleSign * coneLength_asAngleDeg); + Vector3 circleCenter_to_startOfUnconedPart = circleCenter_to_start; + if (pointerAtBothSides) + { + turnAngleDeg_ofUnconedPart = turnAngleDegCC - 2.0f * (turnAngleSign * coneLength_asAngleDeg); + Quaternion rotationToStartOfUnconedPart = Quaternion.AngleAxis(turnAngleSign * coneLength_asAngleDeg, turnAxis_ofVectorCircled.direction_normalized); + circleCenter_to_startOfUnconedPart = rotationToStartOfUnconedPart * circleCenter_to_start; + } + + Vector3 startOfUnconedPart = circleCenter + circleCenter_to_startOfUnconedPart; + LineCircled(startOfUnconedPart, circleCenter, turnAxis_ofVectorCircled.direction_normalized, turnAngleDeg_ofUnconedPart, color, lineWidth, text, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, durationInSec, hiddenByNearerObjects, false, minAngleDeg_withoutTextLineBreak, textAnchor); + + Quaternion rotationToEndOfUnconedPart = Quaternion.AngleAxis(turnAngleDegCC - (turnAngleSign * coneLength_asAngleDeg), turnAxis_ofVectorCircled.direction_normalized); + Vector3 circleCenter_to_endOfUnconedPart = rotationToEndOfUnconedPart * circleCenter_to_start; + Quaternion rotationToEndOfDrawnCircleLineInsideEndCone = Quaternion.AngleAxis(turnAngleDegCC - (turnAngleSign * shorteningOf_straightLineInsideCone_asAngleDeg), turnAxis_ofVectorCircled.direction_normalized); + Vector3 circleCenter_to_endOfDrawnCircleLineInsideEndCone = rotationToEndOfDrawnCircleLineInsideEndCone * circleCenter_to_start; + Quaternion rotationToStartOfDrawnCircleLineInsideStartCone = Quaternion.AngleAxis(turnAngleSign * shorteningOf_straightLineInsideCone_asAngleDeg, turnAxis_ofVectorCircled.direction_normalized); + Vector3 circleCenter_to_startOfDrawnCircleLineInsideStartCone = rotationToStartOfDrawnCircleLineInsideStartCone * circleCenter_to_start; + float angleDeg_ofLinePartThatIsInsideCone = Vector3.Angle(circleCenter_to_endOfUnconedPart, circleCenter_to_endOfDrawnCircleLineInsideEndCone); + if (angleDeg_ofLinePartThatIsInsideCone > 0.5f) + { + DrawBasics.LineCircled(circleCenter, circleCenter_to_endOfUnconedPart, circleCenter_to_endOfDrawnCircleLineInsideEndCone, color, radius, lineWidth, null, false, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, 0.0f, textAnchor, durationInSec, hiddenByNearerObjects); + if (pointerAtBothSides) + { + DrawBasics.LineCircled(circleCenter, circleCenter_to_startOfDrawnCircleLineInsideStartCone, circleCenter_to_startOfUnconedPart, color, radius, lineWidth, null, false, skipFallbackDisplayOfZeroAngles, flattenThickRoundLineIntoCirclePlane, 0.0f, textAnchor, durationInSec, hiddenByNearerObjects); + } + } + + Vector3 circleCenter_to_end = Get_circleCenter_to_end(turnAngleDegCC, circleCenter_to_start, turnAxis_ofVectorCircled.direction_normalized); + Vector3 directionOfEndCone = circleCenter_to_end - circleCenter_to_endOfUnconedPart; + Vector3 upOfConeBaseRect = circleCenter_to_end + circleCenter_to_endOfUnconedPart; + float coneAngleDeg_perpToCirclePlane = flattenThickRoundLineIntoCirclePlane ? 0.0f : coneAngleDeg; + + Color color_ofPointers = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, alphaFactorForPointers); + DrawShapes.ConeFilled(circleCenter + circleCenter_to_end, coneLength, -directionOfEndCone, upOfConeBaseRect, coneAngleDeg, coneAngleDeg_perpToCirclePlane, color_ofPointers, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + float angleDeg_ofLineWidthCone = 0.0f; + float angleDeg_ofLineWidthCone_perpToCirclePlane = 0.0f; + if (isThinLine == false) + { + angleDeg_ofLineWidthCone = Mathf.Rad2Deg * 2.0f * Mathf.Atan(0.5f * lineWidth / Mathf.Max(shorteningOf_straightLineInsideCone, 0.00001f)); + angleDeg_ofLineWidthCone = Mathf.Min(angleDeg_ofLineWidthCone, coneAngleDeg); + angleDeg_ofLineWidthCone_perpToCirclePlane = flattenThickRoundLineIntoCirclePlane ? 0.0f : angleDeg_ofLineWidthCone; + DrawShapes.ConeFilled(circleCenter + circleCenter_to_end, shorteningOf_straightLineInsideCone, circleCenter_to_endOfDrawnCircleLineInsideEndCone - circleCenter_to_end, circleCenter_to_endOfDrawnCircleLineInsideEndCone, angleDeg_ofLineWidthCone, angleDeg_ofLineWidthCone_perpToCirclePlane, color_ofPointers, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + + if (pointerAtBothSides) + { + Vector3 directionOfStartCone = circleCenter_to_start - circleCenter_to_startOfUnconedPart; + upOfConeBaseRect = circleCenter_to_start + circleCenter_to_startOfUnconedPart; + DrawShapes.ConeFilled(circleCenter + circleCenter_to_start, coneLength, -directionOfStartCone, upOfConeBaseRect, coneAngleDeg, coneAngleDeg_perpToCirclePlane, color_ofPointers, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + if (isThinLine == false) + { + DrawShapes.ConeFilled(circleCenter + circleCenter_to_start, shorteningOf_straightLineInsideCone, circleCenter_to_startOfDrawnCircleLineInsideStartCone - circleCenter_to_start, circleCenter_to_startOfDrawnCircleLineInsideStartCone, angleDeg_ofLineWidthCone, angleDeg_ofLineWidthCone_perpToCirclePlane, color_ofPointers, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + } + + } + + public static Vector3 Get_circleCenter_to_end(float turnAngleDeg, Vector3 circleCenter_to_start, Vector3 turnAxis) + { + Vector3 circleCenter_to_end; + if (turnAngleDeg >= 180.0f) + { + Quaternion rotation90DegIntoCorrectDir = Quaternion.AngleAxis(90.0f, turnAxis); + circleCenter_to_end = rotation90DegIntoCorrectDir * circleCenter_to_start; + circleCenter_to_end = rotation90DegIntoCorrectDir * circleCenter_to_end; + Quaternion rotationOfHighterThan180Part = Quaternion.AngleAxis(turnAngleDeg - 180.0f, turnAxis); + circleCenter_to_end = rotationOfHighterThan180Part * circleCenter_to_end; + } + else + { + if (turnAngleDeg <= (-180.0f)) + { + Quaternion rotation90DegIntoCorrectDir = Quaternion.AngleAxis(-90.0f, turnAxis); + circleCenter_to_end = rotation90DegIntoCorrectDir * circleCenter_to_start; + circleCenter_to_end = rotation90DegIntoCorrectDir * circleCenter_to_end; + Quaternion rotationOfHighterThan180Part = Quaternion.AngleAxis(turnAngleDeg + 180.0f, turnAxis); + circleCenter_to_end = rotationOfHighterThan180Part * circleCenter_to_end; + } + else + { + Quaternion rotation_fromStartToEnd = Quaternion.AngleAxis(turnAngleDeg, turnAxis); + circleCenter_to_end = rotation_fromStartToEnd * circleCenter_to_start; + } + } + return circleCenter_to_end; + } + + static InternalDXXL_Plane circlePlane = new InternalDXXL_Plane(); + static float LineCircledBelow180Deg(Vector3 circleCenter, Vector3 circleCenter_to_start, out Vector3 circleCenter_towards_end_normalized, float turnAngleDeg, Vector3 turnAxis, Color color, float forceRadius, float width, bool flattenThickRoundLineIntoCirclePlane, float durationInSec, bool hiddenByNearerObjects) + { + //returns "usedRadius" + circleCenter_towards_end_normalized = circleCenter_to_start; + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0.0f; } + + if ((turnAngleDeg > (-0.001f)) && (turnAngleDeg < 0.001f)) //-> it prooved not enough here to only check for "ApproxZero", even a threshold of "0.0001f" was too tight. It triggered errorcode-21. + { + return circleCenter_to_start.magnitude; + } + + if (turnAngleDeg >= 180.0f) + { + return circleCenter_to_start.magnitude; + } + + if (turnAngleDeg <= -180.0f) + { + return circleCenter_to_start.magnitude; + } + + Vector3 circleCenter_to_start_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(circleCenter_to_start, out float circleCenter_to_start_magnitude); + circleCenter_towards_end_normalized = circleCenter_to_start_normalized; //-> initial value that will get updated below for each subSegment + + float radius; + Vector3 circleLineStartPos; + if (UtilitiesDXXL_Math.ApproximatelyZero(forceRadius)) + { + radius = circleCenter_to_start_magnitude; + circleLineStartPos = circleCenter + circleCenter_to_start; + } + else + { + radius = forceRadius; + circleLineStartPos = circleCenter + circleCenter_to_start_normalized * radius; + } + + Quaternion rotationFromStartToEnd = Quaternion.AngleAxis(turnAngleDeg, turnAxis); + float segmentsPerCircleDegree = 16.0f / 90.0f; + int subSegments = Mathf.CeilToInt(5.0f + segmentsPerCircleDegree * Mathf.Abs(turnAngleDeg)); + float subSegmentsFloat = (float)subSegments; + + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + if (width < DrawBasics.thinestPossibleNonZeroWidthLine) { width = 0.0f; } + bool isThinLine = UtilitiesDXXL_Math.ApproximatelyZero(width); + + float progress0to1 = 1.0f / subSegmentsFloat; + Quaternion rotation_fromCirceStart_toEndOfCurrSegment = Quaternion.Lerp(Quaternion.identity, rotationFromStartToEnd, progress0to1); + Vector3 circleCenter_to_endOfCurrSegment_normalized = rotation_fromCirceStart_toEndOfCurrSegment * circleCenter_to_start_normalized; + Vector3 endPosOfSegment = circleCenter + circleCenter_to_endOfCurrSegment_normalized * radius; + + if (flattenThickRoundLineIntoCirclePlane) + { + //-> This is the only case that needs an amplitude plane. + //-> Precalced here so it has not be done repeatedly for every segment. + circlePlane.Recreate(circleCenter, turnAxis); + } + + UtilitiesDXXL_DrawBasics.DrawCircleSegment(isThinLine, circleLineStartPos, endPosOfSegment, color, width, durationInSec, hiddenByNearerObjects, flattenThickRoundLineIntoCirclePlane, circlePlane); + Vector3 endPosOfPrevSegment = endPosOfSegment; + + for (int i = 1; i < subSegments; i++) + { + progress0to1 = (1.0f + i) / subSegmentsFloat; + rotation_fromCirceStart_toEndOfCurrSegment = Quaternion.Lerp(Quaternion.identity, rotationFromStartToEnd, progress0to1); + circleCenter_to_endOfCurrSegment_normalized = rotation_fromCirceStart_toEndOfCurrSegment * circleCenter_to_start_normalized; + circleCenter_towards_end_normalized = circleCenter_to_endOfCurrSegment_normalized; + endPosOfSegment = circleCenter + circleCenter_to_endOfCurrSegment_normalized * radius; + UtilitiesDXXL_DrawBasics.DrawCircleSegment(isThinLine, endPosOfPrevSegment, endPosOfSegment, color, width, durationInSec, hiddenByNearerObjects, flattenThickRoundLineIntoCirclePlane, circlePlane); + endPosOfPrevSegment = endPosOfSegment; + } + + return radius; + } + + static float CircleSegmentBelow180Deg(bool applyOffsetForRadialLinesToIndicateAnglesOver360deg, bool drawStraighRadialLineAtSegmentStart, bool drawStraighRadialLineAtSegmentEnd, Vector3 circleCenter, Vector3 circleCenter_to_startOnPerimeter, out Vector3 circleCenter_towards_endPosOnPerimeter_normalized, float turnAngleDeg, Vector3 turnAxis, float radiusPortionWhereDrawFillStarts, Color color, float forceRadius, float fillDensity, float durationInSec, bool hiddenByNearerObjects) + { + //returns "radiusOfTheOuterEndOfTheWidenedCircledLine" + circleCenter_towards_endPosOnPerimeter_normalized = circleCenter_to_startOnPerimeter; + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0.0f; } + + if ((turnAngleDeg > (-0.001f)) && (turnAngleDeg < 0.001f)) //-> it prooved not enough here to only check for "ApproxZero", even a threshold of "0.0001f" was too tight. It triggered errorcode-21. + { + return circleCenter_to_startOnPerimeter.magnitude; + } + + if (turnAngleDeg >= 180.0f) + { + return circleCenter_to_startOnPerimeter.magnitude; + } + + if (turnAngleDeg <= -180.0f) + { + return circleCenter_to_startOnPerimeter.magnitude; + } + + Vector3 circleCenter_towards_startOnPerimeter_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(circleCenter_to_startOnPerimeter, out float circleCenter_to_start_magnitude); + circleCenter_towards_endPosOnPerimeter_normalized = circleCenter_towards_startOnPerimeter_normalized; //-> initial value that will get updated below for each subSegment + + float min_radiusPortionWhereDrawFillStarts = 0.02f; + bool drawFill_startsAtCircleCenter = (radiusPortionWhereDrawFillStarts < min_radiusPortionWhereDrawFillStarts); + radiusPortionWhereDrawFillStarts = Mathf.Clamp(radiusPortionWhereDrawFillStarts, min_radiusPortionWhereDrawFillStarts, 0.99f); //-> the case where "radiusPortionWhereDrawFillStarts" is "1" doesn't arrive here, but has already been treated otherwise + + float radiusOfTheOuterEndOfTheWidenedCircledLine; + Vector3 startPosOfSegment_onRoundOuterBoundaryLine; + if (UtilitiesDXXL_Math.ApproximatelyZero(forceRadius)) + { + radiusOfTheOuterEndOfTheWidenedCircledLine = circleCenter_to_start_magnitude; + startPosOfSegment_onRoundOuterBoundaryLine = circleCenter + circleCenter_to_startOnPerimeter; + } + else + { + radiusOfTheOuterEndOfTheWidenedCircledLine = forceRadius; + startPosOfSegment_onRoundOuterBoundaryLine = circleCenter + circleCenter_towards_startOnPerimeter_normalized * radiusOfTheOuterEndOfTheWidenedCircledLine; + } + + Quaternion rotationFromStartToEnd = Quaternion.AngleAxis(turnAngleDeg, turnAxis); + float segmentsPerCircleDegree = fillDensity * (16.0f / 90.0f); + segmentsPerCircleDegree = Mathf.Max(0.0f, segmentsPerCircleDegree); + int subSegments = Mathf.CeilToInt(5.0f + segmentsPerCircleDegree * Mathf.Abs(turnAngleDeg)); + float subSegmentsFloat = (float)subSegments; + + float offsetForRadialLinesIndicatingAnglesOver360deg = applyOffsetForRadialLinesToIndicateAnglesOver360deg ? (-0.5f) : 0.0f; + float progress0to1 = (1.0f + offsetForRadialLinesIndicatingAnglesOver360deg) / subSegmentsFloat; + Quaternion rotation_fromCirceStart_toEndOfCurrSegment = Quaternion.Lerp(Quaternion.identity, rotationFromStartToEnd, progress0to1); + Vector3 circleCenter_to_endOfCurrSegment_normalized = rotation_fromCirceStart_toEndOfCurrSegment * circleCenter_towards_startOnPerimeter_normalized; + Vector3 endPosOfSegment_forRoundOuterBoundaryLine = circleCenter + circleCenter_to_endOfCurrSegment_normalized * radiusOfTheOuterEndOfTheWidenedCircledLine; + + Vector3 startPosOfSegment_onRoundInnerBoundaryLine = Get_posOnRoundInnerBoundaryLine(drawFill_startsAtCircleCenter, circleCenter, startPosOfSegment_onRoundOuterBoundaryLine, radiusPortionWhereDrawFillStarts); + Vector3 endPosOfSegment_forRoundInnerBoundaryLine = Get_posOnRoundInnerBoundaryLine(drawFill_startsAtCircleCenter, circleCenter, endPosOfSegment_forRoundOuterBoundaryLine, radiusPortionWhereDrawFillStarts); + + UtilitiesDXXL_DrawBasics.DrawCircleSegment(true, startPosOfSegment_onRoundOuterBoundaryLine, endPosOfSegment_forRoundOuterBoundaryLine, color, 0.0f, durationInSec, hiddenByNearerObjects, false, null); + + if (drawFill_startsAtCircleCenter == false) + { + UtilitiesDXXL_DrawBasics.DrawCircleSegment(true, startPosOfSegment_onRoundInnerBoundaryLine, endPosOfSegment_forRoundInnerBoundaryLine, color, 0.0f, durationInSec, hiddenByNearerObjects, false, null); + } + + if (drawStraighRadialLineAtSegmentStart) + { + DrawBasics.Line(startPosOfSegment_onRoundInnerBoundaryLine, startPosOfSegment_onRoundOuterBoundaryLine, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + startPosOfSegment_onRoundOuterBoundaryLine = endPosOfSegment_forRoundOuterBoundaryLine; + startPosOfSegment_onRoundInnerBoundaryLine = endPosOfSegment_forRoundInnerBoundaryLine; + + for (int i = 1; i < subSegments; i++) + { + bool isLastSegment = (i == (subSegments - 1)); + float used_offsetForRadialLinesIndicatingAnglesOver360deg = isLastSegment ? 0.0f : offsetForRadialLinesIndicatingAnglesOver360deg; + progress0to1 = (1.0f + i + used_offsetForRadialLinesIndicatingAnglesOver360deg) / subSegmentsFloat; + rotation_fromCirceStart_toEndOfCurrSegment = Quaternion.Lerp(Quaternion.identity, rotationFromStartToEnd, progress0to1); + circleCenter_to_endOfCurrSegment_normalized = rotation_fromCirceStart_toEndOfCurrSegment * circleCenter_towards_startOnPerimeter_normalized; + circleCenter_towards_endPosOnPerimeter_normalized = circleCenter_to_endOfCurrSegment_normalized; + endPosOfSegment_forRoundOuterBoundaryLine = circleCenter + circleCenter_to_endOfCurrSegment_normalized * radiusOfTheOuterEndOfTheWidenedCircledLine; + endPosOfSegment_forRoundInnerBoundaryLine = Get_posOnRoundInnerBoundaryLine(drawFill_startsAtCircleCenter, circleCenter, endPosOfSegment_forRoundOuterBoundaryLine, radiusPortionWhereDrawFillStarts); + + UtilitiesDXXL_DrawBasics.DrawCircleSegment(true, startPosOfSegment_onRoundOuterBoundaryLine, endPosOfSegment_forRoundOuterBoundaryLine, color, 0.0f, durationInSec, hiddenByNearerObjects, false, null); + + if (drawFill_startsAtCircleCenter == false) + { + UtilitiesDXXL_DrawBasics.DrawCircleSegment(true, startPosOfSegment_onRoundInnerBoundaryLine, endPosOfSegment_forRoundInnerBoundaryLine, color, 0.0f, durationInSec, hiddenByNearerObjects, false, null); + } + + DrawBasics.Line(startPosOfSegment_onRoundInnerBoundaryLine, startPosOfSegment_onRoundOuterBoundaryLine, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + if (isLastSegment) + { + if (drawStraighRadialLineAtSegmentEnd) + { + DrawBasics.Line(endPosOfSegment_forRoundInnerBoundaryLine, endPosOfSegment_forRoundOuterBoundaryLine, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + + startPosOfSegment_onRoundOuterBoundaryLine = endPosOfSegment_forRoundOuterBoundaryLine; + startPosOfSegment_onRoundInnerBoundaryLine = endPosOfSegment_forRoundInnerBoundaryLine; + } + + return radiusOfTheOuterEndOfTheWidenedCircledLine; + } + + static Vector3 Get_posOnRoundInnerBoundaryLine(bool drawFill_startsAtCircleCenter, Vector3 circleCenter, Vector3 endPosOnPerimeter, float radiusPortionWhereDrawFillStarts) + { + if (drawFill_startsAtCircleCenter) + { + return circleCenter; + } + else + { + Vector3 circleCenter_to_endPosOnPerimeter = (endPosOnPerimeter - circleCenter); + return (circleCenter + circleCenter_to_endPosOnPerimeter * radiusPortionWhereDrawFillStarts); + } + } + + public static void LineCircledScreenspace(Camera targetCamera, Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color, float width_relToViewportHeight, string text, bool skipFallbackDisplayOfZeroAngles, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec, bool drawSeparateFullCircle_forAnglesBiggerThan360) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(turnAngleDegCC, "turnAngleDegCC")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_relToViewportHeight, "width_relToViewportHeight")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter, "circleCenter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPos, "startPos")) { return; } + + width_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(width_relToViewportHeight); + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(startPos, circleCenter)) + { + UtilitiesDXXL_Screenspace.PointFallback(targetCamera, circleCenter, "[ LineCircledScreenspace with radius of 0]
" + text, color, width_relToViewportHeight, durationInSec); + return; + } + + Vector3 circleCenter_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, circleCenter, false); + Vector3 startPos_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, startPos, false); + Vector3 circleCenter_to_start_worldSpace = startPos_worldSpace - circleCenter_worldSpace; + float width_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(width_relToViewportHeight) == false) + { + width_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, startPos, true, width_relToViewportHeight); + } + + float unlooped_turnAngleDegCC = turnAngleDegCC; + bool unloopedAngleIsOutside_m360_to_p360 = CheckIfAngleIsOutside_m360_to_p360(unlooped_turnAngleDegCC); + if (drawSeparateFullCircle_forAnglesBiggerThan360) //-> endless regression loops are actually already prevented by "turnAngleDegCC_ofAdditional360degRing = 360.0f", but it's better to additionally protect against float calculation/comparison imprecsion herewith + { + if (unloopedAngleIsOutside_m360_to_p360) + { + float turnAngleDegCC_ofAdditional360degRing = 360.0f; + string text_ofAdditional360degRing = null; + bool drawSeparateFullCircle_forAnglesBiggerThan360_onceMore = false; + LineCircledScreenspace(targetCamera, startPos, circleCenter, turnAngleDegCC_ofAdditional360degRing, color, width_relToViewportHeight, text_ofAdditional360degRing, true, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, drawSeparateFullCircle_forAnglesBiggerThan360_onceMore); + } + } + + turnAngleDegCC = LoopAngleIntoSpanFrom_m360_to_p360(unlooped_turnAngleDegCC); + if (UtilitiesDXXL_Math.ApproximatelyZero(turnAngleDegCC)) + { + if (unloopedAngleIsOutside_m360_to_p360) + { + //-> multiples of 360° arrive here, like +/-720° or +/-1080° + turnAngleDegCC = 359.99f * Mathf.Sign(unlooped_turnAngleDegCC); + } + else + { + if (skipFallbackDisplayOfZeroAngles == false) + { + DrawScreenspace.Vector(targetCamera, circleCenter, startPos, color, width_relToViewportHeight, "[ LineCircledScreenSpace with angle of 0°]
" + text, 0.05f, false, false, 0.0f, durationInSec); + } + return; + } + } + + Vector3 circleCenter_towards_end_normalized; + if (turnAngleDegCC >= 180.0f) + { + LineCircledBelow180Deg(circleCenter_worldSpace, circleCenter_to_start_worldSpace, out circleCenter_towards_end_normalized, 90.0f, targetCamera.transform.forward, color, 0.0f, width_worldSpace, true, durationInSec, false); + LineCircledBelow180Deg(circleCenter_worldSpace, -circleCenter_to_start_worldSpace, out circleCenter_towards_end_normalized, -90.0f, targetCamera.transform.forward, color, 0.0f, width_worldSpace, true, durationInSec, false); + LineCircledBelow180Deg(circleCenter_worldSpace, -circleCenter_to_start_worldSpace, out circleCenter_towards_end_normalized, turnAngleDegCC - 180.0f, targetCamera.transform.forward, color, 0.0f, width_worldSpace, true, durationInSec, false); + } + else + { + if (turnAngleDegCC <= (-180.0f)) + { + LineCircledBelow180Deg(circleCenter_worldSpace, circleCenter_to_start_worldSpace, out circleCenter_towards_end_normalized, -90.0f, targetCamera.transform.forward, color, 0.0f, width_worldSpace, true, durationInSec, false); + LineCircledBelow180Deg(circleCenter_worldSpace, -circleCenter_to_start_worldSpace, out circleCenter_towards_end_normalized, 90.0f, targetCamera.transform.forward, color, 0.0f, width_worldSpace, true, durationInSec, false); + LineCircledBelow180Deg(circleCenter_worldSpace, -circleCenter_to_start_worldSpace, out circleCenter_towards_end_normalized, turnAngleDegCC + 180.0f, targetCamera.transform.forward, color, 0.0f, width_worldSpace, true, durationInSec, false); + } + else + { + LineCircledBelow180Deg(circleCenter_worldSpace, circleCenter_to_start_worldSpace, out circleCenter_towards_end_normalized, turnAngleDegCC, targetCamera.transform.forward, color, 0.0f, width_worldSpace, true, durationInSec, false); + } + } + + TryDrawText_atLineCircledScreenspace(targetCamera, startPos, circleCenter, turnAngleDegCC, color, width_relToViewportHeight, text, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec); + } + + public static void CircleSegmentScreenspace(Camera targetCamera, Vector2 startPosOnPerimeter, Vector2 circleCenter, float turnAngleDegCC, Color color, string text, float radiusPortionWhereDrawFillStarts, bool skipFallbackDisplayOfZeroAngles, float fillDensity, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec, bool drawSeparateFullCircle_forAnglesBiggerThan360) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(turnAngleDegCC, "turnAngleDegCC")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radiusPortionWhereDrawFillStarts, "radiusPortionWhereDrawFillStarts")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(fillDensity, "fillDensity")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter, "circleCenter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPosOnPerimeter, "startPosOnPerimeter")) { return; } + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(startPosOnPerimeter, circleCenter)) + { + UtilitiesDXXL_Screenspace.PointFallback(targetCamera, circleCenter, "[ CircleSegmentScreenspace with radius of 0]
" + text, color, 0.0f, durationInSec); + return; + } + + if (radiusPortionWhereDrawFillStarts >= 1.0f) + { + LineCircledScreenspace(targetCamera, startPosOnPerimeter, circleCenter, turnAngleDegCC, color, 0.0f, text, skipFallbackDisplayOfZeroAngles, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, drawSeparateFullCircle_forAnglesBiggerThan360); + return; + } + + Vector3 circleCenter_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, circleCenter, false); + Vector3 startPosOnPerimeter_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, startPosOnPerimeter, false); + Vector3 circleCenter_to_startPosOnPerimeter_worldSpace = startPosOnPerimeter_worldSpace - circleCenter_worldSpace; + + float unlooped_turnAngleDegCC = turnAngleDegCC; + bool unloopedAngleIsOutside_m360_to_p360 = CheckIfAngleIsOutside_m360_to_p360(unlooped_turnAngleDegCC); + bool applyOffsetForRadialLinesToIndicateAnglesOver360deg = false; + if (drawSeparateFullCircle_forAnglesBiggerThan360) //-> endless regression loops are actually already prevented by "turnAngleDegCC_ofAdditional360degRing = 360.0f", but it's better to additionally protect against float calculation/comparison imprecsion herewith + { + if (unloopedAngleIsOutside_m360_to_p360) + { + float turnAngleDegCC_ofAdditional360degRing = 360.0f; + string text_ofAdditional360degRing = null; + bool drawSeparateFullCircle_forAnglesBiggerThan360_onceMore = false; + CircleSegmentScreenspace(targetCamera, startPosOnPerimeter, circleCenter, turnAngleDegCC_ofAdditional360degRing, color, text_ofAdditional360degRing, radiusPortionWhereDrawFillStarts, true, fillDensity, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec, drawSeparateFullCircle_forAnglesBiggerThan360_onceMore); + applyOffsetForRadialLinesToIndicateAnglesOver360deg = true; + } + } + + turnAngleDegCC = LoopAngleIntoSpanFrom_m360_to_p360(unlooped_turnAngleDegCC); + if (UtilitiesDXXL_Math.ApproximatelyZero(turnAngleDegCC)) + { + if (unloopedAngleIsOutside_m360_to_p360) + { + //-> multiples of 360° arrive here, like +/-720° or +/-1080° + turnAngleDegCC = 359.99f * Mathf.Sign(unlooped_turnAngleDegCC); + } + else + { + if (skipFallbackDisplayOfZeroAngles == false) + { + DrawScreenspace.Vector(targetCamera, circleCenter, startPosOnPerimeter, color, 0.0f, "[ CircleSegmentScreenspace with angle of 0°]
" + text, 0.05f, false, false, 0.0f, durationInSec); + } + return; + } + } + + Vector3 circleCenter_towards_endPosOnPerimeter_normalized; + if (turnAngleDegCC >= 180.0f) + { + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, true, true, circleCenter_worldSpace, circleCenter_to_startPosOnPerimeter_worldSpace, out circleCenter_towards_endPosOnPerimeter_normalized, 90.0f, targetCamera.transform.forward, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, false); + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, true, false, circleCenter_worldSpace, -circleCenter_to_startPosOnPerimeter_worldSpace, out circleCenter_towards_endPosOnPerimeter_normalized, -90.0f, targetCamera.transform.forward, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, false); + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, false, true, circleCenter_worldSpace, -circleCenter_to_startPosOnPerimeter_worldSpace, out circleCenter_towards_endPosOnPerimeter_normalized, turnAngleDegCC - 180.0f, targetCamera.transform.forward, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, false); + } + else + { + if (turnAngleDegCC <= (-180.0f)) + { + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, true, true, circleCenter_worldSpace, circleCenter_to_startPosOnPerimeter_worldSpace, out circleCenter_towards_endPosOnPerimeter_normalized, -90.0f, targetCamera.transform.forward, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, false); + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, true, false, circleCenter_worldSpace, -circleCenter_to_startPosOnPerimeter_worldSpace, out circleCenter_towards_endPosOnPerimeter_normalized, 90.0f, targetCamera.transform.forward, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, false); + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, false, true, circleCenter_worldSpace, -circleCenter_to_startPosOnPerimeter_worldSpace, out circleCenter_towards_endPosOnPerimeter_normalized, turnAngleDegCC + 180.0f, targetCamera.transform.forward, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, false); + } + else + { + CircleSegmentBelow180Deg(applyOffsetForRadialLinesToIndicateAnglesOver360deg, true, true, circleCenter_worldSpace, circleCenter_to_startPosOnPerimeter_worldSpace, out circleCenter_towards_endPosOnPerimeter_normalized, turnAngleDegCC, targetCamera.transform.forward, radiusPortionWhereDrawFillStarts, color, 0.0f, fillDensity, durationInSec, false); + } + } + + TryDrawText_atLineCircledScreenspace(targetCamera, startPosOnPerimeter, circleCenter, turnAngleDegCC, color, 0.0f, text, minAngleDeg_withoutTextLineBreak, textAnchor, durationInSec); + } + + static void TryDrawText_atLineCircledScreenspace(Camera targetCamera, Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color, float width_relToViewportHeight, string text, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec) + { + if (text != null && text != "") + { + Vector2 circleCenter_to_start_inWarpedViewportSpace = startPos - circleCenter; + Vector2 circleCenter_to_start_lookingLikeTheVersionInWarpedSpace_butInUnitsOfTheUnwarpedViewportSpace = DrawScreenspace.DirectionInUnitsOfWarpedSpace_to_sameLookingDirectionInUnitsOfUnwarpedSpace(circleCenter_to_start_inWarpedViewportSpace, targetCamera); + float lineRadius_relToViewportHeight = circleCenter_to_start_lookingLikeTheVersionInWarpedSpace_butInUnitsOfTheUnwarpedViewportSpace.magnitude; + float textRadius_relToViewportHeight = 1.05f * lineRadius_relToViewportHeight + 0.5f * width_relToViewportHeight; + float textSize_relToViewportHeight = 0.1f * textRadius_relToViewportHeight; + textSize_relToViewportHeight = Mathf.Max(textSize_relToViewportHeight, DrawScreenspace.minTextSize_relToViewportHeight); + + Vector3 textsInitialUp; + float autoLineBreakAngleDeg; + if (turnAngleDegCC > 0.0f) + { + textsInitialUp = Quaternion.AngleAxis(turnAngleDegCC, Vector3.forward) * circleCenter_to_start_lookingLikeTheVersionInWarpedSpace_butInUnitsOfTheUnwarpedViewportSpace; + autoLineBreakAngleDeg = turnAngleDegCC; + } + else + { + textsInitialUp = circleCenter_to_start_lookingLikeTheVersionInWarpedSpace_butInUnitsOfTheUnwarpedViewportSpace; + autoLineBreakAngleDeg = -turnAngleDegCC; + } + + if (minAngleDeg_withoutTextLineBreak > 0.0f) + { + autoLineBreakAngleDeg = Mathf.Max(autoLineBreakAngleDeg, minAngleDeg_withoutTextLineBreak); + } + + UtilitiesDXXL_Text.WriteOnCircleScreenspace(targetCamera, text, circleCenter, textRadius_relToViewportHeight, color, textSize_relToViewportHeight, textsInitialUp, textAnchor, autoLineBreakAngleDeg, durationInSec, false); + } + } + + public static void VectorCircledScreenspace(Camera targetCamera, Vector2 startPos, Vector2 circleCenter, float turnAngleDegCC, Color color, float lineWidth_relToViewportHeight, string text, float coneLength_relToViewportHeight, bool skipFallbackDisplayOfZeroAngles, bool pointerAtBothSides, float minAngleDeg_withoutTextLineBreak, DrawText.TextAnchorCircledDXXL textAnchor, float durationInSec) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(turnAngleDegCC, "turnAngleDegCC")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth_relToViewportHeight, "lineWidth_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(coneLength_relToViewportHeight, "coneLength_relToViewportHeight")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenter, "circleCenter")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startPos, "startPos")) { return; } + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(startPos, circleCenter)) + { + UtilitiesDXXL_Screenspace.PointFallback(targetCamera, circleCenter, "[ VectorCircledScreenspace with radius of 0]
" + text, color, lineWidth_relToViewportHeight, durationInSec); + return; + } + + Vector3 circleCenter_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, circleCenter, false); + Vector3 startPos_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, startPos, false); + + lineWidth_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth_relToViewportHeight); + float lineWidth_worldSpace; + bool isThinLine; + if (UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_relToViewportHeight)) + { + isThinLine = true; + lineWidth_worldSpace = 0.0f; + } + else + { + isThinLine = false; + lineWidth_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, startPos, true, lineWidth_relToViewportHeight); + } + + float unlooped_turnAngleDegCC = turnAngleDegCC; + bool unloopedAngleIsOutside_m360_to_p360 = CheckIfAngleIsOutside_m360_to_p360(unlooped_turnAngleDegCC); + if (unloopedAngleIsOutside_m360_to_p360) + { + float turnAngleDegCC_ofAdditional360degRing = 360.0f; + string text_ofAdditional360degRing = null; + bool drawSeparateFullCircle_forAnglesBiggerThan360_onceMore = false; + LineCircled(startPos_worldSpace, circleCenter_worldSpace, targetCamera.transform.forward, turnAngleDegCC_ofAdditional360degRing, color, lineWidth_worldSpace, text_ofAdditional360degRing, skipFallbackDisplayOfZeroAngles, true, durationInSec, false, true, minAngleDeg_withoutTextLineBreak, textAnchor, drawSeparateFullCircle_forAnglesBiggerThan360_onceMore); + } + + turnAngleDegCC = LoopAngleIntoSpanFrom_m360_to_p360(turnAngleDegCC); + if (UtilitiesDXXL_Math.ApproximatelyZero(turnAngleDegCC)) + { + if (unloopedAngleIsOutside_m360_to_p360) + { + //-> multiples of 360° arrive here, like +/-720° or +/-1080° + turnAngleDegCC = 359.99f * Mathf.Sign(unlooped_turnAngleDegCC); + } + else + { + if (skipFallbackDisplayOfZeroAngles == false) + { + DrawScreenspace.Vector(targetCamera, circleCenter, startPos, color, lineWidth_relToViewportHeight, "[ radius line of VectorCircledScreenspace with angle of 0°]
" + text, 0.05f, false, false, 0.0f, durationInSec); + } + return; + } + } + + float absTurnAngleDeg = Mathf.Abs(turnAngleDegCC); + float turnAngleSign = Mathf.Sign(turnAngleDegCC); + Vector3 circleCenter_to_start_worldSpace = startPos_worldSpace - circleCenter_worldSpace; + float circleCenter_to_start_worldSpace_magnitude = circleCenter_to_start_worldSpace.magnitude; + float radius_worldSpace = circleCenter_to_start_worldSpace_magnitude; + float perimeterOf360deg_worldSpace = 2.0f * radius_worldSpace * Mathf.PI; + float coneLength_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, startPos, true, coneLength_relToViewportHeight); + float minConeLength_worldSpace = (0.01f * absTurnAngleDeg / 360.0f) * perimeterOf360deg_worldSpace; + float maxConeLength_worldSpace = (0.45f * absTurnAngleDeg / 360.0f) * perimeterOf360deg_worldSpace; + float maxConeLength_asAngleDeg = 45.0f; + float maxConeLength_fromAngleLimit_worldSpace = (maxConeLength_asAngleDeg / 360.0f) * perimeterOf360deg_worldSpace; + maxConeLength_worldSpace = Mathf.Min(maxConeLength_worldSpace, maxConeLength_fromAngleLimit_worldSpace); + coneLength_worldSpace = Mathf.Clamp(coneLength_worldSpace, minConeLength_worldSpace, maxConeLength_worldSpace); + float coneLength_asAngleDeg = 360.0f * (coneLength_worldSpace / perimeterOf360deg_worldSpace); + float coneAngleDeg = 25.0f; + if (isThinLine == false) + { + float coneSize_to_lineWidth_scaler = 1.2f; + float minConeAngleDeg = 2.0f * Mathf.Rad2Deg * Mathf.Atan(coneSize_to_lineWidth_scaler * lineWidth_worldSpace / coneLength_worldSpace); + coneAngleDeg = Mathf.Max(coneAngleDeg, minConeAngleDeg); + } + + float shorteningOf_straightLineInsideCone_worldSpace = 0.0f; + if (isThinLine == false) + { + shorteningOf_straightLineInsideCone_worldSpace = (0.5f * lineWidth_worldSpace) / Mathf.Tan(Mathf.Deg2Rad * 0.5f * coneAngleDeg); + shorteningOf_straightLineInsideCone_worldSpace = 2.0f * shorteningOf_straightLineInsideCone_worldSpace; //solves: curvedLine is not parallel/aligned to coneDir and therefore intersects the coneSurface + shorteningOf_straightLineInsideCone_worldSpace = Mathf.Min(shorteningOf_straightLineInsideCone_worldSpace, 0.85f * coneLength_worldSpace); + } + float shorteningOf_straightLineInsideCone_asAngleDeg = 360.0f * (shorteningOf_straightLineInsideCone_worldSpace / perimeterOf360deg_worldSpace); + float turnAngleDeg_ofUnconedPart = turnAngleDegCC - (turnAngleSign * coneLength_asAngleDeg); + Vector3 circleCenter_to_startOfUnconedPart_worldSpace = circleCenter_to_start_worldSpace; + if (pointerAtBothSides) + { + turnAngleDeg_ofUnconedPart = turnAngleDegCC - 2.0f * (turnAngleSign * coneLength_asAngleDeg); + Quaternion rotationToStartOfUnconedPart = Quaternion.AngleAxis(turnAngleSign * coneLength_asAngleDeg, targetCamera.transform.forward); + circleCenter_to_startOfUnconedPart_worldSpace = rotationToStartOfUnconedPart * circleCenter_to_start_worldSpace; + } + Quaternion rotationToEndOfUnconedPart = Quaternion.AngleAxis(turnAngleDegCC - (turnAngleSign * coneLength_asAngleDeg), targetCamera.transform.forward); + Vector3 circleCenter_to_endOfUnconedPart_worldSpace = rotationToEndOfUnconedPart * circleCenter_to_start_worldSpace; + + Vector3 circleCenter_to_counterClockwiseEndOfUnconedPart_worldSpace; + float turnAngleDeg_ofUnconedPart_clockwise; + + if (turnAngleDeg_ofUnconedPart > 0.0f) + { + //counterclockwise: + turnAngleDeg_ofUnconedPart_clockwise = -turnAngleDeg_ofUnconedPart; + circleCenter_to_counterClockwiseEndOfUnconedPart_worldSpace = circleCenter_to_endOfUnconedPart_worldSpace; + } + else + { + //clockwise: + turnAngleDeg_ofUnconedPart_clockwise = turnAngleDeg_ofUnconedPart; + circleCenter_to_counterClockwiseEndOfUnconedPart_worldSpace = circleCenter_to_startOfUnconedPart_worldSpace; + } + bool skipTextMirrorInvertedFlipCheck = true; + LineCircled(circleCenter_worldSpace + circleCenter_to_counterClockwiseEndOfUnconedPart_worldSpace, circleCenter_worldSpace, targetCamera.transform.forward, turnAngleDeg_ofUnconedPart_clockwise, color, lineWidth_worldSpace, text, skipFallbackDisplayOfZeroAngles, true, durationInSec, false, skipTextMirrorInvertedFlipCheck, minAngleDeg_withoutTextLineBreak, textAnchor); + + Quaternion rotationToEndOfDrawnCircleLineInsideEndCone = Quaternion.AngleAxis(turnAngleDegCC - (turnAngleSign * shorteningOf_straightLineInsideCone_asAngleDeg), targetCamera.transform.forward); + Vector3 circleCenter_to_endOfDrawnCircleLineInsideEndCone_worldSpace = rotationToEndOfDrawnCircleLineInsideEndCone * circleCenter_to_start_worldSpace; + Quaternion rotationToStartOfDrawnCircleLineInsideStartCone = Quaternion.AngleAxis(turnAngleSign * shorteningOf_straightLineInsideCone_asAngleDeg, targetCamera.transform.forward); + Vector3 circleCenter_to_startOfDrawnCircleLineInsideStartCone_worldSpace = rotationToStartOfDrawnCircleLineInsideStartCone * circleCenter_to_start_worldSpace; + float angleDeg_ofLinePartThatIsInsideCone = Vector3.Angle(circleCenter_to_endOfUnconedPart_worldSpace, circleCenter_to_endOfDrawnCircleLineInsideEndCone_worldSpace); + if (angleDeg_ofLinePartThatIsInsideCone > 0.5f) + { + DrawBasics.LineCircled(circleCenter_worldSpace, circleCenter_to_endOfUnconedPart_worldSpace, circleCenter_to_endOfDrawnCircleLineInsideEndCone_worldSpace, color, radius_worldSpace, lineWidth_worldSpace, null, false, skipFallbackDisplayOfZeroAngles, true, 0.0f, textAnchor, durationInSec, false); + if (pointerAtBothSides) + { + DrawBasics.LineCircled(circleCenter_worldSpace, circleCenter_to_startOfDrawnCircleLineInsideStartCone_worldSpace, circleCenter_to_startOfUnconedPart_worldSpace, color, radius_worldSpace, lineWidth_worldSpace, null, false, skipFallbackDisplayOfZeroAngles, true, 0.0f, textAnchor, durationInSec, false); + } + } + + Vector3 circleCenter_to_end_worldSpace = Get_circleCenter_to_end(turnAngleDegCC, circleCenter_to_start_worldSpace, targetCamera.transform.forward); + Vector3 directionOfEndCone_worldSpace = circleCenter_to_end_worldSpace - circleCenter_to_endOfUnconedPart_worldSpace; + Vector3 upOfConeBaseRect_worldSpace = circleCenter_to_end_worldSpace + circleCenter_to_endOfUnconedPart_worldSpace; + DrawShapes.ConeFilled(circleCenter_worldSpace + circleCenter_to_end_worldSpace, coneLength_worldSpace, -directionOfEndCone_worldSpace, upOfConeBaseRect_worldSpace, coneAngleDeg, 0.0f, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, false); + float angleDeg_ofLineWidthCone = 0.0f; + if (isThinLine == false) + { + angleDeg_ofLineWidthCone = Mathf.Rad2Deg * 2.0f * Mathf.Atan(0.5f * lineWidth_worldSpace / Mathf.Max(shorteningOf_straightLineInsideCone_worldSpace, 0.00001f)); + angleDeg_ofLineWidthCone = Mathf.Min(angleDeg_ofLineWidthCone, coneAngleDeg); + DrawShapes.ConeFilled(circleCenter_worldSpace + circleCenter_to_end_worldSpace, shorteningOf_straightLineInsideCone_worldSpace, circleCenter_to_endOfDrawnCircleLineInsideEndCone_worldSpace - circleCenter_to_end_worldSpace, circleCenter_to_endOfDrawnCircleLineInsideEndCone_worldSpace, angleDeg_ofLineWidthCone, 0.0f, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, false); + } + + if (pointerAtBothSides) + { + Vector3 directionOfStartCone_worldSpace = circleCenter_to_start_worldSpace - circleCenter_to_startOfUnconedPart_worldSpace; + upOfConeBaseRect_worldSpace = circleCenter_to_start_worldSpace + circleCenter_to_startOfUnconedPart_worldSpace; + DrawShapes.ConeFilled(circleCenter_worldSpace + circleCenter_to_start_worldSpace, coneLength_worldSpace, -directionOfStartCone_worldSpace, upOfConeBaseRect_worldSpace, coneAngleDeg, 0.0f, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, false); + if (isThinLine == false) + { + DrawShapes.ConeFilled(circleCenter_worldSpace + circleCenter_to_start_worldSpace, shorteningOf_straightLineInsideCone_worldSpace, circleCenter_to_startOfDrawnCircleLineInsideStartCone_worldSpace - circleCenter_to_start_worldSpace, circleCenter_to_startOfDrawnCircleLineInsideStartCone_worldSpace, angleDeg_ofLineWidthCone, 0.0f, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, false); + } + } + } + + static bool CheckIfAngleIsOutside_m360_to_p360(float angle_preLoop) + { + if (angle_preLoop < (-360.0f)) + { + return true; + } + else + { + if (angle_preLoop > 360.0f) + { + return true; + } + else + { + return false; + } + } + } + + static float LoopAngleIntoSpanFrom_m360_to_p360(float angle_preLoop) + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(angle_preLoop, 360.0f)) + { + return 359.99f; + } + else + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(angle_preLoop, -360.0f)) + { + return (-359.99f); + } + else + { + return UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_mX_to_pX(angle_preLoop, 360.0f); + } + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineCircled.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineCircled.cs.meta new file mode 100644 index 0000000..856be8e --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineCircled.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ea424fd2433351438f51f303fddc77c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineStyles.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineStyles.cs new file mode 100644 index 0000000..a475fbe --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineStyles.cs @@ -0,0 +1,1496 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_LineStyles + { + public static bool logWarningToConsole_forTooSmallPatternScaleFactor = true; + public static float minStylePatternScaleFactor = 0.01f; + + public static float sineLineAmplitude = 0.015f; + public static float spiralLineAmplitude = 0.015f; + public static float zigZagLineAmplitude = 0.02f; + public static float rhombusLineAmplitude = 0.025f; + public static float doubleRhombusLineAmplitude = 0.03f; + public static float electricNoiseLineAmplitude = 0.1f; + public static float electricImpulseLineAmplitude = 0.05f; + public static float impulseDistance_ofElectricImpulseLines = 0.175f; + public static float impulseSqueeze_ofElectricImpulseLines = 0.5f; + public static float freeHandLineAmplitude = 0.05f; + + //lineStyle: arrows + public static bool default_pointersDirAlongAnimationDir = true; + public static bool curr_pointersDirAlongAnimationDir = default_pointersDirAlongAnimationDir; + public static float default_dashLength_forArrowLine = 0.085f; + public static float default_minRatio_for_dashLengthToLineWidth_forArrowLine = 24.0f; + public static float default_spaceToDash_ratio_forArrowLine = 1.8f; + public static float default_minEmptySpacesLength_forArrowLine = 0.105f; + public static float curr_dashLength_forArrowLine = default_dashLength_forArrowLine; + public static float curr_minRatio_for_dashLengthToLineWidth_forArrowLine = default_minRatio_for_dashLengthToLineWidth_forArrowLine; + public static float curr_spaceToDash_ratio_forArrowLine = default_spaceToDash_ratio_forArrowLine; + public static float curr_minEmptySpacesLength_forArrowLine = default_minEmptySpacesLength_forArrowLine; + //lineStyle: alternatingColorStripes + public static float default_dashLength_forAlternatingColorStripesLine = 0.04f; + public static float curr_dashLength_forAlternatingColorStripesLine = default_dashLength_forAlternatingColorStripesLine; + + //saving GC.Alloc: + public static List s_listOfSubLines = new List(); + static List s_addedRangeForListOfSubLines = new List(); + static List s_subLineAnchor_distanceToStart = new List(); + static List s_subLinePoints_projectionOntoStraightMainLine = new List(); + static List s_vectors_fromProjectionOntoMainLine_toSubLinePoints = new List(); + static List s_listOfSubLinesForZigZagsUpSegments = new List(); + static List s_listOfSubLinesForZigZagsDownSegments = new List(); + static List s_listOfSubLinesForZigZagsLeftSegments = new List(); + static List s_listOfSubLinesForZigZagsRightSegments = new List(); + static List s_listOfSubLinesForZigZagsUpAndDownSegments = new List(); + static List s_listOfSubLinesForZigZagsLeftAndRightSegments = new List(); + + public static int RefillListOfSubLines(Vector3 start_unswapped, Vector3 end_unswapped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float lineWidth, out float amplitude, Vector3 amplitudeUp_normalized, float animationSpeed, ref LineAnimationProgress lineAnimationProgressToUpdate, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines, float tensionFactor) + { + //function returns "usedSlotsInListOfSubLines" + //Vectors at i=0 and i=1 define the first subLine, at i=2 and i=3 the second subLine, and so on... + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { amplitude = 0.0f; return 0; } + Vector3 start; + Vector3 end; + if (animationSpeed < 0.0f) + { + //swap start/end, because animation is only fit for moving towards end + //though this has the disadvantage of an uncontinuous animation jump in the moment when the animationSpeed changes it's sign + start = end_unswapped; + end = start_unswapped; + animationSpeed = -animationSpeed; + } + else + { + start = start_unswapped; + end = end_unswapped; + } + + Vector3 startToEnd = end - start; + tensionFactor = tensionFactor * DrawBasics.StylePatternScaleFactor_alongLineDir_ignoringAmplitude; + stylePatternScaleFactor = AdjustPatternScaleFactor(stylePatternScaleFactor, startToEnd, skipPatternEnlargementForLongLines); + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start, end)) //-> callers already ensure this, too + { + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + amplitude = 0.0f; + return 0; + } + + if (style == DrawBasics.LineStyle.solid) + { + UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start, 0); + UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end, 1); + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + amplitude = 0.0f; + return 2; //immediate return because the solid linetype acts as fallback -> This prevents the function from potentially calling itself recursively. + } + + if (style == DrawBasics.LineStyle.invisible) + { + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + amplitude = 0.0f; + return 0; + } + + if (style == DrawBasics.LineStyle.dotted) + { + amplitude = 0.0f; + return GetListOfSubLines_forOneDashLine(0.0015f, 1.0f, 4.0f, 0.02f, stylePatternScaleFactor, skipPatternEnlargementForShortLines, start, end, lineWidth, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.dottedDense) + { + amplitude = 0.0f; + return GetListOfSubLines_forOneDashLine(0.0015f, 1.0f, 2.0f, 0.01f, stylePatternScaleFactor, skipPatternEnlargementForShortLines, start, end, lineWidth, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.dottedWide) + { + amplitude = 0.0f; + return GetListOfSubLines_forOneDashLine(0.0015f, 1.0f, 10.0f, 0.06f, stylePatternScaleFactor, skipPatternEnlargementForShortLines, start, end, lineWidth, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.dashed) + { + amplitude = 0.0f; + return GetListOfSubLines_forOneDashLine(0.01f, 7.0f, 1.0f, 0.02f, stylePatternScaleFactor, skipPatternEnlargementForShortLines, start, end, lineWidth, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.dashedLong) + { + amplitude = 0.0f; + return GetListOfSubLines_forOneDashLine(0.04f, 12.0f, 0.4f, 0.02f, stylePatternScaleFactor, skipPatternEnlargementForShortLines, start, end, lineWidth, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.arrows) + { + amplitude = 0.0f; + return GetListOfSubLines_forOneDashLine(curr_dashLength_forArrowLine, curr_minRatio_for_dashLengthToLineWidth_forArrowLine, curr_spaceToDash_ratio_forArrowLine, curr_minEmptySpacesLength_forArrowLine, stylePatternScaleFactor, skipPatternEnlargementForShortLines, start, end, lineWidth, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.alternatingColorStripes) + { + amplitude = 0.0f; + return GetListOfSubLines_forOneDashLine(curr_dashLength_forAlternatingColorStripesLine, 12.0f, 1.0f, curr_dashLength_forAlternatingColorStripesLine, stylePatternScaleFactor, skipPatternEnlargementForShortLines, start, end, lineWidth, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.dotDash) + { + amplitude = 0.0f; + return GetListOfSubLines_forTwoDashLine(0.0015f * stylePatternScaleFactor, true, 0.005f * stylePatternScaleFactor, 5.0f, 0.7f, 0.02f, skipPatternEnlargementForShortLines, start, end, lineWidth, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.dotDashLong) + { + amplitude = 0.0f; + return GetListOfSubLines_forTwoDashLine(0.0015f * stylePatternScaleFactor, true, 0.015f * stylePatternScaleFactor, 15.0f, 0.23f, 0.02f, skipPatternEnlargementForShortLines, start, end, lineWidth, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.twoDash) + { + amplitude = 0.0f; + return GetListOfSubLines_forTwoDashLine(0.008f * stylePatternScaleFactor, false, 0.018f * stylePatternScaleFactor, 18.0f, 0.23f, 0.02f, skipPatternEnlargementForShortLines, start, end, lineWidth, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.disconnectedAnchors) + { + amplitude = 0.0f; + return GetListOfSubLines_forDisconnectedAnchorLines(start, end, startToEnd, ref lineAnimationProgressToUpdate, animationSpeed, tensionFactor); + } + + if (style == DrawBasics.LineStyle.spiral) + { + amplitude = spiralLineAmplitude * stylePatternScaleFactor; + return GetListOfSubLines_forSpiral(amplitude, amplitude, start, end, amplitudeUp_normalized, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.sine) + { + amplitude = sineLineAmplitude * stylePatternScaleFactor; + return GetListOfSubLines_forSpiral(amplitude, 0.0f, start, end, amplitudeUp_normalized, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + } + + if (style == DrawBasics.LineStyle.zigzag) + { + float animationProgress_inSegments; + Vector3 normal_fromLinePerpToMainLinePoints; + Vector3 normal_fromLinePerpToPerpLinePoints; + amplitude = zigZagLineAmplitude * stylePatternScaleFactor; + return GetListOfSubLines_forZigZagTypeLines(ref s_listOfSubLines, DrawBasics.LineStyle.zigzag, start, end, amplitude, amplitudeUp_normalized, tensionFactor, animationSpeed, out animationProgress_inSegments, out normal_fromLinePerpToMainLinePoints, out normal_fromLinePerpToPerpLinePoints, ref lineAnimationProgressToUpdate, false, out int i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out int i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + } + + if (style == DrawBasics.LineStyle.rhombus) + { + float animationProgress_inSegments; + Vector3 normal_fromLinePerpToMainLinePoints; + Vector3 normal_fromLinePerpToPerpLinePoints; + amplitude = rhombusLineAmplitude * stylePatternScaleFactor; + return GetListOfSubLines_forZigZagTypeLines(ref s_listOfSubLines, DrawBasics.LineStyle.rhombus, start, end, amplitude, amplitudeUp_normalized, tensionFactor, animationSpeed, out animationProgress_inSegments, out normal_fromLinePerpToMainLinePoints, out normal_fromLinePerpToPerpLinePoints, ref lineAnimationProgressToUpdate, false, out int i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out int i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + } + + if (style == DrawBasics.LineStyle.doubleRhombus) + { + float animationProgress_inSegments; + Vector3 normal_fromLinePerpToMainLinePoints; + Vector3 normal_fromLinePerpToPerpLinePoints; + amplitude = doubleRhombusLineAmplitude * stylePatternScaleFactor; + return GetListOfSubLines_forZigZagTypeLines(ref s_listOfSubLines, DrawBasics.LineStyle.doubleRhombus, start, end, amplitude, amplitudeUp_normalized, tensionFactor, animationSpeed, out animationProgress_inSegments, out normal_fromLinePerpToMainLinePoints, out normal_fromLinePerpToPerpLinePoints, ref lineAnimationProgressToUpdate, false, out int i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out int i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + } + + if (style == DrawBasics.LineStyle.electricNoise) + { + return GetListOfSubLines_forElectricNoiseLines(start, end, stylePatternScaleFactor, lineWidth, out amplitude, ref lineAnimationProgressToUpdate, amplitudeUp_normalized, animationSpeed, tensionFactor); + } + + if (style == DrawBasics.LineStyle.electricImpulses) + { + return GetListOfSubLines_forElectricImpulseLines(start, end, stylePatternScaleFactor, lineWidth, out amplitude, ref lineAnimationProgressToUpdate, amplitudeUp_normalized, animationSpeed, tensionFactor); + } + + if (style == DrawBasics.LineStyle.freeHand2D) + { + amplitude = freeHandLineAmplitude * stylePatternScaleFactor; + int usedSlotsInListOfSubLines = GetListOfSubLines_forFreehandTypeLines(DrawBasics.LineStyle.freeHand2D, start, end, amplitude, amplitudeUp_normalized, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + amplitude = 0.6f * amplitude; //for text distance to line + return usedSlotsInListOfSubLines; + } + + if (style == DrawBasics.LineStyle.freeHand3D) + { + amplitude = freeHandLineAmplitude * stylePatternScaleFactor; + int usedSlotsInListOfSubLines = GetListOfSubLines_forFreehandTypeLines(DrawBasics.LineStyle.freeHand3D, start, end, amplitude, amplitudeUp_normalized, animationSpeed, ref lineAnimationProgressToUpdate, tensionFactor); + amplitude = 0.6f * amplitude; //for text distance to line + return usedSlotsInListOfSubLines; + } + + Debug.LogError("Line style " + style + " not implemented yet. Now returning emptyLine as fallback."); + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + amplitude = 0.0f; + return 0; + } + + static float AdjustPatternScaleFactor(float patternScaleFactor_toAdjust, Vector3 startToEnd, bool skipPatternEnlargementForLongLines) + { + if (patternScaleFactor_toAdjust < minStylePatternScaleFactor) + { + if (logWarningToConsole_forTooSmallPatternScaleFactor) + { + Debug.LogWarning("stylePatternScaleFactor (" + patternScaleFactor_toAdjust + ") must be bigger than minStylePatternScaleFactor (" + minStylePatternScaleFactor + ") and has been uprounded."); + } + patternScaleFactor_toAdjust = minStylePatternScaleFactor; + } + + //Restrict costly patternRecursion for long lines: + if (skipPatternEnlargementForLongLines == false) + { + float lineLengthSqr = startToEnd.sqrMagnitude; + float lineLengthSqr_aboveWhichToAutoEnlargeThePattern = DrawBasics.LineLength_aboveWhichToAutoEnlargeThePattern * DrawBasics.LineLength_aboveWhichToAutoEnlargeThePattern; //-> don't calculate on startUp, since "Draw.lineLength_aboveWhichToAutoEnlargeThePattern" can be changed during runtime + if (lineLengthSqr > lineLengthSqr_aboveWhichToAutoEnlargeThePattern) + { + float lineLength = Mathf.Sqrt(lineLengthSqr); + float patternAdjustFactor_ifPatternScaleFactorIs1 = lineLength * (1.0f / DrawBasics.LineLength_aboveWhichToAutoEnlargeThePattern); //-> patternAdjustFactor_ifPatternScaleFactorWas1 is always bigger than 1 + if (DrawBasics.autoEnlargeBigPatternsLater_whichDistortsPatternSizeRatios) + { + if (patternAdjustFactor_ifPatternScaleFactorIs1 > patternScaleFactor_toAdjust) + { + float finalPatternAdjustFactor = patternAdjustFactor_ifPatternScaleFactorIs1 / Mathf.Max(patternScaleFactor_toAdjust, 1.0f); + patternScaleFactor_toAdjust = patternScaleFactor_toAdjust * finalPatternAdjustFactor; + } + } + else + { + patternScaleFactor_toAdjust = patternScaleFactor_toAdjust * patternAdjustFactor_ifPatternScaleFactorIs1; + } + } + } + + return patternScaleFactor_toAdjust; + } + + static int GetListOfSubLines_forOneDashLine(float dashLength, float minRatio_for_dashLengthToLineWidth, float spaceToDash_ratio, float minEmptySpacesLength, float stylePatternScaleFactor, bool skipPatternEnlargementForShortLines, Vector3 start, Vector3 end, float lineWidth, float animationSpeed, ref LineAnimationProgress lineAnimationProgressToUpdate, float tensionFactor) + { + //function returns "usedSlotsInListOfSubLines" + int i_nextFreeSlot = 0; + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start, end)) + { + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + return 0; + } + + dashLength = EnlargeOneDashLengthForThickLines(dashLength, minRatio_for_dashLengthToLineWidth, lineWidth, skipPatternEnlargementForShortLines, stylePatternScaleFactor); + + float emptySpacesLength = dashLength * spaceToDash_ratio; + if (skipPatternEnlargementForShortLines == false) + { + emptySpacesLength = Mathf.Max(emptySpacesLength, minEmptySpacesLength); + } + + dashLength = dashLength * stylePatternScaleFactor; + emptySpacesLength = emptySpacesLength * stylePatternScaleFactor; + + dashLength = dashLength * tensionFactor; + emptySpacesLength = emptySpacesLength * tensionFactor; + + dashLength = Mathf.Max(dashLength, 0.0003f); + emptySpacesLength = Mathf.Max(emptySpacesLength, 0.0003f); + + float animationLoopLength = dashLength + emptySpacesLength; + Vector3 startToEnd = end - start; + Vector3 lineNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(startToEnd, out float lineLength); + + //first dash with fixed position: + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start, i_nextFreeSlot); + if (dashLength > lineLength) + { + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end, i_nextFreeSlot); + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + return i_nextFreeSlot; + } + else + { + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start + lineNormalized * dashLength, i_nextFreeSlot); + } + + //other dashes with animated positions: + float animationProgress = GetAnimationProgess_forDashLine(animationSpeed, lineAnimationProgressToUpdate, animationLoopLength); + GetCurrLineAnimationProgress(ref lineAnimationProgressToUpdate, animationProgress); + + float animationProgress_as0to1 = UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_m1_to_p1(animationProgress); + float steppedDistance_markingStartOfAnimatedLine = animationLoopLength * animationProgress_as0to1; + Vector3 currPos = start + lineNormalized * steppedDistance_markingStartOfAnimatedLine; + float alreadyStepped = steppedDistance_markingStartOfAnimatedLine; + int loopIterationCounter = 0; + + if (alreadyStepped > lineLength) + { + //lineEnd reached during first empty phase + i_nextFreeSlot = Add_endingDash_toSubLineAnchorList(i_nextFreeSlot, end, lineNormalized, dashLength); + return i_nextFreeSlot; + } + + while (alreadyStepped < lineLength) + { + //Add dash startPos: + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, currPos, i_nextFreeSlot); + currPos = currPos + lineNormalized * dashLength; + alreadyStepped = alreadyStepped + dashLength; + + if (alreadyStepped > lineLength) + { + //lineEnd reached during current dash phase + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end, i_nextFreeSlot); + i_nextFreeSlot = Add_endingDash_toSubLineAnchorList(i_nextFreeSlot, end, lineNormalized, dashLength); + break; + } + else + { + //Add dash endPos: + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, currPos, i_nextFreeSlot); + currPos = currPos + lineNormalized * emptySpacesLength; + alreadyStepped = alreadyStepped + emptySpacesLength; + if (alreadyStepped >= lineLength) //the "=" in ">=" is important to be continous with the "<" from the while-condition (otherwise (in edgeCases) the last dash will be lost (because: if the empty phase ends exactly at line end, then the upcoming loop will not start and then no "Add_endingDash_toSubLineAnchorList" is called)) + { + //lineEnd reached during current empty phase + i_nextFreeSlot = Add_endingDash_toSubLineAnchorList(i_nextFreeSlot, end, lineNormalized, dashLength); + break; + } + } + loopIterationCounter++; + if (loopIterationCounter > 100000) + { + Debug.LogError("Too many while loop iterations. Forced quit to prevent freeze. dashLength: " + dashLength + " emptySpacesLength: " + emptySpacesLength); + break; + } + } + + return i_nextFreeSlot; + } + + static int GetListOfSubLines_forTwoDashLine(float shortDashLength, bool treatShortDash_asDot, float longDashLength, float minRatio_for_longDashLengthToLineWidth, float spacesToLongDashs_ratio, float minEmptySpacesLength, bool skipPatternEnlargementForShortLines, Vector3 start, Vector3 end, float lineWidth, float animationSpeed, ref LineAnimationProgress lineAnimationProgressToUpdate, float tensionFactor) + { + //function returns "usedSlotsInListOfSubLines" + int i_nextFreeSlot = 0; + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start, end)) + { + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + return 0; + } + + bool dashLengthAdjustion_stoppedWithError = AdjustTwoDashLengthForThickLines(ref shortDashLength, ref longDashLength, treatShortDash_asDot, minRatio_for_longDashLengthToLineWidth, lineWidth, skipPatternEnlargementForShortLines); + if (dashLengthAdjustion_stoppedWithError) + { + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + return 0; + } + float emptySpacesLength = longDashLength * spacesToLongDashs_ratio; + if (skipPatternEnlargementForShortLines == false) + { + emptySpacesLength = Mathf.Max(emptySpacesLength, minEmptySpacesLength); + } + + shortDashLength = shortDashLength * tensionFactor; + longDashLength = longDashLength * tensionFactor; + emptySpacesLength = emptySpacesLength * tensionFactor; + + shortDashLength = Mathf.Max(shortDashLength, 0.0003f); + longDashLength = Mathf.Max(longDashLength, 0.0003f); + emptySpacesLength = Mathf.Max(emptySpacesLength, 0.0003f); + + Vector3 startToEnd = end - start; + float animationLoopLength = longDashLength + emptySpacesLength + shortDashLength + emptySpacesLength; + + Vector3 lineNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(startToEnd, out float lineLength); + float animationProgress = GetAnimationProgess_forDashLine(animationSpeed, lineAnimationProgressToUpdate, animationLoopLength); + GetCurrLineAnimationProgress(ref lineAnimationProgressToUpdate, animationProgress); + + //first longDash with fixed position: + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start, i_nextFreeSlot); + if (longDashLength > lineLength) + { + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end, i_nextFreeSlot); + return i_nextFreeSlot; + } + else + { + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start + lineNormalized * longDashLength, i_nextFreeSlot); + } + + if (animationLoopLength > lineLength) + { + //lineEnd reached inside animationLoopSpan + i_nextFreeSlot = Add_endingDash_toSubLineAnchorList(i_nextFreeSlot, end, lineNormalized, longDashLength); + return i_nextFreeSlot; + } + + float animationProgress_as0to1 = UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_m1_to_p1(animationProgress); + float steppedDistance_markingStartOfAnimatedLine = animationLoopLength * animationProgress_as0to1; + + //first shortDash that fills the animationGenerated hole: + if (steppedDistance_markingStartOfAnimatedLine > (longDashLength + emptySpacesLength)) + { + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start + lineNormalized * (steppedDistance_markingStartOfAnimatedLine - emptySpacesLength - shortDashLength), i_nextFreeSlot); + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start + lineNormalized * (steppedDistance_markingStartOfAnimatedLine - emptySpacesLength), i_nextFreeSlot); + } + + //other dashes with animated positions: + Vector3 currPos = start + lineNormalized * steppedDistance_markingStartOfAnimatedLine; + float alreadyStepped = steppedDistance_markingStartOfAnimatedLine; + int loopIterationCounter = 0; + while (alreadyStepped < lineLength) + { + //Add longDash startPos: + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, currPos, i_nextFreeSlot); + currPos = currPos + lineNormalized * longDashLength; + alreadyStepped = alreadyStepped + longDashLength; + + if (alreadyStepped > lineLength) + { + //lineEnd reached during current longDash phase + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end, i_nextFreeSlot);//end current longDashLinePhase + i_nextFreeSlot = Add_endingDash_toSubLineAnchorList(i_nextFreeSlot, end, lineNormalized, longDashLength); + break; + } + else + { + //Add longDash endPos: + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, currPos, i_nextFreeSlot); + currPos = currPos + lineNormalized * emptySpacesLength; + alreadyStepped = alreadyStepped + emptySpacesLength; + + if (alreadyStepped >= lineLength) //the "=" in ">=": Is probably not critical here, because it's not the last one of these "(alreadyStepped >= lineLength)"-checks inside the while loop + { + //lineEnd reached during current empty phase after longDash phase + i_nextFreeSlot = Add_endingDash_toSubLineAnchorList(i_nextFreeSlot, end, lineNormalized, longDashLength); + break; + } + + //Add shortDash startPos: + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, currPos, i_nextFreeSlot); + currPos = currPos + lineNormalized * shortDashLength; + alreadyStepped = alreadyStepped + shortDashLength; + + if (alreadyStepped >= lineLength) //the "=" in ">=": Is probably not critical here, because it's not the last one of these "(alreadyStepped >= lineLength)"-checks inside the while loop + { + //lineEnd reached during current shortDash phase + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end, i_nextFreeSlot);//end current shortDashLinePhase + i_nextFreeSlot = Add_endingDash_toSubLineAnchorList(i_nextFreeSlot, end, lineNormalized, longDashLength); + break; + } + + //Add shortDash endPos: + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, currPos, i_nextFreeSlot); + currPos = currPos + lineNormalized * emptySpacesLength; + alreadyStepped = alreadyStepped + emptySpacesLength; + + if (alreadyStepped >= lineLength) //the "=" in ">=" is important to be continous with the "<" from the while-condition (otherwise (in edgeCases) the last dash will be lost (because: if the empty phase ends exactly at line end, then the upcoming loop will not start and then no "Add_endingDash_toSubLineAnchorList" is called)) + { + //lineEnd reached during current empty phase after shortDash phase + i_nextFreeSlot = Add_endingDash_toSubLineAnchorList(i_nextFreeSlot, end, lineNormalized, longDashLength); + break; + } + } + + loopIterationCounter++; + if (loopIterationCounter > 100000) + { + Debug.LogError("Too many while loop iterations. Forced quit to prevent freeze. longDashLength: " + longDashLength + " shortDashLength: " + shortDashLength + " emptySpacesLength: " + emptySpacesLength); + break; + } + } + return i_nextFreeSlot; + } + + static float EnlargeOneDashLengthForThickLines(float dashLength, float minRatio_for_dashLengthToLineWidth, float lineWidth, bool skipPatternEnlargementForShortLines, float stylePatternScaleFactor) + { + if (skipPatternEnlargementForShortLines == false) + { + if (lineWidth > 0.0f) + { + //minRatio_for_dashLengthToLineWidth: Use "1.0f" for drawing dots, and higher values for drawing dashes. + minRatio_for_dashLengthToLineWidth = Mathf.Max(minRatio_for_dashLengthToLineWidth, 1.0f); + //float minDashLength_accordingToLineWidth = lineWidth * minRatio_for_dashLengthToLineWidth; + float minDashLength_accordingToLineWidth = lineWidth * minRatio_for_dashLengthToLineWidth / stylePatternScaleFactor; //"stylePatternScaleFactor" here recompensates an increasing "lineWidth". This fixes the problem that dashed lineStyles change their dashSize when changing the "nearClipPlane" of a camera on which a "DrawScreenspace" call is executed. In such cases the "lineWidth" has already been increased to fit the new screen dimension. This also causes the restriction of "stylePatternScaleFactor" as mentioned in the documentation, where it hasn't any effect below a dynamic limit. + dashLength = Mathf.Max(dashLength, minDashLength_accordingToLineWidth); + } + } + return dashLength; + } + + static bool AdjustTwoDashLengthForThickLines(ref float shortDashLength, ref float longDashLength, bool treatShortDash_asDot, float minRatio_for_longDashLengthToLineWidth, float lineWidth, bool skipPatternEnlargementForShortLines) + { + bool stoppedWithError = false; + if (skipPatternEnlargementForShortLines == false) + { + if (lineWidth > 0.0f) + { + //adjust dash length for thickLines: + float shortDashToLongDash_ratio = shortDashLength / longDashLength; + if (minRatio_for_longDashLengthToLineWidth > 1.0f) + { + float minLongDashLength_accordingToLineWidth = lineWidth * minRatio_for_longDashLengthToLineWidth; + longDashLength = Mathf.Max(longDashLength, minLongDashLength_accordingToLineWidth); + } + else + { + Debug.LogError("minRatio_for_longDashLengthToLineWidth (" + minRatio_for_longDashLengthToLineWidth + ") must be bigger than 1.0f, because the longDash is not supported to be treated as a dot."); + stoppedWithError = true; + return stoppedWithError; + } + + shortDashLength = longDashLength * shortDashToLongDash_ratio; + if (shortDashLength < lineWidth || treatShortDash_asDot) + { + shortDashLength = lineWidth; + } + } + } + + return stoppedWithError; + } + + static int Add_endingDash_toSubLineAnchorList(int i_nextFreeSlot, Vector3 end, Vector3 lineNormalized, float dashLength) + { + //function returns "i_nextFreeSlot" + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end - lineNormalized * dashLength, i_nextFreeSlot); + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end, i_nextFreeSlot); + return i_nextFreeSlot; + } + + static int GetListOfSubLines_forDisconnectedAnchorLines(Vector3 start, Vector3 end, Vector3 startToEnd, ref LineAnimationProgress lineAnimationProgressToUpdate, float animationSpeed, float tensionFactor) + { + float visibleSegment_lengthFactor_withoutTension = 0.3f; + float visibleSegment_lengthFactor; + + if (tensionFactor > 1.0f) + { + visibleSegment_lengthFactor = visibleSegment_lengthFactor_withoutTension / tensionFactor; //-> caller has to ensure that "tensionFactor" is not "0" + } + else + { + float max_additionDueToTension = 0.5f - visibleSegment_lengthFactor_withoutTension; + float additionDueToTension = max_additionDueToTension * (1.0f - tensionFactor); + visibleSegment_lengthFactor = visibleSegment_lengthFactor_withoutTension + additionDueToTension; + } + + float lengthFactor_oscillationAmplitude = 0.3333f * visibleSegment_lengthFactor; + float max_relOscillationAmplitude = 0.48f; + lengthFactor_oscillationAmplitude = Mathf.Min(lengthFactor_oscillationAmplitude, max_relOscillationAmplitude - visibleSegment_lengthFactor); + + float animationProgress = GetAnimationProgess_forDisconnectedAnchors(animationSpeed, lineAnimationProgressToUpdate); + visibleSegment_lengthFactor = visibleSegment_lengthFactor + lengthFactor_oscillationAmplitude * Mathf.Sin(animationProgress); + GetCurrLineAnimationProgress(ref lineAnimationProgressToUpdate, animationProgress); + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start, end)) + { + return 0; + } + else + { + UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start, 0); + UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start + startToEnd * visibleSegment_lengthFactor, 1); + UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end - startToEnd * visibleSegment_lengthFactor, 2); + UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end, 3); + return 4; + } + } + + static int GetListOfSubLines_forSpiral(float sineDirAmplitude, float cosineDirAmplitude, Vector3 start, Vector3 end, Vector3 amplitudeUp_normalized, float animationSpeed, ref LineAnimationProgress lineAnimationProgressToUpdate, float tensionFactor) + { + //function returns "usedSlotsInListOfSubLines" + int i_nextFreeSlot = 0; + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start, end)) + { + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + return 0; + } + + float min_sineCycles_forWholeLine = 1.0f; + int lineSegments_perSineCycle = 12; + + if (UtilitiesDXXL_Math.ApproximatelyZero(sineDirAmplitude)) + { + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + return FallbackToThinAndSolidLineStyle(start, end, out sineDirAmplitude, ref lineAnimationProgressToUpdate); + } + Vector3 startToEnd = end - start; + Vector3 line_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(startToEnd, out float length); + float sineCyles_perUnit = 1.0f / (sineDirAmplitude * UtilitiesDXXL_Math.anglesRad_perCircle); + float sineCycles_forWholeLine = sineCyles_perUnit * length / tensionFactor; //-> caller has to ensure that "tensionFactor" is not "0" + sineCycles_forWholeLine = Mathf.Max(sineCycles_forWholeLine, min_sineCycles_forWholeLine); + int lineSegments_forWholeLine = Mathf.CeilToInt(lineSegments_perSineCycle * sineCycles_forWholeLine); + float segmentLength = length / (float)lineSegments_forWholeLine; + Vector3 segment = line_normalized * segmentLength; + Vector3 maxAmplitude_inSineDir = amplitudeUp_normalized * sineDirAmplitude; + Vector3 maxAmplitude_inCosineDir = Vector3.zero; + bool isSpiral = true; + if (UtilitiesDXXL_Math.ApproximatelyZero(cosineDirAmplitude)) + { + isSpiral = false; + } + if (isSpiral) + { + Vector3 cosineDir_normalized = UtilitiesDXXL_Math.GetAVector_perpToGivenVectors(amplitudeUp_normalized, line_normalized); //is already normalized, because the two argument vectors are already normalized+perpendicular + maxAmplitude_inCosineDir = cosineDir_normalized * cosineDirAmplitude; + } + + float endOfFadeIn_as0to1ofWholeLine = (segmentLength * ((float)lineSegments_perSineCycle / 4.0f)) / length; + float startOfFadeOut_as0to1ofWholeLine = 1.0f - endOfFadeIn_as0to1ofWholeLine; + float animationProgress = GetAnimationProgess_forSpiral(animationSpeed, lineAnimationProgressToUpdate, sineDirAmplitude); + GetCurrLineAnimationProgress(ref lineAnimationProgressToUpdate, animationProgress); + + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start, i_nextFreeSlot);//start of first subLineSegment + for (int i = 1; i < lineSegments_forWholeLine; i++) + { + float progressThroughLine_atCurrPosOnLine_as0to1ofWholeLine = (float)i / (float)lineSegments_forWholeLine; + float progressThroughLine_atCurrPosOnLine_asFinishedSineCylces = (float)i / (float)lineSegments_perSineCycle; + float amplitudeDampingNearAnchors = UtilitiesDXXL_Math.Get_jumpFlyCurve_withPlateau(progressThroughLine_atCurrPosOnLine_as0to1ofWholeLine, endOfFadeIn_as0to1ofWholeLine, startOfFadeOut_as0to1ofWholeLine); + Vector3 currPosOnLine = start + segment * i; + float angleProgress = UtilitiesDXXL_Math.anglesRad_perCircle * progressThroughLine_atCurrPosOnLine_asFinishedSineCylces + animationProgress; + Vector3 currSineOffset = amplitudeDampingNearAnchors * maxAmplitude_inSineDir * Mathf.Sin(angleProgress); + Vector3 currCosineOffset = Vector3.zero; + if (isSpiral) + { + currCosineOffset = amplitudeDampingNearAnchors * maxAmplitude_inCosineDir * Mathf.Cos(angleProgress); + } + Vector3 currPos_onSpiralLine = currPosOnLine + currSineOffset + currCosineOffset; + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, currPos_onSpiralLine, i_nextFreeSlot); //end of previous subLineSegment + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, currPos_onSpiralLine, i_nextFreeSlot); //start of current subLineSegment + } + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end, i_nextFreeSlot);//end of last subLineSegment + return i_nextFreeSlot; + } + + static int GetListOfSubLines_forZigZagTypeLines(ref List usedListOfSubLines, DrawBasics.LineStyle zigZagType, Vector3 start, Vector3 end, float amplitude, Vector3 amplitudeUp_normalized, float tensionFactor, float animationSpeed, out float animationProgress_inSegments, out Vector3 normal_fromLinePerpToMainLinePoints, out Vector3 normal_fromLinePerpToPerpLinePoints, ref LineAnimationProgress lineAnimationProgressToUpdate, bool fillPosDetailLists, out int i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out int i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints) + { + //function returns "usedSlotsInListOfSubLines" + + int i_nextFreeSlot = 0; + i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine = 0; + i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints = 0; + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start, end)) + { + animationProgress_inSegments = 0.0f; + SetLineAnimProgressToZero(ref lineAnimationProgressToUpdate); + normal_fromLinePerpToMainLinePoints = Vector3.zero; + normal_fromLinePerpToPerpLinePoints = Vector3.zero; + return 0; + } + + float min_zigZagCycles_forWholeLine = 1.0f; + int lineSegments_perZigZagCycle = 2; + + if (UtilitiesDXXL_Math.ApproximatelyZero(amplitude)) + { + Debug.LogWarning("zigZag amplitude of 0 -> using straight solid line as fallback."); + animationProgress_inSegments = 0.0f; + normal_fromLinePerpToMainLinePoints = Vector3.zero; + normal_fromLinePerpToPerpLinePoints = Vector3.zero; + float lineStyleAmplitude; + return FallbackToThinAndSolidLineStyle(start, end, out lineStyleAmplitude, ref lineAnimationProgressToUpdate); + } + + Vector3 startToEnd = end - start; + Vector3 line_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(startToEnd, out float length); + float zigZagCyles_perUnit = 1.0f / (amplitude * 4.0f * tensionFactor); //-> caller has to ensure that "tensionFactor" is not 0 and not negative + float zigZagCycles_forWholeLine = zigZagCyles_perUnit * length; + zigZagCycles_forWholeLine = Mathf.Max(zigZagCycles_forWholeLine, min_zigZagCycles_forWholeLine); + float subLineSegments_ofWholeLine = lineSegments_perZigZagCycle * zigZagCycles_forWholeLine; + float segmentLength = length / subLineSegments_ofWholeLine; + Vector3 segment = line_normalized * segmentLength; + normal_fromLinePerpToMainLinePoints = amplitudeUp_normalized; + Vector3 mainZigZagOffset = amplitude * normal_fromLinePerpToMainLinePoints; + normal_fromLinePerpToPerpLinePoints = Vector3.zero; + Vector3 additionalPerpZigZagOffset; + + if (zigZagType == DrawBasics.LineStyle.zigzag || zigZagType == DrawBasics.LineStyle.electricNoise || zigZagType == DrawBasics.LineStyle.electricImpulses || zigZagType == DrawBasics.LineStyle.freeHand2D || zigZagType == DrawBasics.LineStyle.freeHand3D) + { + i_nextFreeSlot = GetListOfSubLines_forZigZagLine(ref usedListOfSubLines, mainZigZagOffset, length, line_normalized, segment, segmentLength, start, end, animationSpeed, out animationProgress_inSegments, ref lineAnimationProgressToUpdate, fillPosDetailLists, out i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + if (zigZagType == DrawBasics.LineStyle.freeHand3D) + { + normal_fromLinePerpToPerpLinePoints = UtilitiesDXXL_Math.GetAVector_perpToGivenVectors(normal_fromLinePerpToMainLinePoints, line_normalized); //result is normalized (because argument vectors are normalized+perp) + } + } + else + { + if (zigZagType == DrawBasics.LineStyle.rhombus) + { + int usedSlotsIn_upSegments = GetListOfSubLines_forZigZagLine(ref s_listOfSubLinesForZigZagsUpSegments, mainZigZagOffset, length, line_normalized, segment, segmentLength, start, end, animationSpeed, out animationProgress_inSegments, ref lineAnimationProgressToUpdate, false, out i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + int usedSlotsIn_downSegments = GetListOfSubLines_forZigZagLine(ref s_listOfSubLinesForZigZagsDownSegments, -mainZigZagOffset, length, line_normalized, segment, segmentLength, start, end, animationSpeed, out animationProgress_inSegments, ref lineAnimationProgressToUpdate, fillPosDetailLists, out i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + i_nextFreeSlot = GetIntegrateSegmentList(ref usedListOfSubLines, ref s_listOfSubLinesForZigZagsUpSegments, usedSlotsIn_upSegments, ref s_listOfSubLinesForZigZagsDownSegments, usedSlotsIn_downSegments); + } + else + { + if (zigZagType == DrawBasics.LineStyle.doubleRhombus) + { + normal_fromLinePerpToPerpLinePoints = UtilitiesDXXL_Math.GetAVector_perpToGivenVectors(normal_fromLinePerpToMainLinePoints, line_normalized); //result is normalized (because argument vectors are normalized+perp) + additionalPerpZigZagOffset = amplitude * normal_fromLinePerpToPerpLinePoints; + int usedSlotsIn_upSegments = GetListOfSubLines_forZigZagLine(ref s_listOfSubLinesForZigZagsUpSegments, mainZigZagOffset, length, line_normalized, segment, segmentLength, start, end, animationSpeed, out animationProgress_inSegments, ref lineAnimationProgressToUpdate, false, out i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + int usedSlotsIn_downSegments = GetListOfSubLines_forZigZagLine(ref s_listOfSubLinesForZigZagsDownSegments, -mainZigZagOffset, length, line_normalized, segment, segmentLength, start, end, animationSpeed, out animationProgress_inSegments, ref lineAnimationProgressToUpdate, false, out i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + int usedSlotsIn_leftSegments = GetListOfSubLines_forZigZagLine(ref s_listOfSubLinesForZigZagsLeftSegments, additionalPerpZigZagOffset, length, line_normalized, segment, segmentLength, start, end, animationSpeed, out animationProgress_inSegments, ref lineAnimationProgressToUpdate, false, out i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + int usedSlotsIn_rightSegments = GetListOfSubLines_forZigZagLine(ref s_listOfSubLinesForZigZagsRightSegments, -additionalPerpZigZagOffset, length, line_normalized, segment, segmentLength, start, end, animationSpeed, out animationProgress_inSegments, ref lineAnimationProgressToUpdate, fillPosDetailLists, out i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + int usedSlotsIn_upAndDownSegments = GetIntegrateSegmentList(ref s_listOfSubLinesForZigZagsUpAndDownSegments, ref s_listOfSubLinesForZigZagsUpSegments, usedSlotsIn_upSegments, ref s_listOfSubLinesForZigZagsDownSegments, usedSlotsIn_downSegments); + int usedSlotsIn_leftAndRightSegments = GetIntegrateSegmentList(ref s_listOfSubLinesForZigZagsLeftAndRightSegments, ref s_listOfSubLinesForZigZagsLeftSegments, usedSlotsIn_leftSegments, ref s_listOfSubLinesForZigZagsRightSegments, usedSlotsIn_rightSegments); + i_nextFreeSlot = GetIntegrateSegmentList(ref usedListOfSubLines, ref s_listOfSubLinesForZigZagsUpAndDownSegments, usedSlotsIn_upAndDownSegments, ref s_listOfSubLinesForZigZagsLeftAndRightSegments, usedSlotsIn_leftAndRightSegments); + } + else + { + Debug.LogError("The line style " + zigZagType + " is not yet implemented as a zigZag-Line. -> Now using straight solid line as fallback."); + i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine = 0; + i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints = 0; + animationProgress_inSegments = 0.0f; + normal_fromLinePerpToMainLinePoints = Vector3.zero; + normal_fromLinePerpToPerpLinePoints = Vector3.zero; + float lineStyleAmplitude; + return FallbackToThinAndSolidLineStyle(start, end, out lineStyleAmplitude, ref lineAnimationProgressToUpdate); + } + } + } + + return i_nextFreeSlot; + } + + static int GetListOfSubLines_forZigZagLine(ref List usedListOfSubLines, Vector3 zigZagOffset, float length, Vector3 line_normalized, Vector3 segment, float segmentLength, Vector3 start, Vector3 end, float animationSpeed, out float animationProgress_inSegments, ref LineAnimationProgress lineAnimationProgressToUpdate, bool fillPosDetailLists, out int i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out int i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints) + { + //function returns "usedSlotsIn_usedListOfSubLines" + + int i_nextFreeSlot_inUsedListOfSubLines = 0; + int i_nextFreeSlot_inDistanceToStartList = 0; + i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine = 0; + i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints = 0; + + segmentLength = Mathf.Max(segmentLength, 0.0001f); + float halfSegmentLength = 0.5f * segmentLength; + float cycleLength = 2.0f * segmentLength; //segmentLength describes "1flank ("zig")", cylce describes "2flanks("zagZag")". + float animationProgress = GetAnimationProgess_forSimpleCase(animationSpeed, lineAnimationProgressToUpdate); + GetCurrLineAnimationProgress(ref lineAnimationProgressToUpdate, animationProgress); + float animationProgress_inCycles = animationProgress / cycleLength; + animationProgress_inSegments = 2.0f * animationProgress_inCycles; + float animationProgress_as0to1 = UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_m1_to_p1(animationProgress_inCycles); + float alreadyStepped = -3.5f * segmentLength + animationProgress_as0to1 * cycleLength; //"-3.5" consists of: "0.5" -> so that line starts at crossing point, "1.0" -> is taken at start of first while loop, "2.0" -> the animation cycle + + bool sideOfCurrAmplitude = true; + int loopIterationCounter = 0; + while (alreadyStepped < length) + { + alreadyStepped = alreadyStepped + segmentLength; //incrementation at start of while loop ensures, that one pos after lineEnd gets added. + + Vector3 currUsed_zigZagOffset = sideOfCurrAmplitude ? (-zigZagOffset) : zigZagOffset; + sideOfCurrAmplitude = !sideOfCurrAmplitude; + + Vector3 currPosOnLine = start + alreadyStepped * line_normalized; + Vector3 currPos_onZigZagLine = currPosOnLine + currUsed_zigZagOffset; + + i_nextFreeSlot_inUsedListOfSubLines = UtilitiesDXXL_List.AddToAVectorList(ref usedListOfSubLines, currPos_onZigZagLine, i_nextFreeSlot_inUsedListOfSubLines);//end of previous subLineSegment + i_nextFreeSlot_inUsedListOfSubLines = UtilitiesDXXL_List.AddToAVectorList(ref usedListOfSubLines, currPos_onZigZagLine, i_nextFreeSlot_inUsedListOfSubLines);//start of current subLineSegment + i_nextFreeSlot_inDistanceToStartList = AddToDistanceToStartList(alreadyStepped, i_nextFreeSlot_inDistanceToStartList); + i_nextFreeSlot_inDistanceToStartList = AddToDistanceToStartList(alreadyStepped, i_nextFreeSlot_inDistanceToStartList); + if (fillPosDetailLists) + { + i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine = UtilitiesDXXL_List.AddToAVectorList(ref s_subLinePoints_projectionOntoStraightMainLine, currPosOnLine, i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine); + i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine = UtilitiesDXXL_List.AddToAVectorList(ref s_subLinePoints_projectionOntoStraightMainLine, currPosOnLine, i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine); + i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints = UtilitiesDXXL_List.AddToAVectorList(ref s_vectors_fromProjectionOntoMainLine_toSubLinePoints, currUsed_zigZagOffset, i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints = UtilitiesDXXL_List.AddToAVectorList(ref s_vectors_fromProjectionOntoMainLine_toSubLinePoints, currUsed_zigZagOffset, i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + } + + loopIterationCounter++; + if (loopIterationCounter > 100000) + { + Debug.LogError("Too many while loop iterations. Forced quit to prevent freeze. segmentLength: " + segmentLength); + break; + } + } + + //Beautify lineStart: + for (int i = 0; i < i_nextFreeSlot_inUsedListOfSubLines; i++) + { + if (((i + 1) < i_nextFreeSlot_inUsedListOfSubLines) == false) + { + UtilitiesDXXL_Log.PrintErrorCode("19-" + i + "-" + i_nextFreeSlot_inUsedListOfSubLines); + float lineStyleAmplitude; + return FallbackToThinAndSolidLineStyle(start, end, out lineStyleAmplitude, ref lineAnimationProgressToUpdate); + } + + if (s_subLineAnchor_distanceToStart[i] > halfSegmentLength) + { + break; + } + else + { + if (s_subLineAnchor_distanceToStart[i] > (-halfSegmentLength)) + { + float distance_thatMarks_nextAmplitudeZeroIntersection_afterCurrPos = s_subLineAnchor_distanceToStart[i] + halfSegmentLength; + Vector3 nextAmplitudeZeroIntersection_afterCurrPos = start + distance_thatMarks_nextAmplitudeZeroIntersection_afterCurrPos * line_normalized; + Vector3 pos_relToNextAmplitudeZeroIntersection = usedListOfSubLines[i] - nextAmplitudeZeroIntersection_afterCurrPos; + float triangleShorteningFactor = distance_thatMarks_nextAmplitudeZeroIntersection_afterCurrPos / segmentLength; + + usedListOfSubLines[i] = nextAmplitudeZeroIntersection_afterCurrPos + pos_relToNextAmplitudeZeroIntersection * triangleShorteningFactor; + usedListOfSubLines[i + 1] = usedListOfSubLines[i]; + if (fillPosDetailLists) + { + s_subLinePoints_projectionOntoStraightMainLine[i] = s_subLinePoints_projectionOntoStraightMainLine[i] + line_normalized * (halfSegmentLength * (1.0f - triangleShorteningFactor)); + s_subLinePoints_projectionOntoStraightMainLine[i + 1] = s_subLinePoints_projectionOntoStraightMainLine[i]; + s_vectors_fromProjectionOntoMainLine_toSubLinePoints[i] = s_vectors_fromProjectionOntoMainLine_toSubLinePoints[i] * triangleShorteningFactor; + s_vectors_fromProjectionOntoMainLine_toSubLinePoints[i + 1] = s_vectors_fromProjectionOntoMainLine_toSubLinePoints[i]; + } + } + } + i++; + } + + //Remove points lower than startPos: + for (int i = i_nextFreeSlot_inUsedListOfSubLines - 1; i >= 0; i--) + { + if (s_subLineAnchor_distanceToStart[i] <= (-halfSegmentLength)) + { + i_nextFreeSlot_inUsedListOfSubLines = UtilitiesDXXL_List.RemoveAt_fromAVectorList(ref usedListOfSubLines, i, i_nextFreeSlot_inUsedListOfSubLines); + i_nextFreeSlot_inDistanceToStartList = RemoveAt_fromDistanceToStartList(i, i_nextFreeSlot_inDistanceToStartList); + if (fillPosDetailLists) + { + i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine = UtilitiesDXXL_List.RemoveAt_fromAVectorList(ref s_subLinePoints_projectionOntoStraightMainLine, i, i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine); + i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints = UtilitiesDXXL_List.RemoveAt_fromAVectorList(ref s_vectors_fromProjectionOntoMainLine_toSubLinePoints, i, i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + } + } + } + + //Beautify lineEnd: + float distance_markingHalfSegmentAfterLineEnd = length + halfSegmentLength; + float distance_markingHalfSegmentBeforeLineEnd = length - halfSegmentLength; + for (int i = i_nextFreeSlot_inUsedListOfSubLines - 1; i >= 0; i--) + { + if (i <= 0) + { + UtilitiesDXXL_Log.PrintErrorCode("20-" + i + "-" + i_nextFreeSlot_inUsedListOfSubLines); + float lineStyleAmplitude; + return FallbackToThinAndSolidLineStyle(start, end, out lineStyleAmplitude, ref lineAnimationProgressToUpdate); + } + + if (s_subLineAnchor_distanceToStart[i] < distance_markingHalfSegmentBeforeLineEnd) + { + break; + } + else + { + if (s_subLineAnchor_distanceToStart[i] < distance_markingHalfSegmentAfterLineEnd) + { + float distance_thatMarks_lastAmplitudeZeroIntersection_beforeCurrPos = s_subLineAnchor_distanceToStart[i] - halfSegmentLength; + Vector3 lastAmplitudeZeroIntersection_beforeCurrPos = start + distance_thatMarks_lastAmplitudeZeroIntersection_beforeCurrPos * line_normalized; + Vector3 pos_relToPrevAmplitudeZeroIntersection = usedListOfSubLines[i] - lastAmplitudeZeroIntersection_beforeCurrPos; + float triangleShorteningFactor; + if (s_subLineAnchor_distanceToStart[i] < length) + { + float distance_thatMarks_firstAmplitudeZeroIntersection_afterCurrPos = s_subLineAnchor_distanceToStart[i] + halfSegmentLength; + triangleShorteningFactor = (segmentLength - (distance_thatMarks_firstAmplitudeZeroIntersection_afterCurrPos - length)) / segmentLength; + } + else + { + triangleShorteningFactor = (length - distance_thatMarks_lastAmplitudeZeroIntersection_beforeCurrPos) / segmentLength; + } + + usedListOfSubLines[i] = lastAmplitudeZeroIntersection_beforeCurrPos + pos_relToPrevAmplitudeZeroIntersection * triangleShorteningFactor; + usedListOfSubLines[i - 1] = usedListOfSubLines[i]; + if (fillPosDetailLists) + { + s_subLinePoints_projectionOntoStraightMainLine[i] = lastAmplitudeZeroIntersection_beforeCurrPos + 0.5f * segment * triangleShorteningFactor; + s_subLinePoints_projectionOntoStraightMainLine[i - 1] = s_subLinePoints_projectionOntoStraightMainLine[i]; + s_vectors_fromProjectionOntoMainLine_toSubLinePoints[i] = s_vectors_fromProjectionOntoMainLine_toSubLinePoints[i] * triangleShorteningFactor; + s_vectors_fromProjectionOntoMainLine_toSubLinePoints[i - 1] = s_vectors_fromProjectionOntoMainLine_toSubLinePoints[i]; + } + } + else + { + i_nextFreeSlot_inUsedListOfSubLines = UtilitiesDXXL_List.RemoveAt_fromAVectorList(ref usedListOfSubLines, i, i_nextFreeSlot_inUsedListOfSubLines); + i_nextFreeSlot_inUsedListOfSubLines = UtilitiesDXXL_List.RemoveAt_fromAVectorList(ref usedListOfSubLines, i - 1, i_nextFreeSlot_inUsedListOfSubLines); + i_nextFreeSlot_inDistanceToStartList = RemoveAt_fromDistanceToStartList(i, i_nextFreeSlot_inDistanceToStartList); + i_nextFreeSlot_inDistanceToStartList = RemoveAt_fromDistanceToStartList(i - 1, i_nextFreeSlot_inDistanceToStartList); + + if (fillPosDetailLists) + { + i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine = UtilitiesDXXL_List.RemoveAt_fromAVectorList(ref s_subLinePoints_projectionOntoStraightMainLine, i, i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine); + i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine = UtilitiesDXXL_List.RemoveAt_fromAVectorList(ref s_subLinePoints_projectionOntoStraightMainLine, i - 1, i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine); + i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints = UtilitiesDXXL_List.RemoveAt_fromAVectorList(ref s_vectors_fromProjectionOntoMainLine_toSubLinePoints, i, i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints = UtilitiesDXXL_List.RemoveAt_fromAVectorList(ref s_vectors_fromProjectionOntoMainLine_toSubLinePoints, i - 1, i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + } + } + } + i--; + } + + //Fill detail info lists for line ends: + i_nextFreeSlot_inUsedListOfSubLines = UtilitiesDXXL_List.InsertToAVectorList(ref usedListOfSubLines, 0, start, i_nextFreeSlot_inUsedListOfSubLines); //start of first subLineSegment + if (fillPosDetailLists) + { + i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine = UtilitiesDXXL_List.InsertToAVectorList(ref s_subLinePoints_projectionOntoStraightMainLine, 0, start, i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine); + i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints = UtilitiesDXXL_List.InsertToAVectorList(ref s_vectors_fromProjectionOntoMainLine_toSubLinePoints, 0, Vector3.zero, i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + } + + i_nextFreeSlot_inUsedListOfSubLines = UtilitiesDXXL_List.AddToAVectorList(ref usedListOfSubLines, end, i_nextFreeSlot_inUsedListOfSubLines); //end of last subLineSegment + if (fillPosDetailLists) + { + i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine = UtilitiesDXXL_List.AddToAVectorList(ref s_subLinePoints_projectionOntoStraightMainLine, end, i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine); + i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints = UtilitiesDXXL_List.AddToAVectorList(ref s_vectors_fromProjectionOntoMainLine_toSubLinePoints, Vector3.zero, i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + } + + return i_nextFreeSlot_inUsedListOfSubLines; + } + + static int GetIntegrateSegmentList(ref List targetList, ref List list1_toIntegrate, int usedSlotsInList1, ref List list2_toIntegrate, int usedSlotsInList2) + { + //function returns "usedSlotsInTargetList" + //This function integrates the different lineStrings of rhombus, so that colorFade correctly works + int maxCycles = usedSlotsInList1 + usedSlotsInList2 + 100; + int i_list1 = 0; + int i_list2 = 0; + bool list1or2 = true; + int i_cycle = 0; + int i_ofNextFreeSlot_inTargetList = 0; + while (i_cycle < maxCycles) + { + if (list1or2) + { + i_ofNextFreeSlot_inTargetList = IntegrateSegment(ref targetList, i_ofNextFreeSlot_inTargetList, list1_toIntegrate, ref i_list1, usedSlotsInList1); + } + else + { + i_ofNextFreeSlot_inTargetList = IntegrateSegment(ref targetList, i_ofNextFreeSlot_inTargetList, list2_toIntegrate, ref i_list2, usedSlotsInList2); + } + list1or2 = !list1or2; + i_cycle++; + } + return i_ofNextFreeSlot_inTargetList; + } + + static int IntegrateSegment(ref List targetList, int i_ofNextFreeSlot_inTargetList, List listToIntegrate, ref int i_slotToIntegrateInListToIntegrate, int usedSlotsInListToIntegrate) + { + for (int i = 0; i < 2; i++) + { + if (i_slotToIntegrateInListToIntegrate < usedSlotsInListToIntegrate) + { + i_ofNextFreeSlot_inTargetList = UtilitiesDXXL_List.AddToAVectorList(ref targetList, listToIntegrate[i_slotToIntegrateInListToIntegrate], i_ofNextFreeSlot_inTargetList); + i_slotToIntegrateInListToIntegrate++; + } + } + return i_ofNextFreeSlot_inTargetList; + } + + static int GetListOfSubLines_forFreehandTypeLines(DrawBasics.LineStyle freehandType, Vector3 start, Vector3 end, float patternScaled_freeHandLineAmplitude, Vector3 amplitudeUp_normalized, float animationSpeed, ref LineAnimationProgress lineAnimationProgressToUpdate, float tensionFactor) + { + //function returns "usedSlotsInListOfSubLines" + + if (freehandType != DrawBasics.LineStyle.freeHand2D && freehandType != DrawBasics.LineStyle.freeHand3D) + { + Debug.LogError("Line style " + freehandType + " is not yet implemented as a freehand style type. -> Now using straight solid line as fallback."); + float lineStyleAmplitude; + return FallbackToThinAndSolidLineStyle(start, end, out lineStyleAmplitude, ref lineAnimationProgressToUpdate); + } + + float freehandsZigZagAmplitude = 0.05f * patternScaled_freeHandLineAmplitude; + float animationProgress_inSegments; + Vector3 normal_fromLinePerpToMainLinePoints; + Vector3 normal_fromLinePerpToPerpLinePoints; + int usedSlotsInListOfSubLines = GetListOfSubLines_forZigZagTypeLines(ref s_listOfSubLines, freehandType, start, end, freehandsZigZagAmplitude, amplitudeUp_normalized, tensionFactor, 2.0f * animationSpeed, out animationProgress_inSegments, out normal_fromLinePerpToMainLinePoints, out normal_fromLinePerpToPerpLinePoints, ref lineAnimationProgressToUpdate, true, out int i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out int i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + + for (int i = 1; i < (usedSlotsInListOfSubLines - 1); i++) + { + float perlinResult_forZigZagDim = Mathf.PerlinNoise(((float)i + animationProgress_inSegments - 2.0f * Mathf.Floor(animationProgress_inSegments)) * 0.043f, 0.0f); + float distance_fromProjectionOntoMainLine_toSubLinePointInZigZagPlane = patternScaled_freeHandLineAmplitude * (perlinResult_forZigZagDim - 0.5f); + Vector3 currVector_fromProjectionOntoMainLine_toSubLinePointInZigZagPlane = normal_fromLinePerpToMainLinePoints * distance_fromProjectionOntoMainLine_toSubLinePointInZigZagPlane; + + float perlinResult_forPerpDim; + float distance_fromProjectionOntoZigZagPlane_perpToSubLinePoint; + Vector3 currVector_fromProjectionOntoZigZagPlane_perpToSubLinePoint = Vector3.zero; + if (freehandType == DrawBasics.LineStyle.freeHand3D) + { + perlinResult_forPerpDim = Mathf.PerlinNoise(((float)i + animationProgress_inSegments - 2.0f * Mathf.Floor(animationProgress_inSegments)) * 0.057f, 0.0f); + distance_fromProjectionOntoZigZagPlane_perpToSubLinePoint = patternScaled_freeHandLineAmplitude * (perlinResult_forPerpDim - 0.5f); + currVector_fromProjectionOntoZigZagPlane_perpToSubLinePoint = normal_fromLinePerpToPerpLinePoints * distance_fromProjectionOntoZigZagPlane_perpToSubLinePoint; + } + + s_listOfSubLines[i] = s_subLinePoints_projectionOntoStraightMainLine[i] + currVector_fromProjectionOntoMainLine_toSubLinePointInZigZagPlane + currVector_fromProjectionOntoZigZagPlane_perpToSubLinePoint; + s_listOfSubLines[i + 1] = s_listOfSubLines[i]; + i++; + } + + return usedSlotsInListOfSubLines; + } + + static int GetListOfSubLines_forElectricNoiseLines(Vector3 start, Vector3 end, float stylePatternScaleFactor, float lineWidth, out float amplitude, ref LineAnimationProgress lineAnimationProgressToUpdate, Vector3 amplitudeUp_normalized, float animationSpeed, float tensionFactor) + { + float minSqueezeRatio = 0.06f; + float maxSqueezeRatio = 0.2f; + float squeezeRatio = minSqueezeRatio; + if (UtilitiesDXXL_Math.ApproximatelyZero(lineWidth) == false) + { + squeezeRatio = 5.0f * UtilitiesDXXL_Math.Get_2degParabolicFlateningRise_flatRightOfOne(lineWidth); + } + squeezeRatio = Mathf.Max(squeezeRatio, minSqueezeRatio); + squeezeRatio = Mathf.Min(squeezeRatio, maxSqueezeRatio); + squeezeRatio = squeezeRatio * tensionFactor; + + float minSqueezeRatio_afterTension = 0.001f; + squeezeRatio = Mathf.Max(squeezeRatio, minSqueezeRatio_afterTension); + + float animationProgress_inSegments; + Vector3 normal_fromLinePerpToMainLinePoints; + Vector3 normal_fromLinePerpToPerpLinePoints; + amplitude = electricNoiseLineAmplitude * stylePatternScaleFactor; + int usedSlotsInListOfSubLines = GetListOfSubLines_forZigZagTypeLines(ref s_listOfSubLines, DrawBasics.LineStyle.electricNoise, start, end, amplitude, amplitudeUp_normalized, squeezeRatio, animationSpeed, out animationProgress_inSegments, out normal_fromLinePerpToMainLinePoints, out normal_fromLinePerpToPerpLinePoints, ref lineAnimationProgressToUpdate, true, out int i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out int i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + amplitude = 0.7f * amplitude; //for text distance to line + + for (int i = 1; i < (usedSlotsInListOfSubLines - 1); i++) + { + float perlinResult = Mathf.PerlinNoise(((float)i + animationProgress_inSegments) * 13.23f, 0.0f); + s_listOfSubLines[i] = s_subLinePoints_projectionOntoStraightMainLine[i] + s_vectors_fromProjectionOntoMainLine_toSubLinePoints[i] * perlinResult; + s_listOfSubLines[i + 1] = s_listOfSubLines[i]; + i++; + } + return usedSlotsInListOfSubLines; + } + + static int GetListOfSubLines_forElectricImpulseLines(Vector3 start, Vector3 end, float stylePatternScaleFactor, float lineWidth, out float amplitude, ref LineAnimationProgress lineAnimationProgressToUpdate, Vector3 amplitudeUp_normalized, float animationSpeed, float tensionFactor) + { + Vector3 startToEnd = end - start; + float cycleLength = impulseDistance_ofElectricImpulseLines * stylePatternScaleFactor * tensionFactor; //-> caller has to ensure that "tensionFactor" is not "0" + float patternScaled_electricImpulseLineAmplitude = electricImpulseLineAmplitude * stylePatternScaleFactor; + amplitude = patternScaled_electricImpulseLineAmplitude; + float impulseLength = patternScaled_electricImpulseLineAmplitude * impulseSqueeze_ofElectricImpulseLines + lineWidth; + impulseLength = Mathf.Min(impulseLength, 0.3f * cycleLength); + float solidLength = cycleLength - impulseLength; + + if (solidLength <= 0.0f) + { + //Debug.LogWarning("The configuration of the electricImpulses line style leads to no space between the impulses. Thus the result looks like the zigzag line style. Current configuration -> electricImpulseLineAmplitude: " + electricImpulseLineAmplitude + " patternScaled_electricImpulseLineAmplitude: " + patternScaled_electricImpulseLineAmplitude + " impulseDistance_ofElectricImpulseLines: " + impulseDistance_ofElectricImpulseLines + " impulseSqueeze_ofElectricImpulseLines: " + impulseSqueeze_ofElectricImpulseLines + " (potentially scaled)stylePatternScaleFactor: " + stylePatternScaleFactor); + solidLength = 0.0001f; + } + + impulseLength = Mathf.Max(impulseLength, 0.0001f); + Vector3 lineNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(startToEnd, out float lineLength); + + if (UtilitiesDXXL_Math.ApproximatelyZero(animationSpeed) && CheckIfAnimationProgessIsZeroOrNull(lineAnimationProgressToUpdate)) + { + //animation didn't start + if (impulseLength > lineLength) + { + //impulse fills whole line + float animProgress_ofZigZag; + Vector3 normal_fromLinePerpToMainLinePoints; + Vector3 normal_fromLinePerpToPerpLinePoints; + LineAnimationProgress lineAnimProgress_ofZigZag = null; + int usedSlotsInListOfSubLines = GetListOfSubLines_forZigZagTypeLines(ref s_listOfSubLines, DrawBasics.LineStyle.zigzag, start, end, patternScaled_electricImpulseLineAmplitude, amplitudeUp_normalized, impulseSqueeze_ofElectricImpulseLines, animationSpeed, out animProgress_ofZigZag, out normal_fromLinePerpToMainLinePoints, out normal_fromLinePerpToPerpLinePoints, ref lineAnimProgress_ofZigZag, false, out int i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out int i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + return usedSlotsInListOfSubLines; + } + } + float animationProgress = GetAnimationProgess_forSimpleCase(animationSpeed, lineAnimationProgressToUpdate); + GetCurrLineAnimationProgress(ref lineAnimationProgressToUpdate, animationProgress); + float animationProgress_inCycles = animationProgress / cycleLength; + float animationProgress_as0to1 = UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_m1_to_p1(animationProgress_inCycles); + float alreadyStepped = -cycleLength + cycleLength * animationProgress_as0to1 - 0.96f * solidLength; + Vector3 currPos = start + alreadyStepped * lineNormalized; + + int i_nextFreeSlot = 0; + int loopIterationCounter = 0; + while (alreadyStepped < lineLength) + { + if (alreadyStepped <= 0.0f) + { + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start, i_nextFreeSlot);//start of solid line + } + else + { + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, currPos, i_nextFreeSlot);//start of solid line + } + currPos = currPos + lineNormalized * solidLength; + alreadyStepped = alreadyStepped + solidLength; + if (alreadyStepped >= lineLength) + { + //lineEnd reached during current solid phase + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, end, i_nextFreeSlot); //end of solid line + break; + } + if (alreadyStepped <= 0.0f) + { + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, start, i_nextFreeSlot);//end of solid line + } + else + { + i_nextFreeSlot = UtilitiesDXXL_List.AddToAVectorList(ref s_listOfSubLines, currPos, i_nextFreeSlot); //end of solid line + } + + float alreadyStepped_afterUpcomingImpulse = alreadyStepped + impulseLength; + Vector3 startPosOfImpulse; + if (alreadyStepped <= 0.0f) + { + startPosOfImpulse = start; + } + else + { + startPosOfImpulse = currPos; + } + + Vector3 endPosOfImpulse; + if (alreadyStepped_afterUpcomingImpulse >= lineLength) + { + endPosOfImpulse = end; + } + else + { + if (alreadyStepped_afterUpcomingImpulse <= 0.0f) + { + endPosOfImpulse = start; + } + else + { + endPosOfImpulse = currPos + lineNormalized * impulseLength; + } + } + + float animProgress_ofZigZag; + Vector3 normal_fromLinePerpToMainLinePoints; + Vector3 normal_fromLinePerpToPerpLinePoints; + LineAnimationProgress lineAnimProgress_ofZigZag = null; + int usedSlotsInRangeList = GetListOfSubLines_forZigZagTypeLines(ref s_addedRangeForListOfSubLines, DrawBasics.LineStyle.zigzag, startPosOfImpulse, endPosOfImpulse, patternScaled_electricImpulseLineAmplitude, amplitudeUp_normalized, impulseSqueeze_ofElectricImpulseLines, 0.0f, out animProgress_ofZigZag, out normal_fromLinePerpToMainLinePoints, out normal_fromLinePerpToPerpLinePoints, ref lineAnimProgress_ofZigZag, false, out int i_nextFreeSlot_in_subLinePoints_projectionOntoStraightMainLine, out int i_nextFreeSlot_in_vectors_fromProjectionOntoMainLine_toSubLinePoints); + i_nextFreeSlot = UtilitiesDXXL_List.AddRangeToAVectorList(ref s_listOfSubLines, s_addedRangeForListOfSubLines, i_nextFreeSlot, usedSlotsInRangeList); + + alreadyStepped = alreadyStepped_afterUpcomingImpulse; + currPos = start + alreadyStepped * lineNormalized; + + loopIterationCounter++; + if (loopIterationCounter > 100000) + { + Debug.LogError("Too many while loop iterations. Forced quit to prevent freeze. solidLength: " + solidLength + " impulseLength: " + impulseLength); + break; + } + } + return i_nextFreeSlot; + } + + static int FallbackToThinAndSolidLineStyle(Vector3 start, Vector3 end, out float unusedAmplitude, ref LineAnimationProgress lineAnimationProgressToUpdate) + { + return RefillListOfSubLines(start, end, DrawBasics.LineStyle.solid, 1.0f, 0.0f, out unusedAmplitude, default(Vector3), 0.0f, ref lineAnimationProgressToUpdate, false, false, 1.0f); + } + + static void GetCurrLineAnimationProgress(ref LineAnimationProgress lineAnimationProgress, float currAnimProgress) + { + if (lineAnimationProgress != null) + { + lineAnimationProgress.animProgress = currAnimProgress; + lineAnimationProgress.timeOfDraw = GetTime(); + } + } + + static float GetAnimationProgess_forDashLine(float animationSpeed, LineAnimationProgress lineAnimationProgress, float animationLoopLength) + { + //Know issue: jittery animation in Screenspace: + //-> The reason seems to be a float calculation precision limit error in "UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane()" when "UtilitiesDXXL_Screenspace.GetLineParamsFromCamViewportSpace()" requests the conversion from "width_relToViewportHeight" to "width_worldSpace". + //-> In some situations it helped when using the "line_fadeableAnimSpeed_screenspace.Draw()" (which holds a persistent "LineAnimationProgress" member) instead of just calling the static function "DrawScreenspace.Line()", though I don't know yet why this helps. + + if (lineAnimationProgress == null) + { + return ((animationSpeed * GetTime()) / animationLoopLength); + } + else + { + float timeSinceLastCall = GetTime() - lineAnimationProgress.timeOfDraw; + return lineAnimationProgress.animProgress + ((animationSpeed * timeSinceLastCall) / animationLoopLength); + } + } + + static float GetAnimationProgess_forSpiral(float animationSpeed, LineAnimationProgress lineAnimationProgress, float sineDirAmplitude) + { + //Know issue: jittery animation in Screenspace: See notes in "GetAnimationProgess_forDashLine()" + if (lineAnimationProgress == null) + { + return (-(GetTime() * animationSpeed) / sineDirAmplitude); + } + else + { + float timeSinceLastCall = GetTime() - lineAnimationProgress.timeOfDraw; + return lineAnimationProgress.animProgress + (-(timeSinceLastCall * animationSpeed) / sineDirAmplitude); + } + } + + static float GetAnimationProgess_forSimpleCase(float animationSpeed, LineAnimationProgress lineAnimationProgress) + { + //Know issue: jittery animation in Screenspace: See notes in "GetAnimationProgess_forDashLine()" + if (lineAnimationProgress == null) + { + return (animationSpeed * GetTime()); + } + else + { + float timeSinceLastCall = GetTime() - lineAnimationProgress.timeOfDraw; + return lineAnimationProgress.animProgress + (animationSpeed * timeSinceLastCall); + } + } + + static float GetAnimationProgess_forDisconnectedAnchors(float animationSpeed, LineAnimationProgress lineAnimationProgress) + { + //Know issue: jittery animation in Screenspace: See notes in "GetAnimationProgess_forDashLine()" + float speedScaling = 20.0f; + if (lineAnimationProgress == null) + { + return (GetTime() * animationSpeed * speedScaling); + } + else + { + float timeSinceLastCall = GetTime() - lineAnimationProgress.timeOfDraw; + return lineAnimationProgress.animProgress + (timeSinceLastCall * animationSpeed * speedScaling); + } + } + + public static float GetTime() + { +#if UNITY_EDITOR + if (Application.isPlaying) + { + return Time.time; + } + else + { + return (float)UnityEditor.EditorApplication.timeSinceStartup; + } +#else + return Time.time; +#endif + } + + static bool CheckIfAnimationProgessIsZeroOrNull(LineAnimationProgress lineAnimationProgress) + { + if (lineAnimationProgress == null) + { + return true; + } + else + { + if (UtilitiesDXXL_Math.ApproximatelyZero(lineAnimationProgress.animProgress)) + { + return true; + } + else + { + return false; + } + } + } + + static int AddToDistanceToStartList(float floatToAdd, int i_ofSlotWhereToAdd) + { + //function returns "i_nextFreeSlot" + //function is not ensuring yet if addSlot is the next higher nonExisting-slot + if (i_ofSlotWhereToAdd < s_subLineAnchor_distanceToStart.Count) + { + s_subLineAnchor_distanceToStart[i_ofSlotWhereToAdd] = floatToAdd; + } + else + { + s_subLineAnchor_distanceToStart.Add(floatToAdd); + } + i_ofSlotWhereToAdd++; + return i_ofSlotWhereToAdd; + } + + static int RemoveAt_fromDistanceToStartList(int i_toRemove, int i_nextFreeSlot) + { + //function returns "i_nextFreeSlot" + //function is not checking yet if removeSlot already exists + s_subLineAnchor_distanceToStart.RemoveAt(i_toRemove); + i_nextFreeSlot--; + return i_nextFreeSlot; + } + + static void SetLineAnimProgressToZero(ref LineAnimationProgress lineAnimationProgress) + { + if (lineAnimationProgress != null) + { + lineAnimationProgress.animProgress = 0.0f; + lineAnimationProgress.timeOfDraw = 0.0f; + } + } + + public static bool CheckIfLineStyleNeedsDefinedAmplitudeForSubLineCreation(DrawBasics.LineStyle styleToCheck) + { + switch (styleToCheck) + { + case DrawBasics.LineStyle.solid: + return false; + case DrawBasics.LineStyle.invisible: + return false; + case DrawBasics.LineStyle.dotted: + return false; + case DrawBasics.LineStyle.dottedDense: + return false; + case DrawBasics.LineStyle.dottedWide: + return false; + case DrawBasics.LineStyle.dashed: + return false; + case DrawBasics.LineStyle.dashedLong: + return false; + case DrawBasics.LineStyle.dotDash: + return false; + case DrawBasics.LineStyle.dotDashLong: + return false; + case DrawBasics.LineStyle.twoDash: + return false; + case DrawBasics.LineStyle.disconnectedAnchors: + return false; + case DrawBasics.LineStyle.spiral: + return true; + case DrawBasics.LineStyle.sine: + return true; + case DrawBasics.LineStyle.zigzag: + return true; + case DrawBasics.LineStyle.rhombus: + return true; + case DrawBasics.LineStyle.doubleRhombus: + return true; + case DrawBasics.LineStyle.electricNoise: + return true; + case DrawBasics.LineStyle.electricImpulses: + return true; + case DrawBasics.LineStyle.freeHand2D: + return true; + case DrawBasics.LineStyle.freeHand3D: + return true; + case DrawBasics.LineStyle.arrows: + return false; //arrows-lines do have a defined amplitude dir, but it is not used for sub line creation + case DrawBasics.LineStyle.alternatingColorStripes: + return false; + default: + return false; + } + } + + public static bool CheckIfLineStyleUsesPatternScaling(DrawBasics.LineStyle styleToCheck) + { + switch (styleToCheck) + { + case DrawBasics.LineStyle.solid: + return false; + case DrawBasics.LineStyle.invisible: + return false; + case DrawBasics.LineStyle.dotted: + return true; + case DrawBasics.LineStyle.dottedDense: + return true; + case DrawBasics.LineStyle.dottedWide: + return true; + case DrawBasics.LineStyle.dashed: + return true; + case DrawBasics.LineStyle.dashedLong: + return true; + case DrawBasics.LineStyle.dotDash: + return true; + case DrawBasics.LineStyle.dotDashLong: + return true; + case DrawBasics.LineStyle.twoDash: + return true; + case DrawBasics.LineStyle.disconnectedAnchors: + return false; + case DrawBasics.LineStyle.spiral: + return true; + case DrawBasics.LineStyle.sine: + return true; + case DrawBasics.LineStyle.zigzag: + return true; + case DrawBasics.LineStyle.rhombus: + return true; + case DrawBasics.LineStyle.doubleRhombus: + return true; + case DrawBasics.LineStyle.electricNoise: + return true; + case DrawBasics.LineStyle.electricImpulses: + return true; + case DrawBasics.LineStyle.freeHand2D: + return true; + case DrawBasics.LineStyle.freeHand3D: + return true; + case DrawBasics.LineStyle.arrows: + return true; + case DrawBasics.LineStyle.alternatingColorStripes: + return true; + default: + return false; + } + } + + public static bool CheckIfLineStyleIsAnimatable(DrawBasics.LineStyle styleToCheck) + { + switch (styleToCheck) + { + case DrawBasics.LineStyle.solid: + return false; + case DrawBasics.LineStyle.invisible: + return false; + case DrawBasics.LineStyle.dotted: + return true; + case DrawBasics.LineStyle.dottedDense: + return true; + case DrawBasics.LineStyle.dottedWide: + return true; + case DrawBasics.LineStyle.dashed: + return true; + case DrawBasics.LineStyle.dashedLong: + return true; + case DrawBasics.LineStyle.dotDash: + return true; + case DrawBasics.LineStyle.dotDashLong: + return true; + case DrawBasics.LineStyle.twoDash: + return true; + case DrawBasics.LineStyle.disconnectedAnchors: + return true; + case DrawBasics.LineStyle.spiral: + return true; + case DrawBasics.LineStyle.sine: + return true; + case DrawBasics.LineStyle.zigzag: + return true; + case DrawBasics.LineStyle.rhombus: + return true; + case DrawBasics.LineStyle.doubleRhombus: + return true; + case DrawBasics.LineStyle.electricNoise: + return true; + case DrawBasics.LineStyle.electricImpulses: + return true; + case DrawBasics.LineStyle.freeHand2D: + return true; + case DrawBasics.LineStyle.freeHand3D: + return true; + case DrawBasics.LineStyle.arrows: + return true; + case DrawBasics.LineStyle.alternatingColorStripes: + return true; + default: + return false; + } + } + + public static DrawBasics.LineStyle FallbackTo2DLineStyle(DrawBasics.LineStyle pot3DLineStyle) + { + if (pot3DLineStyle == DrawBasics.LineStyle.spiral) + { + return DrawBasics.LineStyle.sine; + } + + if (pot3DLineStyle == DrawBasics.LineStyle.doubleRhombus) + { + return DrawBasics.LineStyle.rhombus; + } + + if (pot3DLineStyle == DrawBasics.LineStyle.freeHand3D) + { + return DrawBasics.LineStyle.freeHand2D; + } + + return pot3DLineStyle; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineStyles.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineStyles.cs.meta new file mode 100644 index 0000000..9608025 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_LineStyles.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 145dcbed1e04b9340b35d1d0a1690210 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_List.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_List.cs new file mode 100644 index 0000000..dac9e91 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_List.cs @@ -0,0 +1,116 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_List + { + public static void CopyContentOfVectorLists(ref List listWhereToCopyTo, ref List listWhereToCopyFrom, int numberOfSlotsToCopy) + { + for (int i = 0; i < numberOfSlotsToCopy; i++) + { + AddToAVectorList(ref listWhereToCopyTo, listWhereToCopyFrom[i], i); + } + } + + public static void CopyContentOfVector2Lists(ref List listWhereToCopyTo, ref List listWhereToCopyFrom, int numberOfSlotsToCopy) + { + for (int i = 0; i < numberOfSlotsToCopy; i++) + { + AddToAVector2List(ref listWhereToCopyTo, listWhereToCopyFrom[i], i); + } + } + + public static void CopyContentOfVector2ArrayToList(ref List listWhereToCopyTo, ref Vector2[] arrayWhereToCopyFrom, int numberOfSlotsToCopy) + { + for (int i = 0; i < numberOfSlotsToCopy; i++) + { + AddToAVector2List(ref listWhereToCopyTo, arrayWhereToCopyFrom[i], i); + } + } + + public static int AddToAVectorList(ref List targetList, Vector3 posToAdd, int i_ofSlotWhereToAdd) + { + //function returns "i_nextFreeSlot" + if (i_ofSlotWhereToAdd < targetList.Count) + { + targetList[i_ofSlotWhereToAdd] = posToAdd; + } + else + { + while (targetList.Count <= i_ofSlotWhereToAdd) + { + targetList.Add(posToAdd); + } + } + i_ofSlotWhereToAdd++; + return i_ofSlotWhereToAdd; + } + + public static int AddToAVector2List(ref List targetList, Vector2 posToAdd, int i_ofSlotWhereToAdd) + { + //function returns "i_nextFreeSlot" + if (i_ofSlotWhereToAdd < targetList.Count) + { + targetList[i_ofSlotWhereToAdd] = posToAdd; + } + else + { + while (targetList.Count <= i_ofSlotWhereToAdd) + { + targetList.Add(posToAdd); + } + } + i_ofSlotWhereToAdd++; + return i_ofSlotWhereToAdd; + } + + public static int AddToABoolList(ref List targetList, bool boolToAdd, int i_ofSlotWhereToAdd) + { + //function returns "i_nextFreeSlot" + if (i_ofSlotWhereToAdd < targetList.Count) + { + targetList[i_ofSlotWhereToAdd] = boolToAdd; + } + else + { + while (targetList.Count <= i_ofSlotWhereToAdd) + { + targetList.Add(boolToAdd); + } + } + i_ofSlotWhereToAdd++; + return i_ofSlotWhereToAdd; + } + + public static int AddRangeToAVectorList(ref List targetList, List rangeToAdd, int i_ofSlotWhereToAdd, int slotsToAddFromRangeList) + { + //function returns "i_nextFreeSlotAfterInsertedRange" + for (int i = 0; i < slotsToAddFromRangeList; i++) + { + i_ofSlotWhereToAdd = AddToAVectorList(ref targetList, rangeToAdd[i], i_ofSlotWhereToAdd); + } + return i_ofSlotWhereToAdd; + } + + public static int InsertToAVectorList(ref List targetList, int i_whereToInsert, Vector3 posToInsert, int i_nextFreeSlot) + { + //function returns "i_nextFreeSlot" + //function is not checking yet if insertSlot already exists + targetList.Insert(i_whereToInsert, posToInsert); + i_nextFreeSlot++; + return i_nextFreeSlot; + } + + public static int RemoveAt_fromAVectorList(ref List targetList, int i_toRemove, int i_nextFreeSlot) + { + //function returns "i_nextFreeSlot" + //function is not checking yet if removeSlot already exists + targetList.RemoveAt(i_toRemove); + i_nextFreeSlot--; + return i_nextFreeSlot; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_List.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_List.cs.meta new file mode 100644 index 0000000..db6472d --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_List.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 885685a80d4321d44ade42907d54534f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Log.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Log.cs new file mode 100644 index 0000000..86f7de3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Log.cs @@ -0,0 +1,115 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_Log + { + public static string Get_vectorComponentsAsString(Vector3 vector3_toGetComponentsFrom, bool andAppendVectorLength = false) + { + if (andAppendVectorLength) + { + return ("( " + vector3_toGetComponentsFrom.x + " , " + vector3_toGetComponentsFrom.y + " , " + vector3_toGetComponentsFrom.z + " ) (length = " + vector3_toGetComponentsFrom.magnitude + ")"); + } + else + { + return ("( " + vector3_toGetComponentsFrom.x + " , " + vector3_toGetComponentsFrom.y + " , " + vector3_toGetComponentsFrom.z + " )"); + } + } + + public static string Get_vectorComponentsAsString(Vector2 vector2_toGetComponentsFrom, bool andAppendVectorLength = false) + { + if (andAppendVectorLength) + { + return ("( " + vector2_toGetComponentsFrom.x + " , " + vector2_toGetComponentsFrom.y + " ) (length = " + vector2_toGetComponentsFrom.magnitude + ")"); + } + else + { + return ("( " + vector2_toGetComponentsFrom.x + " , " + vector2_toGetComponentsFrom.y + " )"); + } + } + + public static string Get_quaternionComponentsAsString(Quaternion quaternion_toGetComponentsFrom, bool andAppendMagnitude = false) + { + if (andAppendMagnitude) + { + return ("( " + quaternion_toGetComponentsFrom.x + " , " + quaternion_toGetComponentsFrom.y + " , " + quaternion_toGetComponentsFrom.z + " , " + quaternion_toGetComponentsFrom.w + " ) (magnitude = " + UtilitiesDXXL_Math.GetQuaternionMagnitude(quaternion_toGetComponentsFrom) + ")"); + } + else + { + return ("( " + quaternion_toGetComponentsFrom.x + " , " + quaternion_toGetComponentsFrom.y + " , " + quaternion_toGetComponentsFrom.z + " , " + quaternion_toGetComponentsFrom.w + " )"); + } + } + + public static bool ErrorLogForInvalidFloats(float floatToCheck, string floatName) + { + if (UtilitiesDXXL_Math.FloatIsInvalid(floatToCheck)) + { + UnityEngine.Debug.LogError("The float value '" + floatName + "' is not a valid float, but " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(floatToCheck) + ". Draw operation is not executed."); + return true; + } + else + { + return false; + } + } + + public static bool ErrorLogForInvalidVectors(Vector3 vectorToCheck, string vectorName) + { + if (UtilitiesDXXL_Math.FloatIsInvalid(vectorToCheck.x) || UtilitiesDXXL_Math.FloatIsInvalid(vectorToCheck.y) || UtilitiesDXXL_Math.FloatIsInvalid(vectorToCheck.z)) + { + UnityEngine.Debug.LogError("The Vector3 '" + vectorName + "' contains invalid float components: ( x is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(vectorToCheck.x) + ", y is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(vectorToCheck.y) + ", z is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(vectorToCheck.z) + "). Draw operation is not executed."); + return true; + } + else + { + return false; + } + } + + public static bool ErrorLogForInvalidVectors(Vector2 vectorToCheck, string vectorName) + { + if (UtilitiesDXXL_Math.FloatIsInvalid(vectorToCheck.x) || UtilitiesDXXL_Math.FloatIsInvalid(vectorToCheck.y)) + { + UnityEngine.Debug.LogError("The Vector2 '" + vectorName + "' contains invalid float components: ( x is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(vectorToCheck.x) + ", y is " + UtilitiesDXXL_Math.GetFloatInvalidTypeAsString(vectorToCheck.y) + "). Draw operation is not executed."); + return true; + } + else + { + return false; + } + } + + public static bool ErrorLogForNullUnityObjects(UnityEngine.Object objectToCheck, string objectName) + { + if (objectToCheck == null) + { + UnityEngine.Debug.LogError("The Object '" + objectName + "' is 'null'. Draw operation is not executed."); + return true; + } + else + { + return false; + } + } + + public static bool ErrorLogForNullSystemObjects(System.Object objectToCheck, string objectName) + { + if (objectToCheck == null) + { + UnityEngine.Debug.LogError("The Object '" + objectName + "' is 'null'. Draw operation is not executed."); + return true; + } + else + { + return false; + } + } + + public static void PrintErrorCode(string errorCodeNumber) + { + UnityEngine.Debug.LogError("Draw XXL error code " + errorCodeNumber + ". You can help improving the code by submitting this code line including the stack trace and the piece of code that triggered this error. e-mail: drawxxl@symphonygames.net"); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Log.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Log.cs.meta new file mode 100644 index 0000000..b82a31a --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Log.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c6bdc880798aee4497b39c10a096949 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Math.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Math.cs new file mode 100644 index 0000000..454fcf6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Math.cs @@ -0,0 +1,1721 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_Math + { + public enum SkewedDirection { upLeft, upRight, downRight, downLeft, center }; + public enum Dimension { x, y, z }; + public enum DimensionNullable { x, y, z, none }; + + public static float sqrtOf2_precalced = 1.414214f; + public static float sqrtOf2_precalced_minus1 = 0.414214f; + public static float inverseSqrtOf2_precalced = 0.7071065f; + public static float anglesRad_perCircle = 2.0f * Mathf.PI; + public static Vector3 arbitrarySeldomDir_precalced = new Vector3(0.132443f, 0.23452f, 0.87365f); + public static Vector3 arbitrarySeldomDir2_precalced = new Vector3(-0.381128f, -0.18123f, -0.76529f); + public static Vector3 arbitrarySeldomDir_normalized_precalced = new Vector3(0.1448693f, 0.2565236f, 0.9556195f); + + public static bool Check_ifVectors_arePerp(Vector3 first_vector3, Vector3 second_vector3) + { + return (ApproximatelyZero(Vector3.Dot(first_vector3, second_vector3))); + } + + public static bool Check_ifTwoNormalizedVectorsAreApproxPerp_DXXL(Vector3 firstNormalizedVector3, Vector3 secondNormalizedVector3) + { + float threshold = 0.0001f; + return (Abs(Vector3.Dot(firstNormalizedVector3, secondNormalizedVector3)) < threshold); + } + + public static bool Check_ifVectorsPointAwayFromEachOther_perpCountsAsPointingInSameDir(Vector3 first_vector3, Vector3 second_vector3) + { + return (Vector3.Dot(first_vector3, second_vector3) < 0.0f); + } + + public static bool Check_ifVectorsPointAwayFromEachOther_perpCountsAsPointingAwayFromEachOther(Vector3 first_vector3, Vector3 second_vector3) + { + return (Vector3.Dot(first_vector3, second_vector3) <= 0.0f); + } + + public static bool Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(Vector2 first_vector2, Vector2 second_vector2) + { + return ((Vector2.Dot(first_vector2, second_vector2) < 0.0f) == false); + } + + public static bool Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(Vector3 first_vector3, Vector3 second_vector3) + { + return ((Vector3.Dot(first_vector3, second_vector3) < 0.0f) == false); + } + + public static bool Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs(Vector3 first_vector3_normalized, Vector3 second_vector3_normalized) + { + Vector3 crossProduct_ofVectors = Vector3.Cross(first_vector3_normalized, second_vector3_normalized); + return CheckIfCrossProductResultMeans_approxParallel_butCanHeadToDifferntDirs(crossProduct_ofVectors); + } + + public static bool CheckIfCrossProductResultMeans_approxParallel_butCanHeadToDifferntDirs(Vector3 crossProductResult) + { + return (Abs(crossProductResult.x) <= Mathf.Epsilon && Abs(crossProductResult.y) <= Mathf.Epsilon && Abs(crossProductResult.z) <= Mathf.Epsilon); + } + + public static Vector3 GetAVector_perpToGivenVectors(Vector3 vector1, Vector3 vector2) + { + return Vector3.Cross(vector1, vector2); + } + + public static bool Check_ifTwoVectorsAreApproxParallel_butCanHeadToDifferntDirs_expensiveButAccurate(Vector3 first_vector3, Vector3 second_vector3) + { + first_vector3 = GetNormalized_afterScalingIntoRegionOfFloatPrecicion(first_vector3); + second_vector3 = GetNormalized_afterScalingIntoRegionOfFloatPrecicion(second_vector3); + return Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs(first_vector3, second_vector3); + } + + public static bool Check_ifTwoVectorsAreApproxParallel_butCanHeadToDifferntDirs_DXXL(Vector3 firstVector3, Vector3 secondVector3) + { + firstVector3 = GetNormalized_afterScalingIntoRegionOfFloatPrecicion(firstVector3); + secondVector3 = GetNormalized_afterScalingIntoRegionOfFloatPrecicion(secondVector3); + return Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(firstVector3, secondVector3); + } + + public static bool Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(Vector3 firstNormalizedVector3, Vector3 secondNormalizedVector3, float absPadding) + { + Vector3 crossProduct_ofVectors = Vector3.Cross(firstNormalizedVector3, secondNormalizedVector3); + return (Abs(crossProduct_ofVectors.x) <= absPadding && Abs(crossProduct_ofVectors.y) <= absPadding && Abs(crossProduct_ofVectors.z) <= absPadding); + } + + public static bool Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(Vector3 firstNormalizedVector3, Vector3 secondNormalizedVector3) + { + return Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(firstNormalizedVector3, secondNormalizedVector3, 0.0001f); + } + + public static bool CheckIf_twoFloatsAreApproximatelyEqual(float a, float b) + { + return (a >= (b - Mathf.Epsilon)) && (a <= (b + Mathf.Epsilon)); + } + + public static bool ApproximatelyZero(float float_toCheckItIsApproximatelyZero) + { + return (float_toCheckItIsApproximatelyZero >= (-Mathf.Epsilon)) && (float_toCheckItIsApproximatelyZero <= (Mathf.Epsilon)); + } + + public static bool CheckIf_twoVectorsAreApproximatelyEqual(Vector3 a, Vector3 b) + { + return (CheckIf_twoFloatsAreApproximatelyEqual(a.x, b.x) && CheckIf_twoFloatsAreApproximatelyEqual(a.y, b.y) && CheckIf_twoFloatsAreApproximatelyEqual(a.z, b.z)); + } + + public static bool CheckIf_twoVectorsAreExactlyEqual(Vector3 a, Vector3 b) + { + return ((a.x == b.x) && (a.y == b.y) && (a.z == b.z)); + } + + public static bool CheckIf_twoVectorsAreExactlyEqual(Vector2 a, Vector2 b) + { + return ((a.x == b.x) && (a.y == b.y)); + } + + public static bool CheckIf_vectorsAreApproximatelyEqual(Vector3 a, Vector3 b, Vector3 c) + { + if (CheckIf_twoVectorsAreApproximatelyEqual(a, b)) + { + if (CheckIf_twoVectorsAreApproximatelyEqual(a, c)) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } + + public static bool CheckIf_vectorsAreApproximatelyEqual(Vector3 a, Vector3 b, Vector3 c, Vector3 d) + { + if (CheckIf_twoVectorsAreApproximatelyEqual(a, b)) + { + if (CheckIf_twoVectorsAreApproximatelyEqual(a, c)) + { + if (CheckIf_twoVectorsAreApproximatelyEqual(a, d)) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } + else + { + return false; + } + } + + public static bool ApproximatelyZero(Vector3 vector3_toCheckIfItIsApproximatelyZero) + { + return (ApproximatelyZero(vector3_toCheckIfItIsApproximatelyZero.x) && ApproximatelyZero(vector3_toCheckIfItIsApproximatelyZero.y) && ApproximatelyZero(vector3_toCheckIfItIsApproximatelyZero.z)); + } + + public static bool IsDefaultVector(Vector3 vector3_toCheckIfItIsTheDefaultVector) + { + return ApproximatelyZero(vector3_toCheckIfItIsTheDefaultVector); + } + + public static bool IsDefaultVector(Vector2 vector2_toCheckIfItIsTheDefaultVector) + { + return ApproximatelyZero(vector2_toCheckIfItIsTheDefaultVector); + } + + public static bool IsDefaultInvalidQuaternion(Quaternion quaternion_toCheckIfItIsTheDefaultInvalid) + { + return (ApproximatelyZero(quaternion_toCheckIfItIsTheDefaultInvalid.x) && ApproximatelyZero(quaternion_toCheckIfItIsTheDefaultInvalid.y) && ApproximatelyZero(quaternion_toCheckIfItIsTheDefaultInvalid.z) && ApproximatelyZero(quaternion_toCheckIfItIsTheDefaultInvalid.w)); + } + + public static bool IsQuaternionIdentity(Quaternion quaternion_toCheckIfItIsIdentity) + { + return (ApproximatelyZero(quaternion_toCheckIfItIsIdentity.x) && ApproximatelyZero(quaternion_toCheckIfItIsIdentity.y) && ApproximatelyZero(quaternion_toCheckIfItIsIdentity.z) && CheckIf_twoFloatsAreApproximatelyEqual(quaternion_toCheckIfItIsIdentity.w, 1.0f)); + } + + public static bool QuaternionIsApproxNormalized(Quaternion quaternion_toCheck) + { + float quaternionMagnitude = GetQuaternionMagnitude(quaternion_toCheck); + return CheckIfValueLiesInsideDistanceNearAnotherValue(quaternionMagnitude, 1.0f, 0.01f); + } + + public static float GetQuaternionMagnitude(Quaternion quaternion_toCheck) + { + return Mathf.Sqrt(quaternion_toCheck.x * quaternion_toCheck.x + quaternion_toCheck.y * quaternion_toCheck.y + quaternion_toCheck.z * quaternion_toCheck.z + quaternion_toCheck.w * quaternion_toCheck.w); + } + + public static bool CheckIf_twoQuaternionsAreApproximatelyEqual(Quaternion a, Quaternion b) + { + return (CheckIf_twoFloatsAreApproximatelyEqual(a.x, b.x) && CheckIf_twoFloatsAreApproximatelyEqual(a.y, b.y) && CheckIf_twoFloatsAreApproximatelyEqual(a.z, b.z) && CheckIf_twoFloatsAreApproximatelyEqual(a.w, b.w)); + } + + public static bool CheckIf_twoQuaternionsAreExactlyEqual(Quaternion a, Quaternion b) + { + return ((a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w)); + } + + public static bool CheckIf_twoVectorsAreApproximatelyEqual(Vector2 a, Vector2 b) + { + return (CheckIf_twoFloatsAreApproximatelyEqual(a.x, b.x) && CheckIf_twoFloatsAreApproximatelyEqual(a.y, b.y)); + } + + public static bool ApproximatelyZero(Vector2 vector2_toCheckIfItIsApproximatelyZero) + { + return (ApproximatelyZero(vector2_toCheckIfItIsApproximatelyZero.x) && ApproximatelyZero(vector2_toCheckIfItIsApproximatelyZero.y)); + } + + public static float Get_linearRise(float given_x) + { + return (given_x); + } + + public static float Get_linearDecay(float given_x) + { + return (1.0f - given_x); + } + + public static float Abs(float signedNumber) + { + if (signedNumber < 0.0f) + { + return (-signedNumber); + } + else + { + return signedNumber; + } + } + + public static Vector3 Abs(Vector3 vector) + { + return new Vector3(Abs(vector.x), Abs(vector.y), Abs(vector.z)); + } + + public static Vector2 Abs(Vector2 vector) + { + return new Vector2(Abs(vector.x), Abs(vector.y)); + } + + public static bool CheckIf_givenNumberIs_evenNotOdd(int int_toCheck) + { + return (int_toCheck % 2 == 0); + } + + public static bool CheckIfValueLiesInsideDistanceNearAnotherValue(float referenceValue_fromWhichPaddingIsMeasured, float valueToCheck_ifItLiesNearReferenceValue, float paddingSpan_usedForEachSide_soThisIsHalfOfTheWholeToleranceSpan) + { + if (valueToCheck_ifItLiesNearReferenceValue < (referenceValue_fromWhichPaddingIsMeasured - paddingSpan_usedForEachSide_soThisIsHalfOfTheWholeToleranceSpan)) + { + return false; + } + else + { + if (valueToCheck_ifItLiesNearReferenceValue > (referenceValue_fromWhichPaddingIsMeasured + paddingSpan_usedForEachSide_soThisIsHalfOfTheWholeToleranceSpan)) + { + return false; + } + else + { + return true; + } + } + } + + public static float GetSign_trueGivesPlus1_falseGivesMinus1(bool signAsBool) + { + if (signAsBool == true) + { + return (1.0f); + } + else + { + return (-1.0f); + } + } + + public static bool CheckIfVectorIsParallelToXAxis(Vector3 vector) + { + return (ApproximatelyZero(vector.y) && ApproximatelyZero(vector.z)); + } + + public static bool CheckIfVectorIsParallelToYAxis(Vector3 vector) + { + return (ApproximatelyZero(vector.x) && ApproximatelyZero(vector.z)); + } + + public static bool CheckIfVectorIsParallelToZAxis(Vector3 vector) + { + return (ApproximatelyZero(vector.x) && ApproximatelyZero(vector.y)); + } + + public static float Max(float value1, float value2, float value3) + { + return (Mathf.Max(Mathf.Max(value1, value2), value3)); + } + + public static float Min(float value1, float value2, float value3) + { + return (Mathf.Min(Mathf.Min(value1, value2), value3)); + } + + public static float Max(float value1, float value2, float value3, float value4, float value5) + { + return (Mathf.Max((Mathf.Max((Mathf.Max(Mathf.Max(value1, value2), value3)), value4)), value5)); + } + + public static double Max(double value1, double value2) + { + if (value1 > value2) + { + return value1; + } + else + { + return value2; + } + } + + public static double Min(double value1, double value2) + { + if (value1 < value2) + { + return value1; + } + else + { + return value2; + } + } + + public static float AbsNonZeroValue(float valueToAbs_ifNonZero) + { + if (ApproximatelyZero(valueToAbs_ifNonZero) == false) + { + return Mathf.Abs(valueToAbs_ifNonZero); + } + else + { + return valueToAbs_ifNonZero; + } + } + + public static bool VectorIsInvalid(Vector3 vectorToCheckForValidity) + { + return (FloatIsInvalid(vectorToCheckForValidity.x) || FloatIsInvalid(vectorToCheckForValidity.y) || FloatIsInvalid(vectorToCheckForValidity.z)); + } + + public static bool VectorIsInvalid(Vector2 vectorToCheckForValidity) + { + return (FloatIsInvalid(vectorToCheckForValidity.x) || FloatIsInvalid(vectorToCheckForValidity.y)); + } + + public static bool FloatIsValid(float floatToCheckForValidity) + { + return ((float.IsNaN(floatToCheckForValidity) == false) && (float.IsInfinity(floatToCheckForValidity) == false)); + } + + public static bool DoubleIsValid(double doubleToCheckForValidity) + { + return ((double.IsNaN(doubleToCheckForValidity) == false) && (double.IsInfinity(doubleToCheckForValidity) == false)); + } + + public static bool FloatIsInvalid(float floatToCheckForValidity) + { + return (float.IsNaN(floatToCheckForValidity) || float.IsInfinity(floatToCheckForValidity)); + } + + public static string GetFloatInvalidTypeAsString(float floatToCheckForValidity) + { + if (float.IsNaN(floatToCheckForValidity)) + { + return "NaN ('not a number')"; + } + else + { + if (float.IsPositiveInfinity(floatToCheckForValidity)) + { + return "positive infinity"; + } + else + { + if (float.IsNegativeInfinity(floatToCheckForValidity)) + { + return "negative infinity"; + } + else + { + return "valid float: " + floatToCheckForValidity; + } + } + } + } + + public static float GetBiggestAbsComponent(Vector2 vector) + { + float biggestAbsComponent = 0.0f; + float absX = Mathf.Abs(vector.x); + if (absX > biggestAbsComponent) + { + biggestAbsComponent = absX; + } + + float absY = Mathf.Abs(vector.y); + if (absY > biggestAbsComponent) + { + biggestAbsComponent = absY; + } + + return biggestAbsComponent; + } + + public static float GetBiggestAbsComponent(Vector3 vector) + { + float biggestAbsComponent = 0.0f; + float absX = Mathf.Abs(vector.x); + if (absX > biggestAbsComponent) + { + biggestAbsComponent = absX; + } + + float absY = Mathf.Abs(vector.y); + if (absY > biggestAbsComponent) + { + biggestAbsComponent = absY; + } + + float absZ = Mathf.Abs(vector.z); + if (absZ > biggestAbsComponent) + { + biggestAbsComponent = absZ; + } + return biggestAbsComponent; + } + + public static float GetBiggestAbsComponent_ignoringZ(Vector3 vector) + { + float biggestAbsComponent = 0.0f; + float absX = Mathf.Abs(vector.x); + if (absX > biggestAbsComponent) + { + biggestAbsComponent = absX; + } + + float absY = Mathf.Abs(vector.y); + if (absY > biggestAbsComponent) + { + biggestAbsComponent = absY; + } + + return biggestAbsComponent; + } + + public static float GetBiggestAbsComponent_butReassignTheSign(Vector3 vector) + { + float currentSign = 1.0f; + float biggestAbsComponent = 0.0f; + float absX = Mathf.Abs(vector.x); + if (absX > biggestAbsComponent) + { + biggestAbsComponent = absX; + currentSign = Mathf.Sign(vector.x); + } + + float absY = Mathf.Abs(vector.y); + if (absY > biggestAbsComponent) + { + biggestAbsComponent = absY; + currentSign = Mathf.Sign(vector.y); + } + + float absZ = Mathf.Abs(vector.z); + if (absZ > biggestAbsComponent) + { + biggestAbsComponent = absZ; + currentSign = Mathf.Sign(vector.z); + } + return (currentSign * biggestAbsComponent); + } + + public static float GetBiggestAbsComponent_butReassignTheSign(Vector3 vector, Dimension dimensionToExcludeFromCheck) + { + float currentSign = 1.0f; + float biggestAbsComponent = 0.0f; + + float absX; + float absY; + float absZ; + + switch (dimensionToExcludeFromCheck) + { + case Dimension.x: + + absY = Mathf.Abs(vector.y); + if (absY > biggestAbsComponent) + { + biggestAbsComponent = absY; + currentSign = Mathf.Sign(vector.y); + } + + absZ = Mathf.Abs(vector.z); + if (absZ > biggestAbsComponent) + { + biggestAbsComponent = absZ; + currentSign = Mathf.Sign(vector.z); + } + + break; + case Dimension.y: + + absX = Mathf.Abs(vector.x); + if (absX > biggestAbsComponent) + { + biggestAbsComponent = absX; + currentSign = Mathf.Sign(vector.x); + } + + absZ = Mathf.Abs(vector.z); + if (absZ > biggestAbsComponent) + { + biggestAbsComponent = absZ; + currentSign = Mathf.Sign(vector.z); + } + + break; + case Dimension.z: + + absX = Mathf.Abs(vector.x); + if (absX > biggestAbsComponent) + { + biggestAbsComponent = absX; + currentSign = Mathf.Sign(vector.x); + } + + absY = Mathf.Abs(vector.y); + if (absY > biggestAbsComponent) + { + biggestAbsComponent = absY; + currentSign = Mathf.Sign(vector.y); + } + + break; + default: + break; + } + + return (currentSign * biggestAbsComponent); + } + + public static float GetComponentByDimension(Vector3 vector, Dimension dimensionMarkingTheComponentToObtain) + { + switch (dimensionMarkingTheComponentToObtain) + { + case Dimension.x: + return vector.x; + case Dimension.y: + return vector.y; + case Dimension.z: + return vector.z; + default: + return 0.0f; + } + } + + public static Vector3 GetUnitVectorOfDimension(Dimension dimensionMarkingTheComponentToObtain) + { + switch (dimensionMarkingTheComponentToObtain) + { + case Dimension.x: + return Vector3.right; + case Dimension.y: + return Vector3.up; + case Dimension.z: + return Vector3.forward; + default: + return Vector3.zero; + } + } + + public static float GetSmallestComponent(Vector3 vector) + { + return Min(vector.x, vector.z, vector.z); + } + + static InternalDXXL_Plane plane_perpToLine = new InternalDXXL_Plane(); + public static Vector3 Get_aNormalizedVector_perpToGivenVector(Vector3 givenVector, InternalDXXL_Plane plane_inWhichPerpResultVectorPreferablyLies) + { + if (ApproximatelyZero(givenVector)) + { + return Vector3.up; + } + + Vector3 aNormalizedVector_perpToLine; + if ((plane_inWhichPerpResultVectorPreferablyLies == null) || Check_ifTwoVectorsAreApproxParallel_butCanHeadToDifferntDirs_expensiveButAccurate(givenVector, plane_inWhichPerpResultVectorPreferablyLies.normalDir)) + { + if (CheckIfVectorIsParallelToXAxis(givenVector)) + { + aNormalizedVector_perpToLine = Vector3.up; + } + else + { + if (CheckIfVectorIsParallelToYAxis(givenVector)) + { + aNormalizedVector_perpToLine = Vector3.right; + } + else + { + if (CheckIfVectorIsParallelToZAxis(givenVector)) + { + aNormalizedVector_perpToLine = Vector3.up; + } + else + { + if (ApproximatelyZero(givenVector.y)) + { + //line is perp to yAxis + aNormalizedVector_perpToLine = Vector3.up; + } + else + { + //line is not perp to yAxis + plane_perpToLine.Recreate(Vector3.zero, givenVector); + Vector3 aVector_perpToLine = plane_perpToLine.Get_projectionOfVectorOntoPlane(Vector3.up); + aNormalizedVector_perpToLine = GetNormalized_afterScalingIntoRegionOfFloatPrecicion(aVector_perpToLine); + } + } + } + } + } + else + { + //"plane_inWhichPerpResultVectorPreferablyLies" is not null, and "lineDir" is not perp to "plane_inWhichPerpResultVectorPreferablyLies": + Vector3 aVector_perpToLine_insidePlane = Vector3.Cross(givenVector, plane_inWhichPerpResultVectorPreferablyLies.normalDir); + aNormalizedVector_perpToLine = GetNormalized_afterScalingIntoRegionOfFloatPrecicion(aVector_perpToLine_insidePlane); + } + + if (ApproximatelyZero(aNormalizedVector_perpToLine)) + { + plane_perpToLine.Recreate(Vector3.zero, givenVector); + Vector3 aVector_perpToLine = plane_perpToLine.Get_projectionOfVectorOntoPlane(arbitrarySeldomDir_precalced); + aNormalizedVector_perpToLine = GetNormalized_afterScalingIntoRegionOfFloatPrecicion(aVector_perpToLine); + } + return aNormalizedVector_perpToLine; + } + + public static Vector3 Get_aNormalizedVector_perpToGivenVector(Vector3 givenVector) + { + if (ApproximatelyZero(givenVector.y)) + { + //line is horizonal (=perp to yAxis) / or zero + return Vector3.up; + } + else + { + //line is not horizontal + if (ApproximatelyZero(givenVector.x) && ApproximatelyZero(givenVector.z)) + { + //line is vertical + return Vector3.forward; + } + else + { + plane_perpToLine.Recreate(Vector3.zero, givenVector); + Vector3 projection_ofGlobalUpVector_alongLineDir_onto_perpToLinePlane = plane_perpToLine.Get_projectionOfVectorOntoPlane(Vector3.up); + return GetNormalized_afterScalingIntoRegionOfFloatPrecicion(projection_ofGlobalUpVector_alongLineDir_onto_perpToLinePlane); + } + } + } + + public static Vector3 Get_vector_projectedAlongOtherVectorToPerpToOtherVector(Vector3 vectorToProject, Vector3 otherVectorThatIsProjectionDir, bool tryNormalize) + { + if (ApproximatelyZero(otherVectorThatIsProjectionDir)) + { + return Vector3.forward; + } + else + { + plane_perpToLine.Recreate(Vector3.zero, otherVectorThatIsProjectionDir); + //Vector3 theVector_perpToRefVector = plane_perpToLine.Get_projectionOfVectorOntoPlane(vectorToProject); //-> since the plane is guaranteed "through zero origin" it is not needed to project "the whole vector", but it is sufficient to treat the vector as a point, and only project the point. This saves around 50% cpu operations. + Vector3 theVector_perpToRefVector = plane_perpToLine.Get_perpProjectionOfPointOnPlane(vectorToProject); + if (tryNormalize) + { + return GetNormalized_afterScalingIntoRegionOfFloatPrecicion(theVector_perpToRefVector); + } + else + { + return theVector_perpToRefVector; + } + } + } + + public static Vector3 GetApproxNormalized(Vector3 vectorToApproxNormalize) + { + //-> not tested yet if this is actually faster than "Vector3.Normalize()" + //-> Note that if the "vectorToApproxNormalize" is already normalized, then this will "denormalize" it. + float biggestAbsComponent = GetBiggestAbsComponent(vectorToApproxNormalize); + if (ApproximatelyZero(biggestAbsComponent)) + { + return Vector3.zero; + } + else + { + return (vectorToApproxNormalize / biggestAbsComponent); + } + } + + public static Vector3 GetApproxNormalized_afterScalingIntoRegionOfFloatPrecicion(Vector3 vectorToApproxNormalize) + { + vectorToApproxNormalize = ScaleNonZeroVectorIntoRegionOfFloatPrecision(vectorToApproxNormalize); + return GetApproxNormalized(vectorToApproxNormalize); + } + + + public static Vector3 OverwriteDefaultVectors(Vector3 vectorToOverwrite_ifDefault, Vector3 overwritingVector) + { + if (IsDefaultVector(vectorToOverwrite_ifDefault)) + { + return overwritingVector; + } + else + { + return vectorToOverwrite_ifDefault; + } + } + + public static Vector2 OverwriteDefaultVectors(Vector2 vectorToOverwrite_ifDefault, Vector2 overwritingVector) + { + if (IsDefaultVector(vectorToOverwrite_ifDefault)) + { + return overwritingVector; + } + else + { + return vectorToOverwrite_ifDefault; + } + } + + public static Quaternion OverwriteDefaultQuaternionToIdentity(Quaternion quaternionToOverwrite_ifDefault) + { + if (IsDefaultInvalidQuaternion(quaternionToOverwrite_ifDefault)) + { + return Quaternion.identity; + } + else + { + return quaternionToOverwrite_ifDefault; + } + } + + public static Vector2 ScaleNonZeroVectorIntoRegionOfFloatPrecision(Vector2 vectorToScale) + { + Vector2 scaledVector = vectorToScale; + for (int i = 0; i < 10; i++) + { + float biggestAbsComponent_ofScaledVector = GetBiggestAbsComponent(scaledVector); + if (biggestAbsComponent_ofScaledVector < 0.001f) + { + scaledVector = scaledVector * 1000.0f; + } + else + { + if (biggestAbsComponent_ofScaledVector > 100000.0f) + { + scaledVector = scaledVector * 0.001f; + } + else + { + break; + } + } + } + return scaledVector; + } + + public static Vector3 ScaleNonZeroVectorToApproxBiggerThanMinLength(Vector3 vectorToScale, float minLength) + { + Vector3 scaledVector = vectorToScale; + for (int i = 0; i < 10; i++) + { + //-> "GetBiggestAbsComponent()" is smaller than vector.magnitude -> therefore "*Approx*" in the function name + float biggestAbsComponent_ofScaledVector = GetBiggestAbsComponent(scaledVector); + if (biggestAbsComponent_ofScaledVector < minLength) + { + scaledVector = scaledVector * 1000.0f; + } + else + { + break; + } + } + return scaledVector; + } + + public static Vector3 ScaleNonZeroVectorIntoRegionOfFloatPrecision(Vector3 vectorToScale) + { + Vector3 scaledVector = vectorToScale; + for (int i = 0; i < 10; i++) + { + float biggestAbsComponent_ofScaledVector = GetBiggestAbsComponent(scaledVector); + if (biggestAbsComponent_ofScaledVector < 0.001f) + { + scaledVector = scaledVector * 1000.0f; + } + else + { + if (biggestAbsComponent_ofScaledVector > 100000.0f) + { + scaledVector = scaledVector * 0.001f; + } + else + { + break; + } + } + } + return scaledVector; + } + + public static bool CheckIfScaleToFloatPrecisionRegionFailed_meaningLineStayedTooShort(Vector3 previouslyScaledVectorToCheck) + { + return (GetBiggestAbsComponent(previouslyScaledVectorToCheck) < 0.001f); + } + + public static Vector3 ScaleNonZeroVectorIntoRegionOfFloatPrecision(Vector3 vectorToScale, out bool wasRescaled) + { + Vector3 scaledVector = vectorToScale; + wasRescaled = false; + for (int i = 0; i < 10; i++) + { + float biggestAbsComponent_ofScaledVector = GetBiggestAbsComponent(scaledVector); + if (biggestAbsComponent_ofScaledVector < 0.001f) + { + scaledVector = scaledVector * 1000.0f; + wasRescaled = true; + } + else + { + if (biggestAbsComponent_ofScaledVector > 100000.0f) + { + scaledVector = scaledVector * 0.001f; + wasRescaled = true; + } + else + { + break; + } + } + } + return scaledVector; + } + + public static Vector3 ScaleNonZeroVectorIntoRegionOfFloatPrecision(Vector3 vectorToScale, out bool wasRescaled, out float rescaleFactor) + { + Vector3 scaledVector = vectorToScale; + rescaleFactor = 1.0f; + wasRescaled = false; + for (int i = 0; i < 10; i++) + { + float biggestAbsComponent_ofScaledVector = GetBiggestAbsComponent(scaledVector); + if (biggestAbsComponent_ofScaledVector < 0.001f) + { + scaledVector = scaledVector * 1000.0f; + rescaleFactor = rescaleFactor * 1000.0f; + wasRescaled = true; + } + else + { + if (biggestAbsComponent_ofScaledVector > 100000.0f) + { + scaledVector = scaledVector * 0.001f; + rescaleFactor = rescaleFactor * 0.001f; + wasRescaled = true; + } + else + { + break; + } + } + } + return scaledVector; + } + + public static Vector2 ScaleNonZeroVectorIntoRegionOfFloatPrecision(Vector2 vectorToScale, out bool wasRescaled, out float rescaleFactor) + { + Vector2 scaledVector = vectorToScale; + rescaleFactor = 1.0f; + wasRescaled = false; + for (int i = 0; i < 10; i++) + { + float biggestAbsComponent_ofScaledVector = GetBiggestAbsComponent(scaledVector); + if (biggestAbsComponent_ofScaledVector < 0.001f) + { + scaledVector = scaledVector * 1000.0f; + rescaleFactor = rescaleFactor * 1000.0f; + wasRescaled = true; + } + else + { + if (biggestAbsComponent_ofScaledVector > 100000.0f) + { + scaledVector = scaledVector * 0.001f; + rescaleFactor = rescaleFactor * 0.001f; + wasRescaled = true; + } + else + { + break; + } + } + } + return scaledVector; + } + + public static Vector2 GetNormalized_afterScalingIntoRegionOfFloatPrecicion(Vector2 vectorToNormalize) + { + //the build-in ".normalize" function has problems with very small or very big vectors (and returns zero-vectors for those). This can be fixed by scaling the vectorToNormalize before the actual normalizing. + vectorToNormalize = ScaleNonZeroVectorIntoRegionOfFloatPrecision(vectorToNormalize); + return vectorToNormalize.normalized; + } + + public static Vector2 GetNormalized_afterScalingIntoRegionOfFloatPrecicion(Vector2 vectorToNormalize, out float magnitudeOfUnscaledOriginalVector) + { + //the build-in ".normalize" function has problems with very small or very big vectors (and returns zero-vectors for those). This can be fixed by scaling the vectorToNormalize before the actual normalizing. + bool wasRescaled; + float rescaleFactor; + vectorToNormalize = ScaleNonZeroVectorIntoRegionOfFloatPrecision(vectorToNormalize, out wasRescaled, out rescaleFactor); + float magnitude_ofScaledVector = vectorToNormalize.magnitude; + magnitudeOfUnscaledOriginalVector = wasRescaled ? (magnitude_ofScaledVector / rescaleFactor) : magnitude_ofScaledVector; + + if (ApproximatelyZero(magnitude_ofScaledVector)) + { + return Vector2.zero; + } + else + { + return vectorToNormalize / magnitude_ofScaledVector; + } + } + + public static Vector3 GetNormalized_afterScalingIntoRegionOfFloatPrecicion(Vector3 vectorToNormalize) + { + //the build-in ".normalize" function has problems with very small or very big vectors (and returns zero-vectors for those). This can be fixed by scaling the vectorToNormalize before the actual normalizing. + vectorToNormalize = ScaleNonZeroVectorIntoRegionOfFloatPrecision(vectorToNormalize); + return vectorToNormalize.normalized; + } + + public static Vector3 GetNormalized_afterScalingIntoRegionOfFloatPrecicion(Vector3 vectorToNormalize, out float magnitudeOfUnscaledOriginalVector) + { + //the build-in ".normalize" function has problems with very small or very big vectors (and returns zero-vectors for those). This can be fixed by scaling the vectorToNormalize before the actual normalizing. + bool wasRescaled; + float rescaleFactor; + vectorToNormalize = ScaleNonZeroVectorIntoRegionOfFloatPrecision(vectorToNormalize, out wasRescaled, out rescaleFactor); + float magnitude_ofScaledVector = vectorToNormalize.magnitude; + magnitudeOfUnscaledOriginalVector = wasRescaled ? (magnitude_ofScaledVector / rescaleFactor) : magnitude_ofScaledVector; + + if (ApproximatelyZero(magnitude_ofScaledVector)) + { + return Vector3.zero; + } + else + { + return vectorToNormalize / magnitude_ofScaledVector; + } + } + + public static bool CheckIfNormalizationFailed_meaningLineStayedTooShort(Vector3 previouslyNormalizedVectorToCheck) + { + return (GetBiggestAbsComponent(previouslyNormalizedVectorToCheck) < 0.1f); + } + + public static bool CheckIfNormalizationFailed_meaningLineStayedTooShort(Vector2 previouslyNormalizedVectorToCheck) + { + return (GetBiggestAbsComponent(previouslyNormalizedVectorToCheck) < 0.1f); + } + + public static float GetHighestXComponent(Vector3[] vertices) + { + //collection has to have at least 1 item + float highestX = vertices[0].x; + for (int i = 1; i < vertices.Length; i++) + { + highestX = Mathf.Max(highestX, vertices[i].x); + } + return highestX; + } + + public static float GetLowestXComponent(Vector3[] vertices) + { + //collection has to have at least 1 item + float lowestX = vertices[0].x; + for (int i = 1; i < vertices.Length; i++) + { + lowestX = Mathf.Min(lowestX, vertices[i].x); + } + return lowestX; + } + + public static float GetHighestYComponent(Vector3[] vertices) + { + //collection has to have at least 1 item + float highestY = vertices[0].y; + for (int i = 1; i < vertices.Length; i++) + { + highestY = Mathf.Max(highestY, vertices[i].y); + } + return highestY; + } + + public static float GetLowestYComponent(Vector3[] vertices) + { + //collection has to have at least 1 item + float lowestY = vertices[0].y; + for (int i = 1; i < vertices.Length; i++) + { + lowestY = Mathf.Min(lowestY, vertices[i].y); + } + return lowestY; + } + + public static float GetHighestZComponent(Vector3[] vertices) + { + //collection has to have at least 1 item + float highestZ = vertices[0].z; + for (int i = 1; i < vertices.Length; i++) + { + highestZ = Mathf.Max(highestZ, vertices[i].z); + } + return highestZ; + } + + public static float GetLowestZComponent(Vector3[] vertices) + { + //collection has to have at least 1 item + float lowestZ = vertices[0].z; + for (int i = 1; i < vertices.Length; i++) + { + lowestZ = Mathf.Min(lowestZ, vertices[i].z); + } + return lowestZ; + } + + public static float GetHighestXComponent(List vertices) + { + //collection has to have at least 1 item + float highestX = vertices[0].x; + for (int i = 1; i < vertices.Count; i++) + { + highestX = Mathf.Max(highestX, vertices[i].x); + } + return highestX; + } + + public static float GetLowestXComponent(List vertices) + { + //collection has to have at least 1 item + float lowestX = vertices[0].x; + for (int i = 1; i < vertices.Count; i++) + { + lowestX = Mathf.Min(lowestX, vertices[i].x); + } + return lowestX; + } + + public static float GetHighestYComponent(List vertices) + { + //collection has to have at least 1 item + float highestY = vertices[0].y; + for (int i = 1; i < vertices.Count; i++) + { + highestY = Mathf.Max(highestY, vertices[i].y); + } + return highestY; + } + + public static float GetLowestYComponent(List vertices) + { + //collection has to have at least 1 item + float lowestY = vertices[0].y; + for (int i = 1; i < vertices.Count; i++) + { + lowestY = Mathf.Min(lowestY, vertices[i].y); + } + return lowestY; + } + + public static float GetHighestZComponent(List vertices) + { + //collection has to have at least 1 item + float highestZ = vertices[0].z; + for (int i = 1; i < vertices.Count; i++) + { + highestZ = Mathf.Max(highestZ, vertices[i].z); + } + return highestZ; + } + + public static float GetLowestZComponent(List vertices) + { + //collection has to have at least 1 item + float lowestZ = vertices[0].z; + for (int i = 1; i < vertices.Count; i++) + { + lowestZ = Mathf.Min(lowestZ, vertices[i].z); + } + return lowestZ; + } + + public static float GetHighestXComponent(List vertices, int usedSlotsInList) + { + //collection has to have at least 1 item + float highestX = vertices[0].x; + for (int i = 1; i < usedSlotsInList; i++) + { + highestX = Mathf.Max(highestX, vertices[i].x); + } + return highestX; + } + + public static float GetLowestXComponent(List vertices, int usedSlotsInList) + { + //collection has to have at least 1 item + float lowestX = vertices[0].x; + for (int i = 1; i < usedSlotsInList; i++) + { + lowestX = Mathf.Min(lowestX, vertices[i].x); + } + return lowestX; + } + + public static float GetHighestYComponent(List vertices, int usedSlotsInList) + { + //collection has to have at least 1 item + float highestY = vertices[0].y; + for (int i = 1; i < usedSlotsInList; i++) + { + highestY = Mathf.Max(highestY, vertices[i].y); + } + return highestY; + } + + public static float GetLowestYComponent(List vertices, int usedSlotsInList) + { + //collection has to have at least 1 item + float lowestY = vertices[0].y; + for (int i = 1; i < usedSlotsInList; i++) + { + lowestY = Mathf.Min(lowestY, vertices[i].y); + } + return lowestY; + } + + public static float GetHighestZComponent(List vertices, int usedSlotsInList) + { + //collection has to have at least 1 item + float highestZ = vertices[0].z; + for (int i = 1; i < usedSlotsInList; i++) + { + highestZ = Mathf.Max(highestZ, vertices[i].z); + } + return highestZ; + } + + public static float GetLowestZComponent(List vertices, int usedSlotsInList) + { + //collection has to have at least 1 item + float lowestZ = vertices[0].z; + for (int i = 1; i < usedSlotsInList; i++) + { + lowestZ = Mathf.Min(lowestZ, vertices[i].z); + } + return lowestZ; + } + + public static float GetHighestXComponent(Vector2[] vertices) + { + //collection has to have at least 1 item + float highestX = vertices[0].x; + for (int i = 1; i < vertices.Length; i++) + { + highestX = Mathf.Max(highestX, vertices[i].x); + } + return highestX; + } + + public static float GetLowestXComponent(Vector2[] vertices) + { + //collection has to have at least 1 item + float lowestX = vertices[0].x; + for (int i = 1; i < vertices.Length; i++) + { + lowestX = Mathf.Min(lowestX, vertices[i].x); + } + return lowestX; + } + + public static float GetHighestYComponent(Vector2[] vertices) + { + //collection has to have at least 1 item + float highestY = vertices[0].y; + for (int i = 1; i < vertices.Length; i++) + { + highestY = Mathf.Max(highestY, vertices[i].y); + } + return highestY; + } + + public static float GetLowestYComponent(Vector2[] vertices) + { + //collection has to have at least 1 item + float lowestY = vertices[0].y; + for (int i = 1; i < vertices.Length; i++) + { + lowestY = Mathf.Min(lowestY, vertices[i].y); + } + return lowestY; + } + + public static float GetHighestXComponent(List vertices) + { + //collection has to have at least 1 item + float highestX = vertices[0].x; + for (int i = 1; i < vertices.Count; i++) + { + highestX = Mathf.Max(highestX, vertices[i].x); + } + return highestX; + } + + public static float GetLowestXComponent(List vertices) + { + //collection has to have at least 1 item + float lowestX = vertices[0].x; + for (int i = 1; i < vertices.Count; i++) + { + lowestX = Mathf.Min(lowestX, vertices[i].x); + } + return lowestX; + } + + public static float GetHighestYComponent(List vertices) + { + //collection has to have at least 1 item + float highestY = vertices[0].y; + for (int i = 1; i < vertices.Count; i++) + { + highestY = Mathf.Max(highestY, vertices[i].y); + } + return highestY; + } + + public static float GetLowestYComponent(List vertices) + { + //collection has to have at least 1 item + float lowestY = vertices[0].y; + for (int i = 1; i < vertices.Count; i++) + { + lowestY = Mathf.Min(lowestY, vertices[i].y); + } + return lowestY; + } + + public static Vector3 GetNearestVertex(Vector3 refPos, List verticesToChooseFrom, int usedSlotsInList) + { + //collection has to have at least 1 item + Vector3 nearestVertex = verticesToChooseFrom[0]; + float nearestDistanceSqr = (refPos - verticesToChooseFrom[0]).sqrMagnitude; + for (int i = 1; i < usedSlotsInList; i++) + { + float currDistanceSqr = (refPos - verticesToChooseFrom[i]).sqrMagnitude; + if (currDistanceSqr < nearestDistanceSqr) + { + nearestVertex = verticesToChooseFrom[i]; + nearestDistanceSqr = currDistanceSqr; + } + } + return nearestVertex; + } + + public static Vector2 GetNearestVertex(Vector2 refPos, List verticesToChooseFrom, int usedSlotsInList) + { + //collection has to have at least 1 item + Vector2 nearestVertex = verticesToChooseFrom[0]; + float nearestDistanceSqr = (refPos - verticesToChooseFrom[0]).sqrMagnitude; + for (int i = 1; i < usedSlotsInList; i++) + { + float currDistanceSqr = (refPos - verticesToChooseFrom[i]).sqrMagnitude; + if (currDistanceSqr < nearestDistanceSqr) + { + nearestVertex = verticesToChooseFrom[i]; + nearestDistanceSqr = currDistanceSqr; + } + } + return nearestVertex; + } + + public static bool IsVectorApproxUniform(Vector3 vector) + { + if (CheckIfValueLiesInsideDistanceNearAnotherValue(vector.x, vector.y, 0.001f)) + { + if (CheckIfValueLiesInsideDistanceNearAnotherValue(vector.x, vector.z, 0.001f)) + { + return true; + } + } + return false; + } + + public static bool IsVectorApproxUniform(Vector2 vector) + { + return CheckIfValueLiesInsideDistanceNearAnotherValue(vector.x, vector.y, 0.001f); + } + + public static bool ContainsNegativeComponents(Vector3 vector) + { + return (vector.x < 0.0f || vector.y < 0.0f || vector.z < 0.0f); + } + + public static bool ContainsNegativeComponents(Vector2 vector) + { + return (vector.x < 0.0f || vector.y < 0.0f); + } + + public static bool ContainsZeroComponents(Vector3 vector) + { + return (ApproximatelyZero(vector.x) || ApproximatelyZero(vector.y) || ApproximatelyZero(vector.z)); + } + + public static bool ContainsZeroComponentsInXorY(Vector3 vector) + { + return (ApproximatelyZero(vector.x) || ApproximatelyZero(vector.y)); + } + + public static float Loop_floatIntoSpanFrom_0_to_1(float floatValue_thatMayBeOutside_spanFrom0to1) + { + if (floatValue_thatMayBeOutside_spanFrom0to1 > 0.0f) + { + return (floatValue_thatMayBeOutside_spanFrom0to1 - (float)Mathf.FloorToInt(floatValue_thatMayBeOutside_spanFrom0to1)); + } + else + { + return ((floatValue_thatMayBeOutside_spanFrom0to1 - (float)Mathf.CeilToInt(floatValue_thatMayBeOutside_spanFrom0to1)) + 1.0f); + } + } + + public static float Loop_floatIntoSpanFrom_m1_to_p1(float floatValue_thatMayBeOutside_spanFrom_m10_to_p1) + { + if (floatValue_thatMayBeOutside_spanFrom_m10_to_p1 > 0.0f) + { + return (floatValue_thatMayBeOutside_spanFrom_m10_to_p1 - (float)Mathf.FloorToInt(floatValue_thatMayBeOutside_spanFrom_m10_to_p1)); + } + else + { + return (floatValue_thatMayBeOutside_spanFrom_m10_to_p1 - (float)Mathf.CeilToInt(floatValue_thatMayBeOutside_spanFrom_m10_to_p1)); + } + } + + public static float Loop_floatIntoSpanFrom_0_to_x(float floatValue_thatMayBeOutside_spanFrom_0_to_x, float xThreshold) + { + float floatStartValue_normalized = floatValue_thatMayBeOutside_spanFrom_0_to_x / xThreshold; + float loopedTo_0_to_1 = Loop_floatIntoSpanFrom_0_to_1(floatStartValue_normalized); + return (loopedTo_0_to_1 * xThreshold); + } + + public static float Loop_floatIntoSpanFrom_mX_to_pX(float floatValue_thatMayBeOutside_spanFrom_mX_to_pX, float xThreshold) + { + float floatStartValue_normalized = floatValue_thatMayBeOutside_spanFrom_mX_to_pX / xThreshold; + float loopedTo_m1_to_p1 = Loop_floatIntoSpanFrom_m1_to_p1(floatStartValue_normalized); + return (loopedTo_m1_to_p1 * xThreshold); + } + + public static int LoopOvershootingIndexIntoCollectionSize(int intValueToLoop, int collectionCount) + { + //-> works only for values not farer than one loopspan away + if (intValueToLoop < 0) + { + return (intValueToLoop + collectionCount); + } + else + { + if (intValueToLoop < collectionCount) + { + return intValueToLoop; + } + else + { + return (intValueToLoop - collectionCount); + } + } + } + + public static float Get_jumpFlyCurve_withPlateau(float given_x, float startOfPlateau, float endOfPlateau) + { + if (given_x < startOfPlateau) + { + return Get_2degParabolicFlateningRise(given_x / startOfPlateau); + } + else + { + if (given_x > endOfPlateau) + { + float lengthOfEndSegment = 1.0f - endOfPlateau; + return Get_2degParabolicSteepeningDecay((given_x - endOfPlateau) / lengthOfEndSegment); + } + else + { + return 1.0f; + } + } + } + + public static float Get_2degParabolicSteepeningRise(float given_x) + { + return (given_x * given_x); + } + + public static float Get_3degParabolicSteepeningRise(float given_x) + { + return (given_x * given_x * given_x); + } + + public static float Get_4degParabolicSteepeningRise(float given_x) + { + return (given_x * given_x * given_x * given_x); + } + + public static float Get_2degParabolicFlateningRise(float given_x) + { + float x_minus1 = (given_x - 1.0f); + return (-x_minus1 * x_minus1 + 1.0f); + } + + public static float Get_2degParabolicFlateningRise_flatRightOfOne(float given_x) + { + if (given_x >= 1.0f) + { + return 1.0f; + } + else + { + return Get_2degParabolicFlateningRise(given_x); + } + } + + public static float Get_3degParabolicFlateningRise(float given_x) + { + float x_minus1 = (given_x - 1.0f); + return (x_minus1 * x_minus1 * x_minus1 + 1.0f); + } + + public static float Get_4degParabolicFlateningRise(float given_x) + { + float x_minus1 = (given_x - 1.0f); + return (-x_minus1 * x_minus1 * x_minus1 * x_minus1 + 1.0f); + } + + public static float Get_2degParabolicSteepeningDecay(float given_x) + { + return (-(given_x * given_x) + 1.0f); + } + + public static float GetDecimalOrderOfMagnitudeAtLowerEnd(float value_forWhichToGetTheDecimalOrderOnTheLowerSide, out float inverseOfReturnValue, out bool calculationWasSuccesful) + { + calculationWasSuccesful = true; + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 1.0f) + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 10.0f) + { + inverseOfReturnValue = 1.0f; + return 1.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 100.0f) + { + inverseOfReturnValue = 0.1f; + return 10.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 1000.0f) + { + inverseOfReturnValue = 0.01f; + return 100.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 10000.0f) + { + inverseOfReturnValue = 0.001f; + return 1000.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 100000.0f) + { + inverseOfReturnValue = 0.0001f; + return 10000.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 1000000.0f) + { + inverseOfReturnValue = 0.00001f; + return 100000.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 10000000.0f) + { + inverseOfReturnValue = 0.000001f; + return 1000000.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 100000000.0f) + { + inverseOfReturnValue = 0.0000001f; + return 10000000.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 1000000000.0f) + { + inverseOfReturnValue = 0.00000001f; + return 100000000.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 10000000000.0f) + { + inverseOfReturnValue = 0.000000001f; + return 1000000000.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 100000000000.0f) + { + inverseOfReturnValue = 0.0000000001f; + return 10000000000.0f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide < 1000000000000.0f) + { + inverseOfReturnValue = 0.00000000001f; + return 100000000000.0f; + } + else + { + float decimalOrderOfMagnitudeAtLowerEnd_viaLog10 = GetDecimalOrderOfMagnitudeAtLowerEnd_viaLog10(value_forWhichToGetTheDecimalOrderOnTheLowerSide); + inverseOfReturnValue = 1.0f / decimalOrderOfMagnitudeAtLowerEnd_viaLog10; + return decimalOrderOfMagnitudeAtLowerEnd_viaLog10; + } + } + } + } + } + } + } + } + } + } + } + } + } + else + { + //-> value_forWhichToGetTheDecimalOrderOnTheLowerSide < 1.0f + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.1f) + { + inverseOfReturnValue = 10.0f; + return 0.1f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.01f) + { + inverseOfReturnValue = 100.0f; + return 0.01f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.001f) + { + inverseOfReturnValue = 1000.0f; + return 0.001f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.0001f) + { + inverseOfReturnValue = 10000.0f; + return 0.0001f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.00001f) + { + inverseOfReturnValue = 100000.0f; + return 0.00001f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.000001f) + { + inverseOfReturnValue = 1000000.0f; + return 0.000001f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.0000001f) + { + inverseOfReturnValue = 10000000.0f; + return 0.0000001f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.00000001f) + { + inverseOfReturnValue = 100000000.0f; + return 0.00000001f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.000000001f) + { + inverseOfReturnValue = 1000000000.0f; + return 0.000000001f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.0000000001f) + { + inverseOfReturnValue = 10000000000.0f; + return 0.0000000001f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.00000000001f) + { + inverseOfReturnValue = 100000000000.0f; + return 0.00000000001f; + } + else + { + if (value_forWhichToGetTheDecimalOrderOnTheLowerSide >= 0.000000000001f) + { + inverseOfReturnValue = 1000000000000.0f; + return 0.000000000001f; + } + else + { + calculationWasSuccesful = false; + inverseOfReturnValue = 1.0f; + return 1.0f; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + public static float GetDecimalOrderOfMagnitudeAtLowerEnd_viaLog10(float value_forWhichToGetTheDecimalOrderOnTheLowerSide) + { + float log10ofValue = Mathf.Log10(value_forWhichToGetTheDecimalOrderOnTheLowerSide); + float log10ofValue_floorInt = Mathf.Floor(log10ofValue); + return Mathf.Pow(10.0f, log10ofValue_floorInt); + } + + public static float AcuteAngle_0to90(Vector3 from, Vector3 to) + { + float angleDeg_0to180 = Vector3.Angle(from, to); + if (angleDeg_0to180 > 90.0f) + { + return (180.0f - angleDeg_0to180); + } + else + { + return angleDeg_0to180; + } + } + + public static float GetCenterBetweenTwoFloats(float float1, float float2) + { + return 0.5f * (float1 + float2); + } + + public static Vector3 GetCenterBetweenTwoPoints(Vector3 point1, Vector3 point2) + { + return 0.5f * (point1 + point2); + } + + public static float GetAverageBoxExtent(Vector3 boxDimensions) + { + return 0.3333f * (boxDimensions.x + boxDimensions.y + boxDimensions.z); + } + + public static float GetAverageBoxExtent(Vector2 boxDimensions) + { + return 0.5f * (boxDimensions.x + boxDimensions.y); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Math.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Math.cs.meta new file mode 100644 index 0000000..c188ba9 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Math.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2fd2d1388619c5a4abbbffea9f1b5873 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements.cs new file mode 100644 index 0000000..b173ee8 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements.cs @@ -0,0 +1,462 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_Measurements + { + public enum DistanceSpecifyingStringType { point_point, point_line, line_line, point_ll_point, point_l_I_l_point, point_plane, plane_plane }; + + static float angleDeg_markingALineBreakAfterAFloatPlusTheDegreeSign = 45.5f; //-> is roughly optimized that a float with all digits plus a "°" are in one line, then the linebreak for the rad-display. Though not fully stable in this regard. + + public static float Distance(bool is2D, DistanceSpecifyingStringType distanceSpecifyingStringType, Vector3 from, Vector3 to, Color color, float lineWidth, string text, float coneLength, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(from, "from")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(to, "to")) { return 0.0f; } + + //fallback for "distance=zero" -> The called "Draw.Vector()" function already displays a comprehensible fallback + + Vector3 startToEnd = to - from; + float distance = startToEnd.magnitude; + if (skipDraw) { return distance; } + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return distance; } + + lineWidth = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth); + + //assuring that text is always from left to right: + Vector3 drawnVectorsStartPos; + Vector3 drawnVectorsEndPos; + if (from.x < to.x) + { + drawnVectorsStartPos = from; + drawnVectorsEndPos = to; + } + else + { + drawnVectorsStartPos = to; + drawnVectorsEndPos = from; + } + + string finalTextAtLine = string.IsNullOrEmpty(text) ? (GetDistanceSpecifyingDistancePrefixString(distanceSpecifyingStringType) + distance) : (GetDistanceSpecifyingDistancePrefixString(distanceSpecifyingStringType) + distance + "

" + text); + + UtilitiesDXXL_DrawBasics.Set_relSizeOfTextOnLines_reversible(0.65f); + UtilitiesDXXL_DrawBasics.Set_shiftTextPosOnLines_toNonIntersecting_reversible(true); + DrawBasics.Vector(drawnVectorsStartPos, drawnVectorsEndPos, color, lineWidth, finalTextAtLine, coneLength, true, is2D, default(Vector3), false, enlargeSmallTextToThisMinTextSize, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_relSizeOfTextOnLines(); + UtilitiesDXXL_DrawBasics.Reverse_shiftTextPosOnLines_toNonIntersecting(); + + Color anchorPoint1Color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawMeasurements.defaultColor1, 0.3f); + Color anchorPoint2Color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawMeasurements.defaultColor2, 0.3f); + DrawBasics.Point(from, null, anchorPoint1Color, 0.1f * distance, 0.0f, anchorPoint1Color, Quaternion.identity, false, true, is2D, durationInSec, hiddenByNearerObjects); + DrawBasics.Point(to, null, anchorPoint2Color, 0.1f * distance, 0.0f, anchorPoint2Color, Quaternion.identity, false, true, is2D, durationInSec, hiddenByNearerObjects); + + return distance; + } + + static string GetDistanceSpecifyingDistancePrefixString(DistanceSpecifyingStringType distanceSpecifyingStringType) + { + switch (distanceSpecifyingStringType) + { + case DistanceSpecifyingStringType.point_point: + return "POINT-POINTdistance =
"; + + case DistanceSpecifyingStringType.point_line: + return "POINT-LINEdistance =
"; + + case DistanceSpecifyingStringType.line_line: + return "LINE-LINEdistance =
"; + + case DistanceSpecifyingStringType.point_ll_point: + return "POINT||POINTdistance =
"; + + case DistanceSpecifyingStringType.point_l_I_l_point: + return "POINT|=|POINTdistance =
"; + + case DistanceSpecifyingStringType.point_plane: + return "POINT-PLANEdistance =
"; + + case DistanceSpecifyingStringType.plane_plane: + return "PLANE-PLANEdistance =
"; + + default: + return "distance =
"; + } + } + + + public static float Angle(bool boldTextDisplay, bool is2D, bool pointerAtBothSides, Vector3 from, Vector3 to, Vector3 turnCenter, Color color, float forceRadius, float lineWidth, string text, bool useReflexAngleOver180deg, bool displayRadInsteadOfDeg, float coneLength, bool drawBoundaryLines, bool addTextForAlternativeAngleUnit, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(from, "from")) { return 0.0f; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(to, "to")) { return 0.0f; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(turnCenter, "turnCenter")) { return 0.0f; } + + lineWidth = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth); + + if (UtilitiesDXXL_Math.ApproximatelyZero(from)) + { + UtilitiesDXXL_DrawBasics.PointFallback(turnCenter, "[ Angle with startVectorLength of 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(to)) + { + UtilitiesDXXL_DrawBasics.PointFallback(turnCenter, "[ Angle with endVectorLength of 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + Vector3 from_scaledIntoRegionOfFloatPrecision = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(from); + Vector3 to_scaledIntoRegionOfFloatPrecision = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(to); + + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(from_scaledIntoRegionOfFloatPrecision) < 0.0001f) + { + UtilitiesDXXL_DrawBasics.PointFallback(turnCenter, "[ Angle with startVectorLength near 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(to_scaledIntoRegionOfFloatPrecision) < 0.0001f) + { + UtilitiesDXXL_DrawBasics.PointFallback(turnCenter, "[ Angle with endVectorLength near 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + return 0.0f; + } + + float angleDeg = Vector3.Angle(from_scaledIntoRegionOfFloatPrecision, to_scaledIntoRegionOfFloatPrecision); + if (useReflexAngleOver180deg) + { + angleDeg = 360.0f - angleDeg; + } + float angleRad = angleDeg * Mathf.Deg2Rad; + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) + { + return ReturnAngleInCorrectUnit(angleRad, angleDeg, displayRadInsteadOfDeg); + } + + Color smallRepresenationColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.5f); + string mainValueRepresentationText; + string minorValueRepresentationText = null; + if (displayRadInsteadOfDeg) + { + mainValueRepresentationText = "" + angleRad + " rad"; + if (addTextForAlternativeAngleUnit) + { + minorValueRepresentationText = "(" + angleDeg + "°)"; + } + } + else + { + mainValueRepresentationText = "" + angleDeg + "°"; + if (addTextForAlternativeAngleUnit) + { + minorValueRepresentationText = "(" + angleRad + " rad)"; + } + } + + string angleText; + if (UtilitiesDXXL_Math.ApproximatelyZero(angleDeg)) + { + //-> fallback information: + angleText = "Angle measurement with result: " + mainValueRepresentationText + minorValueRepresentationText + "
" + text; + } + else + { + if (boldTextDisplay) + { + angleText = "" + mainValueRepresentationText + minorValueRepresentationText + "
" + text; + } + else + { + angleText = "" + mainValueRepresentationText + minorValueRepresentationText + "
" + text; + } + } + + if (is2D) + { + DrawBasics2D.VectorCircled(turnCenter, from, to, color, forceRadius, lineWidth, angleText, useReflexAngleOver180deg, turnCenter.z, coneLength, false, pointerAtBothSides, angleDeg_markingALineBreakAfterAFloatPlusTheDegreeSign, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); + } + else + { + DrawBasics.VectorCircled(turnCenter, from, to, color, forceRadius, lineWidth, angleText, useReflexAngleOver180deg, coneLength, pointerAtBothSides, false, true, angleDeg_markingALineBreakAfterAFloatPlusTheDegreeSign, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); + } + + if (drawBoundaryLines) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(forceRadius, "forceRadius")) + { + return ReturnAngleInCorrectUnit(angleRad, angleDeg, displayRadInsteadOfDeg); + } + + Vector3 from_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(from, out float from_magnitude); + Vector3 to_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(to); + float radius = UtilitiesDXXL_Math.ApproximatelyZero(forceRadius) ? from_magnitude : forceRadius; + radius = Mathf.Abs(radius); + + if (radius > 0.0f) + { + Color colorOfFromLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawMeasurements.defaultColor1, 0.2f); + Color colorOfToLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawMeasurements.defaultColor2, 0.2f); + Line_fadeableAnimSpeed.InternalDraw(turnCenter, turnCenter + from_normalized * radius * 1.1f, colorOfFromLine, 0.0f, null, DrawBasics.LineStyle.dashedLong, radius * 1.022f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed.InternalDraw(turnCenter, turnCenter + to_normalized * radius * 1.1f, colorOfToLine, 0.0f, null, DrawBasics.LineStyle.dashedLong, radius * 1.022f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + Vector3 turnAxis = Vector3.Cross(from_normalized, to_normalized); + if (UtilitiesDXXL_Math.ApproximatelyZero(turnAxis) == false) + { + Vector3 turnAxis_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(turnAxis); + float lenghtOfTurnAxisDisplayLine = radius * 0.1f; + float halfLenghtOfTurnAxisDisplayLine = 0.5f * lenghtOfTurnAxisDisplayLine; + Color colorOfTurnAxisDisplay = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.2f); + Line_fadeableAnimSpeed.InternalDraw(turnCenter - turnAxis_normalized * halfLenghtOfTurnAxisDisplayLine, turnCenter + turnAxis_normalized * halfLenghtOfTurnAxisDisplayLine, colorOfTurnAxisDisplay, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + + return ReturnAngleInCorrectUnit(angleRad, angleDeg, displayRadInsteadOfDeg); + } + + static float ReturnAngleInCorrectUnit(float angleRad, float angleDeg, bool displayRadInsteadOfDeg) + { + if (displayRadInsteadOfDeg) + { + return angleRad; + } + else + { + return angleDeg; + } + } + + public static void WriteLineNameAtProjectionPlumbPos(bool is2D, string lineName, string fallbackLineName, string stringPrefix, Vector3 projectionToLineOrigin, float distance_projectionToLineOrigin, Vector3 pointPreProjection_forTextUp, InternalDXXL_Line line, Vector3 pointsProjectionOntoLine, float textSize, Color color, bool alignedCenter, float durationInSec, bool hiddenByNearerObjects) + { + // float lineDirection_magnitude = line.direction.magnitude; + if (distance_projectionToLineOrigin > line.length || UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(projectionToLineOrigin, line.direction_normalized)) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(distance_projectionToLineOrigin) == false) + { + Vector3 projectionToLineOrigin_normalized = projectionToLineOrigin / distance_projectionToLineOrigin; + string lineIdentifyingText = ((lineName == null) || (lineName == "")) ? fallbackLineName : lineName; + lineIdentifyingText = stringPrefix + lineIdentifyingText; + textSize = Mathf.Max(textSize, 0.001f); + Vector3 textDir = line.origin - pointsProjectionOntoLine; + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(textDir) < 0.0001f) + { + textDir = UtilitiesDXXL_Math.arbitrarySeldomDir_normalized_precalced; + } + Vector3 textUp = pointsProjectionOntoLine - pointPreProjection_forTextUp; + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(textUp) < 0.0001f) + { + textUp = UtilitiesDXXL_Math.arbitrarySeldomDir2_precalced; + } + bool textDirHasBeenSwitched = false; + if (is2D) + { + if (textUp.y > 0.0f) + { + if (textDir.x < 0.0f) + { + textDir = -textDir; + textDirHasBeenSwitched = true; + } + } + else + { + if (textDir.x > 0.0f) + { + textDir = -textDir; + textDirHasBeenSwitched = true; + } + } + } + UtilitiesDXXL_Text.Write(lineIdentifyingText, pointsProjectionOntoLine, color, textSize, textDir, textUp, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, true, is2D, false); + float lengthOfLongestLine_ofLineIdentifyingText = DrawText.parsedTextSpecs.widthOfLongestLine; + if (alignedCenter == false) + { + lengthOfLongestLine_ofLineIdentifyingText = 0.0f; + } + Vector3 textPos = textDirHasBeenSwitched ? (pointsProjectionOntoLine + projectionToLineOrigin_normalized * (0.5f * lengthOfLongestLine_ofLineIdentifyingText)) : (pointsProjectionOntoLine - projectionToLineOrigin_normalized * (0.5f * lengthOfLongestLine_ofLineIdentifyingText)); + UtilitiesDXXL_Text.WriteFramed(lineIdentifyingText, textPos, color, textSize, textDir, textUp, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + } + } + + public static void Draw90degSymbol(float distance, Vector3 pointsProjectionOntoLine, Vector3 pointPreProjection, Vector3 lineDirPerpToMeasuredDistance_normalized, Color color, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(distance) == false) + { + float size_of90DegSymbol = 0.25f; + size_of90DegSymbol = Mathf.Min(size_of90DegSymbol, 0.25f * distance); + Vector3 projectionToPoint = pointPreProjection - pointsProjectionOntoLine; + Vector3 projectionToPoint_normalized = projectionToPoint / distance; + Vector3 symbolFor90deg_firstPoint = pointsProjectionOntoLine + lineDirPerpToMeasuredDistance_normalized * size_of90DegSymbol; + Vector3 symbolFor90deg_middlePoint = pointsProjectionOntoLine + lineDirPerpToMeasuredDistance_normalized * size_of90DegSymbol + projectionToPoint_normalized * size_of90DegSymbol; + Vector3 symbolFor90deg_thirdPoint = pointsProjectionOntoLine + projectionToPoint_normalized * size_of90DegSymbol; + Line_fadeableAnimSpeed.InternalDraw(symbolFor90deg_firstPoint, symbolFor90deg_middlePoint, color, 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(symbolFor90deg_thirdPoint, symbolFor90deg_middlePoint, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + + public static void ChooseColorAndStyleForDistanceThresholdLine(ref Color usedColor, ref DrawBasics.LineStyle usedLineStyle, float distance, float thresholdDistance, bool exactlyThresholdLength_countsAsShorter, DrawBasics.LineStyle overwriteStyle_forNear, DrawBasics.LineStyle overwriteStyle_forFar, Color overwriteColor_forNear, Color overwriteColor_forFar) + { + if (exactlyThresholdLength_countsAsShorter) + { + if (distance <= thresholdDistance) + { + usedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forNear, UtilitiesDXXL_Colors.red_boolFalse); + usedLineStyle = overwriteStyle_forNear; + } + else + { + usedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forFar, UtilitiesDXXL_Colors.green_boolTrue); + usedLineStyle = overwriteStyle_forFar; + } + } + else + { + if (distance < thresholdDistance) + { + usedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forNear, UtilitiesDXXL_Colors.red_boolFalse); + usedLineStyle = overwriteStyle_forNear; + } + else + { + usedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forFar, UtilitiesDXXL_Colors.green_boolTrue); + usedLineStyle = overwriteStyle_forFar; + } + } + } + + + public static void ChooseColorAndStyleForDistanceThresholdsLine(ref Color usedColor, ref DrawBasics.LineStyle usedLineStyle, float distance, float smallerThresholdDistance, float biggerThresholdDistance, bool exactlyThresholdLength_countsAsShorter, DrawBasics.LineStyle overwriteStyle_forNear, DrawBasics.LineStyle overwriteStyle_forMiddle, DrawBasics.LineStyle overwriteStyle_forFar, Color overwriteColor_forNear, Color overwriteColor_forMiddle, Color overwriteColor_forFar) + { + if (exactlyThresholdLength_countsAsShorter) + { + if (distance <= smallerThresholdDistance) + { + usedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forNear, UtilitiesDXXL_Colors.red_lineThresholdFarDistance); + usedLineStyle = overwriteStyle_forNear; + } + else + { + if (distance <= biggerThresholdDistance) + { + usedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forMiddle, UtilitiesDXXL_Colors.orange_lineThresholdMiddleDistance); + usedLineStyle = overwriteStyle_forMiddle; + } + else + { + usedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forFar, UtilitiesDXXL_Colors.green_lineThresholdNearDistance); + usedLineStyle = overwriteStyle_forFar; + } + } + } + else + { + if (distance < smallerThresholdDistance) + { + usedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forNear, UtilitiesDXXL_Colors.red_lineThresholdFarDistance); + usedLineStyle = overwriteStyle_forNear; + } + else + { + if (distance < biggerThresholdDistance) + { + usedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forMiddle, UtilitiesDXXL_Colors.orange_lineThresholdMiddleDistance); + usedLineStyle = overwriteStyle_forMiddle; + } + else + { + usedColor = UtilitiesDXXL_Colors.OverwriteDefaultColor(overwriteColor_forFar, UtilitiesDXXL_Colors.green_lineThresholdNearDistance); + usedLineStyle = overwriteStyle_forFar; + } + } + } + } + + public static void WriteOrthoViewDirNameAtProjectionPlumbPos(string lineName, Vector3 pointPreProjection_forTextUp, Vector3 pointsProjectionOntoLine, Vector3 textDir, float textSize, Color color, float durationInSec, bool hiddenByNearerObjects) + { + textSize = Mathf.Max(textSize, 0.001f); + Vector3 textUp = pointsProjectionOntoLine - pointPreProjection_forTextUp; + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(textUp) < 0.0001f) + { + textUp = UtilitiesDXXL_Math.arbitrarySeldomDir2_precalced; + } + UtilitiesDXXL_Text.WriteFramed(lineName, pointsProjectionOntoLine, color, textSize, textDir, textUp, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + + static Color defaultColor1_before; + public static void Set_defaultColor1_reversible(Color new_defaultColor1) + { + defaultColor1_before = DrawMeasurements.defaultColor1; + DrawMeasurements.defaultColor1 = new_defaultColor1; + } + public static void Reverse_defaultColor1() + { + DrawMeasurements.defaultColor1 = defaultColor1_before; + } + + static Color defaultColor2_before; + public static void Set_defaultColor2_reversible(Color new_defaultColor2) + { + defaultColor2_before = DrawMeasurements.defaultColor2; + DrawMeasurements.defaultColor2 = new_defaultColor2; + } + public static void Reverse_defaultColor2() + { + DrawMeasurements.defaultColor2 = defaultColor2_before; + } + + public static void Set_defaultColors_reversible(Color new_defaultColors) + { + Set_defaultColor1_reversible(new_defaultColors); + Set_defaultColor2_reversible(new_defaultColors); + } + public static void Reverse_defaultColors() + { + Reverse_defaultColor1(); + Reverse_defaultColor2(); + } + + static Vector3 preferredPlanePatternOrientation_forDistancePointToPlane_before; + public static void Set_preferredPlanePatternOrientation_forDistancePointToPlane_reversible(Vector3 new_preferredPlanePatternOrientation_forDistancePointToPlane) + { + preferredPlanePatternOrientation_forDistancePointToPlane_before = DrawMeasurements.preferredPlanePatternOrientation_forDistancePointToPlane; + DrawMeasurements.preferredPlanePatternOrientation_forDistancePointToPlane = new_preferredPlanePatternOrientation_forDistancePointToPlane; + } + public static void Reverse_preferredPlanePatternOrientation_forDistancePointToPlane() + { + DrawMeasurements.preferredPlanePatternOrientation_forDistancePointToPlane = preferredPlanePatternOrientation_forDistancePointToPlane_before; + } + + static float minimumLineLength_forDistancePointToLine_before; + public static void Set_minimumLineLength_forDistancePointToLine_reversible(float new_minimumLineLength_forDistancePointToLine) + { + minimumLineLength_forDistancePointToLine_before = DrawMeasurements.minimumLineLength_forDistancePointToLine; + DrawMeasurements.minimumLineLength_forDistancePointToLine = new_minimumLineLength_forDistancePointToLine; + } + public static void Reverse_minimumLineLength_forDistancePointToLine() + { + DrawMeasurements.minimumLineLength_forDistancePointToLine = minimumLineLength_forDistancePointToLine_before; + } + + static float minimumLineLength_forDistanceLineToLine_before; + public static void Set_minimumLineLength_forDistanceLineToLine_reversible(float new_minimumLineLength_forDistanceLineToLine) + { + minimumLineLength_forDistanceLineToLine_before = DrawMeasurements.minimumLineLength_forDistanceLineToLine; + DrawMeasurements.minimumLineLength_forDistanceLineToLine = new_minimumLineLength_forDistanceLineToLine; + } + public static void Reverse_minimumLineLength_forDistanceLineToLine() + { + DrawMeasurements.minimumLineLength_forDistanceLineToLine = minimumLineLength_forDistanceLineToLine_before; + } + + static float minimumLineLength_forAngleLineToPlane_before; + public static void Set_minimumLineLength_forAngleLineToPlane_reversible(float new_minimumLineLength_forAngleLineToPlane) + { + minimumLineLength_forAngleLineToPlane_before = DrawMeasurements.minimumLineLength_forAngleLineToPlane; + DrawMeasurements.minimumLineLength_forAngleLineToPlane = new_minimumLineLength_forAngleLineToPlane; + } + public static void Reverse_minimumLineLength_forAngleLineToPlane() + { + DrawMeasurements.minimumLineLength_forAngleLineToPlane = minimumLineLength_forAngleLineToPlane_before; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements.cs.meta new file mode 100644 index 0000000..942716b --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0359b63ce8101e4483b335fef4d56b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements2D.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements2D.cs new file mode 100644 index 0000000..41882f2 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements2D.cs @@ -0,0 +1,30 @@ +namespace DrawXXL +{ + public class UtilitiesDXXL_Measurements2D + { + + static float minimumLineLength_forDistancePointToLine_before; + public static void Set_minimumLineLength_forDistancePointToLine_reversible(float new_minimumLineLength_forDistancePointToLine) + { + minimumLineLength_forDistancePointToLine_before = DrawMeasurements2D.minimumLineLength_forDistancePointToLine; + DrawMeasurements2D.minimumLineLength_forDistancePointToLine = new_minimumLineLength_forDistancePointToLine; + } + public static void Reverse_minimumLineLength_forDistancePointToLine() + { + DrawMeasurements2D.minimumLineLength_forDistancePointToLine = minimumLineLength_forDistancePointToLine_before; + } + + static float minimumLineLength_forAngleLineToLine_before; + public static void Set_minimumLineLength_forAngleLineToLine_reversible(float new_minimumLineLength_forAngleLineToLine) + { + minimumLineLength_forAngleLineToLine_before = DrawMeasurements2D.minimumLineLength_forAngleLineToLine; + DrawMeasurements2D.minimumLineLength_forAngleLineToLine = new_minimumLineLength_forAngleLineToLine; + } + public static void Reverse_minimumLineLength_forAngleLineToLine() + { + DrawMeasurements2D.minimumLineLength_forAngleLineToLine = minimumLineLength_forAngleLineToLine_before; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements2D.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements2D.cs.meta new file mode 100644 index 0000000..f239c2f --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Measurements2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 644ee3cf788d34b4781b12af227f71c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_ObserverCamera.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_ObserverCamera.cs new file mode 100644 index 0000000..d1bb5e0 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_ObserverCamera.cs @@ -0,0 +1,219 @@ +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)); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_ObserverCamera.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_ObserverCamera.cs.meta new file mode 100644 index 0000000..30d752e --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_ObserverCamera.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc1038dd775604449bab8269bdd1d542 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics.cs new file mode 100644 index 0000000..948ceee --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics.cs @@ -0,0 +1,2106 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_Physics + { + public static float minArrowLength = 0.001f; + + public static void DrawRaycastTillFirstHit(bool hasHit, Vector3 origin, Vector3 direction, float maxDistance, RaycastHit hitInfo, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(origin, "[ DrawRaycast with direction of zero]
" + nameText, DrawPhysics.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + float distanceOfFarestHit = GetDistanceOfSingleHit(hasHit, hitInfo); + DrawRayOfRaycast(hasHit ? 1 : 0, origin, direction, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + if (hasHit) + { + DrawRaycastHitInfo(hitInfo, 0, nameText, direction, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawRaycastPotMultipleHits(Vector3 origin, Vector3 direction, float maxDistance, RaycastHit[] hitInfos, int numberOfUsedSlotsInHitInfoArray, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(origin, "[ DrawRaycast with direction of zero]
" + nameText, DrawPhysics.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + float distanceOfFarestHit = GetDistanceOfFarestHit(hitInfos, numberOfUsedSlotsInHitInfoArray); + DrawRayOfRaycast(numberOfUsedSlotsInHitInfoArray, origin, direction, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + DrawRaycastHitInfo(hitInfos[i], i, nameText, direction, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawRayOfRaycast(int hitCount, Vector3 origin, Vector3 direction, float maxDistance, string nameText, float distanceOfFarestHit, float durationInSec, bool hiddenByNearerObjects) + { + bool hasHit = hitCount > 0; + Color color = hasHit ? DrawPhysics.colorForHittingCasts : DrawPhysics.colorForNonHittingCasts; + Vector3 direction_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(direction); + bool hasUnlimitedLength = float.IsInfinity(maxDistance); + float absMaxDistance = Mathf.Abs(maxDistance); + float lengthOfRayDirIndicator = Mathf.Min(1.0f, 0.9f * absMaxDistance); + maxDistance = Mathf.Min(maxDistance, 100000.0f); + maxDistance = Mathf.Max(maxDistance, -100000.0f); + Vector3 endPos = origin + direction_normalized * maxDistance; + Line_fadeableAnimSpeed.InternalDraw(origin, endPos, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //at origin: + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + float width_ofBase = 0.1f * lengthOfRayDirIndicator; + DrawShapes.Pyramid(origin, lengthOfRayDirIndicator, width_ofBase, width_ofBase, color, direction_normalized, Vector3.up, DrawShapes.Shape2DType.square, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + else + { + string rayText = GetRayText(nameText, hitCount, maxDistance); + DrawEngineBasics.RayLineExtended(origin, direction_normalized * lengthOfRayDirIndicator, color, 0.0f, rayText, 0.0f, false, 0.01f, 0.0f, durationInSec, hiddenByNearerObjects); + } + + //overdraw line after last hit: + if (hasHit) + { + Line_fadeableAnimSpeed.InternalDraw(origin + direction_normalized * distanceOfFarestHit, endPos, DrawPhysics.colorForCastLineBeyondHit, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + //end cap: + if (hasUnlimitedLength == false) + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + DrawShapes.Square(endPos, 0.025f, hasHit ? DrawPhysics.colorForCastLineBeyondHit : DrawPhysics.colorForNonHittingCasts, direction_normalized, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + else + { + DrawShapes.Decagon(endPos, 0.025f, hasHit ? DrawPhysics.colorForCastLineBeyondHit : DrawPhysics.colorForNonHittingCasts, direction_normalized, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + } + } + + static string GetRayText(string nameText, int hitCount, float maxDistance) + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + return null; + } + else + { + string rayText; + if (DrawPhysics.drawCastNameTag_atCastOrigin && nameText != null && nameText.Length != 0) + { + rayText = (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? GetSizeMarkupStartStringForCastNames(nameText) + nameText + "

hits: " + hitCount : GetSizeMarkupStartStringForCastNames(nameText) + nameText + "

number of hits: " + hitCount; + } + else + { + rayText = (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? "hits: " + hitCount : "Raycast

number of hits: " + hitCount; + } + + if (maxDistance < 0.0f) + { + rayText = "[ negative ray direction

-> no hits will be detected]
" + rayText; + } + return rayText; + } + } + + static void DrawRaycastHitInfo(RaycastHit hitInfo, int i_hit, string nameText, Vector3 direction, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo.point) || UtilitiesDXXL_Math.VectorIsInvalid(hitInfo.normal)) + { + Debug.LogError("Draw XXL: A 'Physics.RayCast()' returned an invalid hit position (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + ") or normal (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.normal) + "). The drawn cast visualization may be incorrect."); + } + else + { + bool saveDrawnLines = i_hit >= DrawPhysics.hitResultsWithMoreDetailedDisplay; + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.high_withFullDetails) { saveDrawnLines = true; } + + //Normal: + Color color_ofNormal = Get_color_ofNormal(); + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + DrawBasics.LineFrom(hitInfo.point, hitInfo.normal, color_ofNormal, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + float relConeLength_ofNormalVector = 0.17f; + string normalText = (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? null : (saveDrawnLines ? "normal" : "normal
of hit surface"); + + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorFrom(hitInfo.point, hitInfo.normal, color_ofNormal, saveDrawnLines ? 0.0f : 0.006f, normalText, relConeLength_ofNormalVector, false, false, default(Vector3), false, 0.01f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + //Normal Socket and Text Description: + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + DrawNormalSocketAndText_highQuality(hitInfo, i_hit, nameText, color_ofNormal, saveDrawnLines, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + DrawNormalSocketAndText_mediumQuality(hitInfo, nameText, color_ofNormal, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + //normal socket: + DrawShapes.Square(hitInfo.point, 0.12f, color_ofNormal, hitInfo.normal, direction, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + break; + default: + break; + } + + } + } + + static void DrawNormalSocketAndText_highQuality(RaycastHit hitInfo, int i_hit, string nameText, Color color_ofNormal, bool saveDrawnLines, float durationInSec, bool hiddenByNearerObjects) + { + //normal socket: + DrawShapes.Decagon(hitInfo.point, 0.02f, color_ofNormal, hitInfo.normal, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Decagon(hitInfo.point, 0.04f, color_ofNormal, hitInfo.normal, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Decagon(hitInfo.point, 0.06f, color_ofNormal, hitInfo.normal, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + //text description: + Vector3 textOffsetDir = default(Vector3); + float textOffsetDistance = DrawPhysics.scaleFactor_forCastHitTextSize; + string text; + if (DrawPhysics.drawCastNameTag_atHitPositions && nameText != null && nameText.Length != 0) + { + text = (saveDrawnLines ? (nameText + " / #" + i_hit + ":
hit GO: " + hitInfo.transform.gameObject.name + "
pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + "
dist = " + hitInfo.distance) : (GetStrokeWidthMarkupStartStringForHitPosDesctiptionHeaders(nameText) + nameText + " / hit #" + i_hit + ":
GameObject that was hit: " + hitInfo.transform.gameObject.name + "
position = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + "
distance = " + hitInfo.distance)); + } + else + { + text = (saveDrawnLines ? ("hit #" + i_hit + ":
hit GO: " + hitInfo.transform.gameObject.name + "
pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + "
dist = " + hitInfo.distance) : ("Raycast hit #" + i_hit + ":
GameObject that was hit: " + hitInfo.transform.gameObject.name + "
position = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + "
distance = " + hitInfo.distance)); + } + + TrySet_default_textOffsetDirection_forPointTags_reversible(); + DrawBasics.PointTag(hitInfo.point, text, DrawPhysics.colorForCastsHitText, 0.0f, textOffsetDistance, textOffsetDir, 1.0f, false, durationInSec, hiddenByNearerObjects); + TryReverse_default_textOffsetDirection_forPointTags(); + } + + static void DrawNormalSocketAndText_mediumQuality(RaycastHit hitInfo, string nameText, Color color_ofNormal, float durationInSec, bool hiddenByNearerObjects) + { + //normal socket: + DrawShapes.Decagon(hitInfo.point, 0.06f, color_ofNormal, hitInfo.normal, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + //text description: + if (DrawPhysics.drawCastNameTag_atHitPositions && nameText != null && nameText.Length != 0) + { + UtilitiesDXXL_Text.WriteFramed(nameText, hitInfo.point, DrawPhysics.colorForCastsHitText, 0.1f * DrawPhysics.scaleFactor_forCastHitTextSize, default(Vector3), default(Vector3), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawSpherecastTillFirstHit(float sphereRadius, bool hasHit, Vector3 origin, Vector3 direction, float maxDistance, RaycastHit hitInfo, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(origin, "[ DrawSpherecast with direction of zero]
" + nameText, DrawPhysics.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool radiusIsZero = UtilitiesDXXL_Math.ApproximatelyZero(sphereRadius); + bool sphereHasNegativeRadius = sphereRadius < 0.0f; + sphereRadius = Mathf.Abs(sphereRadius); + float distanceOfFarestHit = GetDistanceOfSingleHit(hasHit, hitInfo); + Vector3 direction_normalized = DrawRayOfSpherecast(sphereRadius, sphereHasNegativeRadius, radiusIsZero, hasHit ? 1 : 0, origin, direction, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + if (hasHit) + { + DrawSpherecastHitInfo(origin, direction_normalized, sphereRadius, sphereHasNegativeRadius, hitInfo, 0, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawSpherecastPotMultipleHits(float sphereRadius, Vector3 origin, Vector3 direction, float maxDistance, RaycastHit[] hitInfos, int numberOfUsedSlotsInHitInfoArray, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(origin, "[ DrawSpherecast with direction of zero]
" + nameText, DrawPhysics.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool radiusIsZero = UtilitiesDXXL_Math.ApproximatelyZero(sphereRadius); + bool sphereHasNegativeRadius = sphereRadius < 0.0f; + sphereRadius = Mathf.Abs(sphereRadius); + float distanceOfFarestHit = GetDistanceOfFarestHit(hitInfos, numberOfUsedSlotsInHitInfoArray); + Vector3 direction_normalized = DrawRayOfSpherecast(sphereRadius, sphereHasNegativeRadius, radiusIsZero, numberOfUsedSlotsInHitInfoArray, origin, direction, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + DrawSpherecastHitInfo(origin, direction_normalized, sphereRadius, sphereHasNegativeRadius, hitInfos[i], i, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawBoxcastTillFirstHit(bool hasHit, Vector3 origin, Vector3 halfExtents, Quaternion orientation, Vector3 direction, float maxDistance, RaycastHit hitInfo, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(origin, "[ DrawBoxcast with direction of zero]
" + nameText, DrawPhysics.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool boxScaleIsZero = UtilitiesDXXL_Math.ApproximatelyZero(halfExtents); + bool atLeastOneBoxDimIsNegative = UtilitiesDXXL_Math.ContainsNegativeComponents(halfExtents); + Vector3 boxSize = 2.0f * halfExtents; //Note: inconsistent naming inside Unity: Here: "halfExtents" = "halfSize", while in "Bounds": "extents" = "halfSize" + Vector3 boxForward_normalized = orientation * Vector3.forward; + Vector3 boxUp_normalized = orientation * Vector3.up; + + float distanceOfFarestHit = GetDistanceOfSingleHit(hasHit, hitInfo); + Vector3 direction_normalized = DrawRayOfBoxcast(hasHit ? 1 : 0, origin, boxSize, atLeastOneBoxDimIsNegative, boxScaleIsZero, boxForward_normalized, boxUp_normalized, orientation, direction, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + if (hasHit) + { + DrawBoxcastHitInfo(origin, direction_normalized, boxSize, atLeastOneBoxDimIsNegative, boxForward_normalized, boxUp_normalized, hitInfo, 0, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawBoxcastPotMultipleHits(Vector3 origin, Vector3 halfExtents, Quaternion orientation, Vector3 direction, float maxDistance, RaycastHit[] hitInfos, int numberOfUsedSlotsInHitInfoArray, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(origin, "[ DrawBoxcast with direction of zero]
" + nameText, DrawPhysics.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool boxScaleIsZero = UtilitiesDXXL_Math.ApproximatelyZero(halfExtents); + bool atLeastOneBoxDimIsNegative = UtilitiesDXXL_Math.ContainsNegativeComponents(halfExtents); + Vector3 boxSize = 2.0f * halfExtents; //Note: inconsistent naming inside Unity: Here: "halfExtents" = "halfSize", while in "Bounds": "extents" = "halfSize" + Vector3 boxForward_normalized = orientation * Vector3.forward; + Vector3 boxUp_normalized = orientation * Vector3.up; + + float distanceOfFarestHit = GetDistanceOfFarestHit(hitInfos, numberOfUsedSlotsInHitInfoArray); + Vector3 direction_normalized = DrawRayOfBoxcast(numberOfUsedSlotsInHitInfoArray, origin, boxSize, atLeastOneBoxDimIsNegative, boxScaleIsZero, boxForward_normalized, boxUp_normalized, orientation, direction, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + DrawBoxcastHitInfo(origin, direction_normalized, boxSize, atLeastOneBoxDimIsNegative, boxForward_normalized, boxUp_normalized, hitInfos[i], i, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawCapsulecastTillFirstHit(float capsuleRadius, bool hasHit, Vector3 posOfCapsuleSphere1_atCastStart, Vector3 posOfCapsuleSphere2_atCastStart, Vector3 direction, float maxDistance, RaycastHit hitInfo, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(posOfCapsuleSphere1_atCastStart, "[ DrawCapsulecast with direction of zero]
" + nameText, DrawPhysics.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool radiusIsZero = UtilitiesDXXL_Math.ApproximatelyZero(capsuleRadius); + bool capsuleHasNegativeRadius = capsuleRadius < 0.0f; + capsuleRadius = Mathf.Abs(capsuleRadius); + float distanceOfFarestHit = GetDistanceOfSingleHit(hasHit, hitInfo); + Vector3 direction_normalized = DrawRayOfCapsulecast(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, capsuleRadius, capsuleHasNegativeRadius, radiusIsZero, hasHit ? 1 : 0, direction, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + if (hasHit) + { + DrawCapsulecastHitInfo(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, direction_normalized, capsuleRadius, capsuleHasNegativeRadius, hitInfo, 0, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawCapsulecastPotMultipleHits(float capsuleRadius, Vector3 posOfCapsuleSphere1_atCastStart, Vector3 posOfCapsuleSphere2_atCastStart, Vector3 direction, float maxDistance, RaycastHit[] hitInfos, int numberOfUsedSlotsInHitInfoArray, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(posOfCapsuleSphere1_atCastStart, "[ DrawCapsulecast with direction of zero]
" + nameText, DrawPhysics.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool radiusIsZero = UtilitiesDXXL_Math.ApproximatelyZero(capsuleRadius); + bool capsuleHasNegativeRadius = capsuleRadius < 0.0f; + capsuleRadius = Mathf.Abs(capsuleRadius); + float distanceOfFarestHit = GetDistanceOfFarestHit(hitInfos, numberOfUsedSlotsInHitInfoArray); + Vector3 direction_normalized = DrawRayOfCapsulecast(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, capsuleRadius, capsuleHasNegativeRadius, radiusIsZero, numberOfUsedSlotsInHitInfoArray, direction, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + DrawCapsulecastHitInfo(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, direction_normalized, capsuleRadius, capsuleHasNegativeRadius, hitInfos[i], i, nameText, durationInSec, hiddenByNearerObjects); + } + } + + static int strutsPerCastSphere = 8; + static int strutsPerCastCapsule = 8; + static Vector3[] volumeCastOutlineVertices_local = new Vector3[34]; + static Vector3[] volumeCastOutlineVerticesReduced_local = new Vector3[6]; + static InternalDXXL_Plane planePerpToCastDir_throughCapsulesSphere1AtCastStartPos = new InternalDXXL_Plane(); + static InternalDXXL_Plane castDirPlaneThroughWorldZeroOrigin = new InternalDXXL_Plane(); + static Vector3 DrawRayOfSpherecast(float sphereRadius, bool sphereHasNegativeRadius, bool radiusIsZero, int hitCount, Vector3 origin, Vector3 direction, float maxDistance, string nameText, float distanceOfFarestHit, float durationInSec, bool hiddenByNearerObjects) + { + bool hasHit = hitCount > 0; + Vector3 direction_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(direction); + bool hasUnlimitedLength = float.IsInfinity(maxDistance); + maxDistance = Mathf.Min(maxDistance, 100000.0f); + maxDistance = Mathf.Max(maxDistance, -100000.0f); + Vector3 endPos = origin + direction_normalized * maxDistance; + + Color color = hasHit ? DrawPhysics.colorForHittingCasts : DrawPhysics.colorForNonHittingCasts; + Color color_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.5f); + Color color_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.25f); + + Color color_ofCastEnd = hasHit ? DrawPhysics.colorForCastLineBeyondHit : DrawPhysics.colorForNonHittingCasts; + Color color_ofCastEnd_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.5f); + Color color_ofCastEnd_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.25f); + + if (radiusIsZero == false) + { + float arrowWidth = sphereRadius * 0.5f; + float arrowLength = sphereRadius * 1.0f; + float arrowsRelConeLenth = 0.45f; + float sphereDiameter = 2.0f * sphereRadius; + + DrawSphereAtCastStartAndEnd(origin, endPos, direction_normalized, sphereRadius, color, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + float startArrows_startDistanceFromStart = sphereDiameter; + DrawArrowsAtVolumeCastStartAndEnd(out float distance_ofStartArrowsStartPos, out float distance_ofEndArrowsStartPos, hasHit, origin, direction_normalized, startArrows_startDistanceFromStart, maxDistance, distanceOfFarestHit, arrowLength, color_lowerAlpha, color_ofCastEnd_lowerAlpha, arrowsRelConeLenth, arrowWidth, durationInSec, hiddenByNearerObjects); + int usedSlotsIn_verticesPerOutlineCircle = FillSphereCastOutlineVerticesArray(origin, direction_normalized, sphereRadius); + float sizeApproximationOfVolume = sphereDiameter; + DrawCascadeOfArrows(distance_ofStartArrowsStartPos, distance_ofEndArrowsStartPos, sizeApproximationOfVolume, hasHit, hasUnlimitedLength, origin, direction_normalized, distanceOfFarestHit, arrowLength, arrowWidth, arrowsRelConeLenth, color_lowerAlpha, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + DrawCascadeOfVolumeSilhouettes(usedSlotsIn_verticesPerOutlineCircle, sizeApproximationOfVolume, hasHit, hasUnlimitedLength, origin, direction_normalized, maxDistance, distanceOfFarestHit, color, color_ofCastEnd, durationInSec, hiddenByNearerObjects); + } + + int usedSlotsIn_verticesPerReducedOutlineCircle = FillSphereCastReducedOutlineVerticesArray(origin, direction_normalized, sphereRadius, radiusIsZero); + DrawVolumeCastDirOutline(usedSlotsIn_verticesPerReducedOutlineCircle, hasHit, origin, endPos, direction_normalized, distanceOfFarestHit, color_lowAlpha, color_ofCastEnd_lowAlpha, durationInSec, hiddenByNearerObjects); + WriteTextAtSphereCastOrigin(origin, direction_normalized, sphereRadius, sphereHasNegativeRadius, color, nameText, hitCount, maxDistance, durationInSec, hiddenByNearerObjects); + return direction_normalized; + } + + static Vector3 DrawRayOfBoxcast(int hitCount, Vector3 origin, Vector3 boxSize, bool atLeastOneBoxDimIsNegative, bool boxScaleIsZero, Vector3 boxForward_normalized, Vector3 boxUp_normalized, Quaternion boxRotation, Vector3 direction, float maxDistance, string nameText, float distanceOfFarestHit, float durationInSec, bool hiddenByNearerObjects) + { + bool hasHit = hitCount > 0; + Vector3 direction_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(direction); + bool hasUnlimitedLength = float.IsInfinity(maxDistance); + maxDistance = Mathf.Min(maxDistance, 100000.0f); + maxDistance = Mathf.Max(maxDistance, -100000.0f); + Vector3 endPos = origin + direction_normalized * maxDistance; + + Color color = hasHit ? DrawPhysics.colorForHittingCasts : DrawPhysics.colorForNonHittingCasts; + Color color_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.5f); + Color color_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.25f); + + Color color_ofCastEnd = hasHit ? DrawPhysics.colorForCastLineBeyondHit : DrawPhysics.colorForNonHittingCasts; + Color color_ofCastEnd_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.5f); + Color color_ofCastEnd_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.25f); + + Vector3 absBoxSize = UtilitiesDXXL_Math.Abs(boxSize); + float averageBoxSize = 0.3333f * (absBoxSize.x + absBoxSize.y + absBoxSize.z); + + int usedSlotsIn_verticesPerReducedOutlineCircle = 1; + if (boxScaleIsZero == false) + { + float arrowWidth = averageBoxSize * 0.25f; + float arrowLength = averageBoxSize * 0.5f; + float arrowsRelConeLenth = 0.45f; + + Vector3 boxRight_normalized = Vector3.Cross(boxUp_normalized, boxForward_normalized); + DrawBoxAtCastStartAndEnd(origin, endPos, boxSize, boxForward_normalized, boxUp_normalized, color, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + float startArrows_startDistanceFromStart = averageBoxSize * 0.5f + arrowLength; + DrawArrowsAtVolumeCastStartAndEnd(out float distance_ofStartArrowsStartPos, out float distance_ofEndArrowsStartPos, hasHit, origin, direction_normalized, startArrows_startDistanceFromStart, maxDistance, distanceOfFarestHit, arrowLength, color_lowerAlpha, color_ofCastEnd_lowerAlpha, arrowsRelConeLenth, arrowWidth, durationInSec, hiddenByNearerObjects); + usedSlotsIn_verticesPerReducedOutlineCircle = FillBoxCastReducedOutlineVerticesArray(direction_normalized, boxSize, boxRotation, boxForward_normalized, boxUp_normalized, boxRight_normalized); + int usedSlotsIn_verticesPerOutlineCircle = FillBoxCastOutlineVerticesArray(direction_normalized, usedSlotsIn_verticesPerReducedOutlineCircle); + float sizeApproximationOfVolume = averageBoxSize; + DrawCascadeOfArrows(distance_ofStartArrowsStartPos, distance_ofEndArrowsStartPos, sizeApproximationOfVolume, hasHit, hasUnlimitedLength, origin, direction_normalized, distanceOfFarestHit, arrowLength, arrowWidth, arrowsRelConeLenth, color_lowerAlpha, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + DrawCascadeOfVolumeSilhouettes(usedSlotsIn_verticesPerOutlineCircle, sizeApproximationOfVolume, hasHit, hasUnlimitedLength, origin, direction_normalized, maxDistance, distanceOfFarestHit, color, color_ofCastEnd, durationInSec, hiddenByNearerObjects); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = Vector3.zero; + } + + DrawVolumeCastDirOutline(usedSlotsIn_verticesPerReducedOutlineCircle, hasHit, origin, endPos, direction_normalized, distanceOfFarestHit, color_lowAlpha, color_ofCastEnd_lowAlpha, durationInSec, hiddenByNearerObjects); + WriteTextAtBoxCastOrigin(origin, direction_normalized, boxSize, atLeastOneBoxDimIsNegative, boxUp_normalized, color, nameText, hitCount, maxDistance, averageBoxSize, durationInSec, hiddenByNearerObjects); + return direction_normalized; + } + + static Vector3 DrawRayOfCapsulecast(Vector3 posOfCapsuleSphere1_atCastStart, Vector3 posOfCapsuleSphere2_atCastStart, float capsuleRadius, bool capsuleHasNegativeRadius, bool radiusIsZero, int hitCount, Vector3 direction, float maxDistance, string nameText, float distanceOfFarestHit, float durationInSec, bool hiddenByNearerObjects) + { + bool hasHit = hitCount > 0; + Vector3 direction_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(direction); + bool hasUnlimitedLength = float.IsInfinity(maxDistance); + maxDistance = Mathf.Min(maxDistance, 100000.0f); + maxDistance = Mathf.Max(maxDistance, -100000.0f); + + Color color = hasHit ? DrawPhysics.colorForHittingCasts : DrawPhysics.colorForNonHittingCasts; + Color color_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.5f); + Color color_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.25f); + + Color color_ofCastEnd = hasHit ? DrawPhysics.colorForCastLineBeyondHit : DrawPhysics.colorForNonHittingCasts; + Color color_ofCastEnd_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.5f); + Color color_ofCastEnd_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.25f); + + float capsuleSpheresDiameter = 2.0f * capsuleRadius; + bool capsuleIsSqueezedToSphere = UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart); + Vector3 capsuleUp_normalized; //sphere1 is "upper" sphere + float distanceBetweenSpheres; + if (capsuleIsSqueezedToSphere) + { + capsuleUp_normalized = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(direction_normalized); + distanceBetweenSpheres = 0.0f; + } + else + { + Vector3 capsuleUp = posOfCapsuleSphere1_atCastStart - posOfCapsuleSphere2_atCastStart; + capsuleUp_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(capsuleUp, out distanceBetweenSpheres); + } + bool capsuleAppearsAsSphereAlongCastDir = capsuleIsSqueezedToSphere || UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(direction_normalized, capsuleUp_normalized); + + Vector3 posOfCapsuleSphere1_atCastEnd = posOfCapsuleSphere1_atCastStart + direction_normalized * maxDistance; + Vector3 posOfCapsuleSphere2_atCastEnd = posOfCapsuleSphere2_atCastStart + direction_normalized * maxDistance; + + Vector3 towardsRight_ofSphere1_viewedAlongCastDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(Vector3.Cross(capsuleUp_normalized, direction_normalized)); + //is only used if "capsuleAppearsAsSphereAlongCastDir == false" (an in these cases cannot become zero): + Vector3 towardsRight_ofSphere1_viewedAlongCastDir = towardsRight_ofSphere1_viewedAlongCastDir_normalized * capsuleRadius; + + if (radiusIsZero == false) + { + Vector3 capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir; + float sizeApproximationOfCapsule = capsuleSpheresDiameter + 0.5f * distanceBetweenSpheres; + float sizeApproximationOfCapsule_insidePerpToCastDirPlane; + Vector3 sphere1_to_sphere2 = posOfCapsuleSphere2_atCastStart - posOfCapsuleSphere1_atCastStart; + float distance_fromSphere1ActingAsOrigin_toActualCapsuleCenter_alongCastDir = 0.5f * Vector3.Project(sphere1_to_sphere2, direction_normalized).magnitude; + float signedDistance_fromSphere1ActingAsOrigin_toActualCapsuleCenter_alongCastDir = UtilitiesDXXL_Math.GetSign_trueGivesPlus1_falseGivesMinus1(UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(sphere1_to_sphere2, direction_normalized)) * distance_fromSphere1ActingAsOrigin_toActualCapsuleCenter_alongCastDir; + if (capsuleAppearsAsSphereAlongCastDir) + { + capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir = Vector3.zero; + sizeApproximationOfCapsule_insidePerpToCastDirPlane = capsuleSpheresDiameter; + } + else + { + Vector3 capsuleCenter_atStartPos = 0.5f * (posOfCapsuleSphere1_atCastStart + posOfCapsuleSphere2_atCastStart); + planePerpToCastDir_throughCapsulesSphere1AtCastStartPos.Recreate(posOfCapsuleSphere1_atCastStart, direction_normalized); + Vector3 capsuleSphere1ToCapsuleSilhoutteCenter = capsuleCenter_atStartPos - posOfCapsuleSphere1_atCastStart; + capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir = planePerpToCastDir_throughCapsulesSphere1AtCastStartPos.Get_projectionOfVectorOntoPlane(capsuleSphere1ToCapsuleSilhoutteCenter); + sizeApproximationOfCapsule_insidePerpToCastDirPlane = capsuleSpheresDiameter + 2.0f * capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir.magnitude; + } + float arrowWidth = sizeApproximationOfCapsule_insidePerpToCastDirPlane * 0.25f; + float arrowLength = sizeApproximationOfCapsule_insidePerpToCastDirPlane * 0.5f; + float arrowsRelConeLenth = 0.45f; + + DrawCapsuleAtCastStartAndEnd(direction_normalized, posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, posOfCapsuleSphere1_atCastEnd, posOfCapsuleSphere2_atCastEnd, capsuleRadius, color, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + float distanceFromOrigin_toStartOfStartArrow_excludingCompensationForCapsulesWhereOriginIsNotCapsuleCenter = capsuleSpheresDiameter; + DrawArrowsAtVolumeCastStartAndEnd(out float distance_ofStartArrowsStartPos, out float distance_ofEndArrowsStartPos, hasHit, posOfCapsuleSphere1_atCastStart, direction_normalized, distanceFromOrigin_toStartOfStartArrow_excludingCompensationForCapsulesWhereOriginIsNotCapsuleCenter, maxDistance, distanceOfFarestHit, arrowLength, color_lowerAlpha, color_ofCastEnd_lowerAlpha, arrowsRelConeLenth, arrowWidth, durationInSec, hiddenByNearerObjects, capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir, signedDistance_fromSphere1ActingAsOrigin_toActualCapsuleCenter_alongCastDir); + int usedSlotsIn_verticesPerOutlineCircle = FillCapsuleCastOutlineVerticesArray(capsuleAppearsAsSphereAlongCastDir, posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, direction_normalized, capsuleRadius, towardsRight_ofSphere1_viewedAlongCastDir); + DrawCascadeOfArrows(distance_ofStartArrowsStartPos, distance_ofEndArrowsStartPos, sizeApproximationOfCapsule, hasHit, hasUnlimitedLength, posOfCapsuleSphere1_atCastStart, direction_normalized, distanceOfFarestHit, arrowLength, arrowWidth, arrowsRelConeLenth, color_lowerAlpha, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects, capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir); + DrawCascadeOfVolumeSilhouettes(usedSlotsIn_verticesPerOutlineCircle, sizeApproximationOfCapsule, hasHit, hasUnlimitedLength, posOfCapsuleSphere1_atCastStart, direction_normalized, maxDistance, distanceOfFarestHit, color, color_ofCastEnd, durationInSec, hiddenByNearerObjects); + } + else + { + DrawCapsuleAtCastStartAndEnd_fallbackForZeroRadiusLine(direction_normalized, posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, posOfCapsuleSphere1_atCastEnd, posOfCapsuleSphere2_atCastEnd, color, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + } + + int usedSlotsIn_verticesPerReducedOutlineCircle = FillCapsuleCastReducedOutlineVerticesArray(capsuleAppearsAsSphereAlongCastDir, posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, direction_normalized, capsuleRadius, radiusIsZero, towardsRight_ofSphere1_viewedAlongCastDir); + DrawVolumeCastDirOutline(usedSlotsIn_verticesPerReducedOutlineCircle, hasHit, posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere1_atCastEnd, direction_normalized, distanceOfFarestHit, color_lowAlpha, color_ofCastEnd_lowAlpha, durationInSec, hiddenByNearerObjects); + WriteTextAtCapsuleCastOrigin(capsuleAppearsAsSphereAlongCastDir, posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, direction_normalized, capsuleRadius, capsuleHasNegativeRadius, color, nameText, hitCount, maxDistance, durationInSec, hiddenByNearerObjects); + return direction_normalized; + } + + static void DrawSphereAtCastStartAndEnd(Vector3 origin, Vector3 endPos, Vector3 direction_normalized, float sphereRadius, Color color, Color color_ofCastEnd_lowerAlpha, float durationInSec, bool hiddenByNearerObjects) + { + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(64); + + //start sphere: + DrawShapes.Sphere(origin, sphereRadius, color, direction_normalized, default(Vector3), 0.0f, null, strutsPerCastSphere, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + + //end sphere: + DrawShapes.Sphere(endPos, sphereRadius, color_ofCastEnd_lowerAlpha, direction_normalized, default(Vector3), 0.0f, null, strutsPerCastSphere, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(32); + + //start sphere: + DrawShapes.Sphere(origin, sphereRadius, color, direction_normalized, default(Vector3), 0.0f, null, strutsPerCastSphere, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + + //end sphere: + DrawShapes.Sphere(endPos, sphereRadius, color_ofCastEnd_lowerAlpha, direction_normalized, default(Vector3), 0.0f, null, 2, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(16); + + //start sphere: + DrawShapes.Sphere(origin, sphereRadius, color, direction_normalized, default(Vector3), 0.0f, null, 2, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + + //end sphere: + //-> not supported + + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + default: + break; + } + } + + static void DrawBoxAtCastStartAndEnd(Vector3 origin, Vector3 endPos, Vector3 boxSize, Vector3 boxForward_normalized, Vector3 boxUp_normalized, Color color, Color color_ofCastEnd_lowerAlpha, float durationInSec, bool hiddenByNearerObjects) + { + //start box: + DrawShapes.Cube(origin, boxSize, color, boxUp_normalized, boxForward_normalized, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + //end box: + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + DrawShapes.CubeFilled(endPos, boxSize, color_ofCastEnd_lowerAlpha, boxUp_normalized, boxForward_normalized, 0.0f, 4, null, DrawBasics.LineStyle.solid, default(Color), 0.01f, 1.0f, true, false, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + DrawShapes.Cube(endPos, boxSize, color_ofCastEnd_lowerAlpha, boxUp_normalized, boxForward_normalized, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + break; + default: + break; + } + } + + static void DrawCapsuleAtCastStartAndEnd(Vector3 direction_normalized, Vector3 posOfCapsuleSphere1_atCastStart, Vector3 posOfCapsuleSphere2_atCastStart, Vector3 posOfCapsuleSphere1_atCastEnd, Vector3 posOfCapsuleSphere2_atCastEnd, float capsuleRadius, Color color, Color color_ofCastEnd_lowerAlpha, float durationInSec, bool hiddenByNearerObjects) + { + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(64); + + //start capsule: + DrawShapes.Capsule(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, capsuleRadius, color, direction_normalized, 0.0f, null, strutsPerCastCapsule, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + //end capsule: + DrawShapes.Capsule(posOfCapsuleSphere1_atCastEnd, posOfCapsuleSphere2_atCastEnd, capsuleRadius, color_ofCastEnd_lowerAlpha, direction_normalized, 0.0f, null, strutsPerCastCapsule, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(32); + + //start capsule: + DrawShapes.Capsule(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, capsuleRadius, color, direction_normalized, 0.0f, null, strutsPerCastCapsule, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + //end capsule: + DrawShapes.Capsule(posOfCapsuleSphere1_atCastEnd, posOfCapsuleSphere2_atCastEnd, capsuleRadius, color_ofCastEnd_lowerAlpha, direction_normalized, 0.0f, null, 2, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(16); + + //start capsule: + DrawShapes.Capsule(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, capsuleRadius, color, direction_normalized, 0.0f, null, 2, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + //end capsule: + //-> not supported + + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + default: + break; + } + } + + static void DrawCapsuleAtCastStartAndEnd_fallbackForZeroRadiusLine(Vector3 direction_normalized, Vector3 posOfCapsuleSphere1_atCastStart, Vector3 posOfCapsuleSphere2_atCastStart, Vector3 posOfCapsuleSphere1_atCastEnd, Vector3 posOfCapsuleSphere2_atCastEnd, Color color, Color color_ofCastEnd_lowerAlpha, float durationInSec, bool hiddenByNearerObjects) + { + //This is also called if the capsule didn't only shrink to line, but to point. Calling "Draw.Line()" instead of " DrawShapes.Capsule" here has the advantage that no zeroExtentShape-Fallback is displayed. + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart) == false) + { + //start capsule: + Line_fadeableAnimSpeed.InternalDraw(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //end capsule: + Line_fadeableAnimSpeed.InternalDraw(posOfCapsuleSphere1_atCastEnd, posOfCapsuleSphere2_atCastEnd, color_ofCastEnd_lowerAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + + static void DrawArrowsAtVolumeCastStartAndEnd(out float distance_ofStartArrowsStartPos, out float distance_ofEndArrowsStartPos, bool hasHit, Vector3 origin, Vector3 direction_normalized, float distanceFromOrigin_toStartOfStartArrow_excludingCompensationForCapsulesWhereOriginIsNotCapsuleCenter, float maxDistance, float distanceOfFarestHit, float arrowLength, Color color_lowerAlpha, Color color_ofCastEnd_lowerAlpha, float arrowsRelConeLenth, float arrowWidth, float durationInSec, bool hiddenByNearerObjects, Vector3 capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir = default(Vector3), float signedDistance_fromSphere1ActingAsOrigin_toActualCapsuleCenter_alongCastDir = 0.0f) + { + //"_excludingCompensationForCapsulesWhereOriginIsNotCapsuleCenter" -> capsules use sphere1(=upperSphere) as orgin here instead of the actual center of the capsule + + distance_ofStartArrowsStartPos = 0.0f; + distance_ofEndArrowsStartPos = 0.0f; + + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + if (arrowLength > minArrowLength) + { + //at start: + float original_distanceFromOrigin_toStartOfStartArrow_excludingCompensationForCapsules = distanceFromOrigin_toStartOfStartArrow_excludingCompensationForCapsulesWhereOriginIsNotCapsuleCenter; + float distanceFromOrigin_toStartOfStartArrow = distanceFromOrigin_toStartOfStartArrow_excludingCompensationForCapsulesWhereOriginIsNotCapsuleCenter; + if (signedDistance_fromSphere1ActingAsOrigin_toActualCapsuleCenter_alongCastDir > 0.0f) + { + distanceFromOrigin_toStartOfStartArrow = distanceFromOrigin_toStartOfStartArrow + 2.0f * signedDistance_fromSphere1ActingAsOrigin_toActualCapsuleCenter_alongCastDir; + } + distanceFromOrigin_toStartOfStartArrow = Mathf.Min(distanceFromOrigin_toStartOfStartArrow, 0.5f * maxDistance); + if (hasHit) { distanceFromOrigin_toStartOfStartArrow = Mathf.Min(distanceFromOrigin_toStartOfStartArrow, 0.5f * distanceOfFarestHit); } + if (distanceFromOrigin_toStartOfStartArrow <= 0.0f) { distanceFromOrigin_toStartOfStartArrow = original_distanceFromOrigin_toStartOfStartArrow_excludingCompensationForCapsules; } + bool isAfterLastHit = hasHit && ((distanceFromOrigin_toStartOfStartArrow + 0.5f * arrowLength) > distanceOfFarestHit); + distance_ofStartArrowsStartPos = distanceFromOrigin_toStartOfStartArrow; + Vector3 startVector_startPos = origin + direction_normalized * distanceFromOrigin_toStartOfStartArrow + capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir; + Vector3 startVector_endPos = origin + direction_normalized * (distanceFromOrigin_toStartOfStartArrow + arrowLength) + capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir; + + UtilitiesDXXL_DrawBasics.Set_automaticAmplitudeAndTextAlignment_reversible(DrawBasics.AutomaticAmplitudeAndTextAlignment.perpendicularToCamera); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + UtilitiesDXXL_DrawBasics.Vector(startVector_startPos, startVector_endPos, isAfterLastHit ? color_ofCastEnd_lowerAlpha : color_lowerAlpha, arrowWidth, null, arrowsRelConeLenth, false, true, false, 0.0f, false, durationInSec, hiddenByNearerObjects, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + UtilitiesDXXL_DrawBasics.Reverse_automaticAmplitudeAndTextAlignment(); + + //at end: + float distanceFromOrigin_toStartOfEndArrow = maxDistance - original_distanceFromOrigin_toStartOfStartArrow_excludingCompensationForCapsules - arrowLength; + if (signedDistance_fromSphere1ActingAsOrigin_toActualCapsuleCenter_alongCastDir < 0.0f) + { + distanceFromOrigin_toStartOfEndArrow = distanceFromOrigin_toStartOfEndArrow + 2.0f * signedDistance_fromSphere1ActingAsOrigin_toActualCapsuleCenter_alongCastDir; + } + distance_ofEndArrowsStartPos = distanceFromOrigin_toStartOfEndArrow; + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.high_withFullDetails) + { + if (maxDistance > (distanceFromOrigin_toStartOfStartArrow + 12.0f * arrowLength)) + { + isAfterLastHit = hasHit && ((distanceFromOrigin_toStartOfEndArrow + 0.5f * arrowLength) > distanceOfFarestHit); + Vector3 endVector_startPos = origin + direction_normalized * distanceFromOrigin_toStartOfEndArrow + capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir; + Vector3 endVector_endPos = origin + direction_normalized * (distanceFromOrigin_toStartOfEndArrow + arrowLength) + capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir; + + UtilitiesDXXL_DrawBasics.Set_automaticAmplitudeAndTextAlignment_reversible(DrawBasics.AutomaticAmplitudeAndTextAlignment.perpendicularToCamera); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + UtilitiesDXXL_DrawBasics.Vector(endVector_startPos, endVector_endPos, isAfterLastHit ? color_ofCastEnd_lowerAlpha : color_lowerAlpha, arrowWidth, null, arrowsRelConeLenth, false, true, false, 0.0f, false, durationInSec, hiddenByNearerObjects, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + UtilitiesDXXL_DrawBasics.Reverse_automaticAmplitudeAndTextAlignment(); + } + } + } + } + + static int FillSphereCastOutlineVerticesArray(Vector3 origin, Vector3 direction_normalized, float sphereRadius) + { + int usedSlotsIn_verticesPerOutlineCircle = 32; + UtilitiesDXXL_Shapes.DrawFlatPolygon(0.0f, usedSlotsIn_verticesPerOutlineCircle, origin, sphereRadius, direction_normalized, default, default, 0.0f, null, 0.0f, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, false, true); + for (int i = 0; i < usedSlotsIn_verticesPerOutlineCircle; i++) + { + volumeCastOutlineVertices_local[i] = UtilitiesDXXL_Shapes.verticesGlobal[i] - origin; + } + return usedSlotsIn_verticesPerOutlineCircle; + } + + static int FillSphereCastReducedOutlineVerticesArray(Vector3 origin, Vector3 direction_normalized, float sphereRadius, bool radiusIsZero) + { + if (radiusIsZero) + { + int usedSlotsIn_verticesPerReducedOutlineCircle = 1; + volumeCastOutlineVerticesReduced_local[0] = Vector3.zero; + return usedSlotsIn_verticesPerReducedOutlineCircle; + } + else + { + int usedSlotsIn_verticesPerReducedOutlineCircle = 4; + UtilitiesDXXL_Shapes.DrawFlatPolygon(0.0f, usedSlotsIn_verticesPerReducedOutlineCircle, origin, sphereRadius, direction_normalized, default, default, 0.0f, null, 0.0f, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, false, true); + for (int i = 0; i < usedSlotsIn_verticesPerReducedOutlineCircle; i++) + { + volumeCastOutlineVerticesReduced_local[i] = UtilitiesDXXL_Shapes.verticesGlobal[i] - origin; + } + return usedSlotsIn_verticesPerReducedOutlineCircle; + } + } + + static int FillBoxCastOutlineVerticesArray(Vector3 direction_normalized, int usedSlotsIn_verticesPerReducedOutlineCircle) + { + int usedSlotsIn_verticesPerOutlineCircle = usedSlotsIn_verticesPerReducedOutlineCircle; + castDirPlaneThroughWorldZeroOrigin.Recreate(Vector3.zero, direction_normalized); + for (int i = 0; i < usedSlotsIn_verticesPerOutlineCircle; i++) + { + volumeCastOutlineVertices_local[i] = castDirPlaneThroughWorldZeroOrigin.Get_perpProjectionOfPointOnPlane(volumeCastOutlineVerticesReduced_local[i]); + } + return usedSlotsIn_verticesPerOutlineCircle; + } + + ///cube definition: + //viewed along z-forward: + //starts with: nearer square, lowLeft, then counterclockwise + //then: farer square, same pattern + static Vector3[] unscaledUnrotatedBox = new Vector3[8] { new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(0.5f, -0.5f, -0.5f), new Vector3(0.5f, 0.5f, -0.5f), new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, 0.5f, 0.5f), new Vector3(-0.5f, 0.5f, 0.5f) }; + static int FillBoxCastReducedOutlineVerticesArray(Vector3 direction_normalized, Vector3 boxSize, Quaternion boxRotation, Vector3 boxForward_normalized, Vector3 boxUp_normalized, Vector3 boxRight_normalized) + { + int usedSlotsIn_verticesPerReducedOutlineCircle = 4; + if (UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(direction_normalized, boxForward_normalized)) + { + //castDir parallel to box.forward/backward: + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + } + else + { + if (UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(direction_normalized, boxUp_normalized)) + { + //castDir parallel to box.up/down: + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + } + else + { + if (UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(direction_normalized, boxRight_normalized)) + { + //castDir parallel to box.right/left: + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + } + else + { + if (UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxPerp_DXXL(direction_normalized, boxUp_normalized)) + { + //box rotated around boxUp (seen along castDir): + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxForward_normalized)) + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxRight_normalized)) + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + } + } + else + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxRight_normalized)) + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + } + } + + } + else + { + if (UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxPerp_DXXL(direction_normalized, boxForward_normalized)) + { + //box rotated around boxForward (seen along castDir): + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxUp_normalized)) + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxRight_normalized)) + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + } + } + else + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxRight_normalized)) + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + } + } + } + else + { + if (UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxPerp_DXXL(direction_normalized, boxRight_normalized)) + { + //box rotated around boxRight (seen along castDir): + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxForward_normalized)) + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxUp_normalized)) + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + } + } + else + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxUp_normalized)) + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + } + } + } + else + { + //a cube corner points along castDir: + usedSlotsIn_verticesPerReducedOutlineCircle = 6; + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxForward_normalized)) + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxUp_normalized)) + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxRight_normalized)) + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[4] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + volumeCastOutlineVerticesReduced_local[5] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[4] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[5] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + } + } + else + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxRight_normalized)) + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[4] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + volumeCastOutlineVerticesReduced_local[5] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[4] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + volumeCastOutlineVerticesReduced_local[5] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + } + } + } + else + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxUp_normalized)) + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxRight_normalized)) + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[4] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + volumeCastOutlineVerticesReduced_local[5] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[4] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + volumeCastOutlineVerticesReduced_local[5] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + } + } + else + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized, boxRight_normalized)) + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[0], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[6], boxSize); + volumeCastOutlineVerticesReduced_local[4] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[5] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + } + else + { + volumeCastOutlineVerticesReduced_local[0] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[4], boxSize); + volumeCastOutlineVerticesReduced_local[1] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[5], boxSize); + volumeCastOutlineVerticesReduced_local[2] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[1], boxSize); + volumeCastOutlineVerticesReduced_local[3] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[2], boxSize); + volumeCastOutlineVerticesReduced_local[4] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[3], boxSize); + volumeCastOutlineVerticesReduced_local[5] = boxRotation * Vector3.Scale(unscaledUnrotatedBox[7], boxSize); + } + } + } + } + } + } + } + } + } + return usedSlotsIn_verticesPerReducedOutlineCircle; + } + + static int FillCapsuleCastOutlineVerticesArray(bool capsuleAppearsAsSphereAlongCastDir, Vector3 posOfCapsuleSphere1_atCastStart, Vector3 posOfCapsuleSphere2_atCastStart, Vector3 direction_normalized, float capsuleRadius, Vector3 towardsRight_ofSphere1_viewedAlongCastDir) + { + if (capsuleAppearsAsSphereAlongCastDir) + { + return FillSphereCastOutlineVerticesArray(posOfCapsuleSphere1_atCastStart, direction_normalized, capsuleRadius); + } + else + { + int usedSlotsIn_verticesPerOutlineCircle = 34; + Vector3 towardsLeft_ofSphere1_viewedAlongCastDir = -towardsRight_ofSphere1_viewedAlongCastDir; + + Vector3 posOfCapsuleSphere2_projectedOntoCastDirPlaneThroughSphere1 = planePerpToCastDir_throughCapsulesSphere1AtCastStartPos.Get_perpProjectionOfPointOnPlane(posOfCapsuleSphere2_atCastStart); + Vector3 sphere2projectionOntoCastDirPlane_localToSphere1 = posOfCapsuleSphere2_projectedOntoCastDirPlaneThroughSphere1 - posOfCapsuleSphere1_atCastStart; + + float angleDeg_perVertext = 180.0f / (float)(16 - 1); + for (int i = 0; i < 17; i++) + { + Quaternion rotation_ofCurrVertex = UnityEngine.Quaternion.AngleAxis(angleDeg_perVertext * i, direction_normalized); + volumeCastOutlineVertices_local[i] = rotation_ofCurrVertex * towardsRight_ofSphere1_viewedAlongCastDir; + volumeCastOutlineVertices_local[i + 17] = sphere2projectionOntoCastDirPlane_localToSphere1 + rotation_ofCurrVertex * towardsLeft_ofSphere1_viewedAlongCastDir; + } + return usedSlotsIn_verticesPerOutlineCircle; + } + } + + static int FillCapsuleCastReducedOutlineVerticesArray(bool capsuleAppearsAsSphereAlongCastDir, Vector3 posOfCapsuleSphere1_atCastStart, Vector3 posOfCapsuleSphere2_atCastStart, Vector3 direction_normalized, float capsuleRadius, bool radiusIsZero, Vector3 towardsRight_ofSphere1_viewedAlongCastDir) + { + Vector3 capsuleSphere1_toSphere2 = posOfCapsuleSphere2_atCastStart - posOfCapsuleSphere1_atCastStart; + if (radiusIsZero) + { + int usedSlotsIn_verticesPerReducedOutlineCircle = 2; + volumeCastOutlineVerticesReduced_local[0] = Vector3.zero; + volumeCastOutlineVerticesReduced_local[1] = capsuleSphere1_toSphere2; + return usedSlotsIn_verticesPerReducedOutlineCircle; + } + else + { + if (capsuleAppearsAsSphereAlongCastDir) + { + return FillSphereCastReducedOutlineVerticesArray(posOfCapsuleSphere1_atCastStart, direction_normalized, capsuleRadius, false); + } + else + { + int usedSlotsIn_verticesPerReducedOutlineCircle = 6; + + Quaternion rotationFromRightToUp = UnityEngine.Quaternion.AngleAxis(90.0f, direction_normalized); + Vector3 towardsUp_ofSphere1_viewedAlongCastDir = rotationFromRightToUp * towardsRight_ofSphere1_viewedAlongCastDir; + + volumeCastOutlineVerticesReduced_local[0] = towardsRight_ofSphere1_viewedAlongCastDir; + volumeCastOutlineVerticesReduced_local[1] = -towardsRight_ofSphere1_viewedAlongCastDir; + volumeCastOutlineVerticesReduced_local[2] = towardsUp_ofSphere1_viewedAlongCastDir; + + volumeCastOutlineVerticesReduced_local[3] = capsuleSphere1_toSphere2 + towardsRight_ofSphere1_viewedAlongCastDir; + volumeCastOutlineVerticesReduced_local[4] = capsuleSphere1_toSphere2 - towardsRight_ofSphere1_viewedAlongCastDir; + volumeCastOutlineVerticesReduced_local[5] = capsuleSphere1_toSphere2 - towardsUp_ofSphere1_viewedAlongCastDir; + + return usedSlotsIn_verticesPerReducedOutlineCircle; + } + } + } + + static void DrawVolumeCastDirOutline(int usedSlotsIn_verticesPerReducedOutlineCircle, bool hasHit, Vector3 origin, Vector3 endPos, Vector3 direction_normalized, float distanceOfFarestHit, Color color_lowAlpha, Color color_ofCastEnd_lowAlpha, float durationInSec, bool hiddenByNearerObjects) + { + for (int i = 0; i < usedSlotsIn_verticesPerReducedOutlineCircle; i++) + { + if (hasHit) + { + Vector3 posOfFarestHit = origin + direction_normalized * distanceOfFarestHit; + Line_fadeableAnimSpeed.InternalDraw(origin + volumeCastOutlineVerticesReduced_local[i], posOfFarestHit + volumeCastOutlineVerticesReduced_local[i], color_lowAlpha, 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(posOfFarestHit + volumeCastOutlineVerticesReduced_local[i], endPos + volumeCastOutlineVerticesReduced_local[i], color_ofCastEnd_lowAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + Line_fadeableAnimSpeed.InternalDraw(origin + volumeCastOutlineVerticesReduced_local[i], endPos + volumeCastOutlineVerticesReduced_local[i], color_lowAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + + static void DrawCascadeOfVolumeSilhouettes(int usedSlotsIn_verticesPerOutlineCircle, float sizeApproximationOfVolume, bool hasHit, bool hasUnlimitedLength, Vector3 origin, Vector3 direction_normalized, float maxDistance, float distanceOfFarestHit, Color color, Color color_ofCastEnd, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + if (UtilitiesDXXL_Math.ApproximatelyZero(DrawPhysics.castSilhouetteVisualizerDensity) == false) + { + float distanceBetweenSilhouettes = hasUnlimitedLength ? (6.0f * sizeApproximationOfVolume) : (3.25f * sizeApproximationOfVolume); + int maxSilhouettesPerVolumeCast = hasUnlimitedLength ? 5 : 15; + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + distanceBetweenSilhouettes = hasUnlimitedLength ? (6.0f * sizeApproximationOfVolume) : (4.5f * sizeApproximationOfVolume); + maxSilhouettesPerVolumeCast = hasUnlimitedLength ? 2 : 5; + } + + float used_castSilhouetteVisualizerDensity = DrawPhysics.castSilhouetteVisualizerDensity; + used_castSilhouetteVisualizerDensity = Mathf.Max(used_castSilhouetteVisualizerDensity, 0.01f); + used_castSilhouetteVisualizerDensity = Mathf.Min(used_castSilhouetteVisualizerDensity, 1000.0f); + distanceBetweenSilhouettes = distanceBetweenSilhouettes / used_castSilhouetteVisualizerDensity; + if (used_castSilhouetteVisualizerDensity > 1.0f) { maxSilhouettesPerVolumeCast = Mathf.RoundToInt(used_castSilhouetteVisualizerDensity * maxSilhouettesPerVolumeCast); } + maxSilhouettesPerVolumeCast = Mathf.Min(maxSilhouettesPerVolumeCast, DrawPhysics.maxSilhouettesPerCastVisualization); + + distanceBetweenSilhouettes = Mathf.Max(distanceBetweenSilhouettes, 0.5f); + float distance_ofCurrSilhouette = 0.0f; + for (int i_silhouette = 0; i_silhouette < maxSilhouettesPerVolumeCast; i_silhouette++) + { + distance_ofCurrSilhouette = distance_ofCurrSilhouette + distanceBetweenSilhouettes; + bool isAfterLastHit = hasHit && (distance_ofCurrSilhouette > distanceOfFarestHit); + if (distance_ofCurrSilhouette < maxDistance) + { + Vector3 posOfCurrSilhouetteOnRayLine = origin + distance_ofCurrSilhouette * direction_normalized; + for (int i_lineOfSilhouette = 0; i_lineOfSilhouette < usedSlotsIn_verticesPerOutlineCircle; i_lineOfSilhouette++) + { + Line_fadeableAnimSpeed.InternalDraw(posOfCurrSilhouetteOnRayLine + volumeCastOutlineVertices_local[i_lineOfSilhouette], posOfCurrSilhouetteOnRayLine + volumeCastOutlineVertices_local[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i_lineOfSilhouette + 1, usedSlotsIn_verticesPerOutlineCircle)], isAfterLastHit ? color_ofCastEnd : color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + else + { + break; + } + + if (hasUnlimitedLength) + { + distanceBetweenSilhouettes = (1.0f + (1.0f / used_castSilhouetteVisualizerDensity)) * distanceBetweenSilhouettes; + } + else + { + if (i_silhouette > 3 || (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes)) + { + distanceBetweenSilhouettes = (1.0f + (0.5f / used_castSilhouetteVisualizerDensity)) * distanceBetweenSilhouettes; + } + } + } + } + } + + static void DrawCascadeOfArrows(float distance_ofStartArrowsStartPos, float distance_ofEndArrowsStartPos, float sizeApproximationOfVolume, bool hasHit, bool hasUnlimitedLength, Vector3 origin, Vector3 direction_normalized, float distanceOfFarestHit, float arrowLength, float arrowWidth, float arrowsRelConeLenth, Color color_lowerAlpha, Color color_ofCastEnd_lowerAlpha, float durationInSec, bool hiddenByNearerObjects, Vector3 capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir = default(Vector3)) + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.high_withFullDetails) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(DrawPhysics.castSilhouetteVisualizerDensity) == false) + { + if (arrowLength > minArrowLength) + { + float distanceBetweenArrows = hasUnlimitedLength ? (6.0f * sizeApproximationOfVolume) : (3.25f * sizeApproximationOfVolume); + int maxArrowsPerVolumeCast = hasUnlimitedLength ? 5 : 15; + + distanceBetweenArrows = Mathf.Max(distanceBetweenArrows, 0.5f); + float distance_ofCurrArrowsStart = distance_ofStartArrowsStartPos + distanceBetweenArrows; + for (int i_arrow = 0; i_arrow < maxArrowsPerVolumeCast; i_arrow++) + { + if (distance_ofCurrArrowsStart < distance_ofEndArrowsStartPos) + { + bool isAfterLastHit = hasHit && ((distance_ofCurrArrowsStart + 0.5f * arrowLength) > distanceOfFarestHit); + Vector3 vectorStartPos = origin + distance_ofCurrArrowsStart * direction_normalized + capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir; + Vector3 vectorEndPos = origin + (distance_ofCurrArrowsStart + arrowLength) * direction_normalized + capsuleSphere1ToCapsuleSilhoutteCenter_perpToCastDir; + + UtilitiesDXXL_DrawBasics.Set_automaticAmplitudeAndTextAlignment_reversible(DrawBasics.AutomaticAmplitudeAndTextAlignment.perpendicularToCamera); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + UtilitiesDXXL_DrawBasics.Vector(vectorStartPos, vectorEndPos, isAfterLastHit ? color_ofCastEnd_lowerAlpha : color_lowerAlpha, arrowWidth, null, arrowsRelConeLenth, false, true, false, 0.0f, false, durationInSec, hiddenByNearerObjects, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + UtilitiesDXXL_DrawBasics.Reverse_automaticAmplitudeAndTextAlignment(); + } + else + { + break; + } + + if (hasUnlimitedLength) + { + distanceBetweenArrows = 2.0f * distanceBetweenArrows; + } + else + { + if (i_arrow > 3) + { + distanceBetweenArrows = 1.5f * distanceBetweenArrows; + } + } + distance_ofCurrArrowsStart = distance_ofCurrArrowsStart + distanceBetweenArrows; + } + } + } + } + } + + static void WriteTextAtSphereCastOrigin(Vector3 origin, Vector3 direction_normalized, float sphereRadius, bool sphereHasNegativeRadius, Color color, string nameText, int hitCount, float maxDistance, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + Vector3 sphereUp_normalized = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(direction_normalized); + if (sphereUp_normalized.y < 0.0f) { sphereUp_normalized = -sphereUp_normalized; } + float textSize = 0.2f * sphereRadius; + textSize = Mathf.Max(textSize, 0.02f); + Color textColor = Color.Lerp(color, Color.black, 0.75f); + string additinalWarningText = sphereHasNegativeRadius ? "[ negative sphere radius -> invalid results and/or hitting sphere will be inside other colliders]
" : null; + string castText = GetVolumeCastStartTextString("Spherecast

number of hits: ", nameText, hitCount, maxDistance, additinalWarningText); + Vector3 textPos = origin + sphereUp_normalized * (sphereRadius + 0.65f * textSize); + UtilitiesDXXL_Text.Write(castText, textPos, textColor, textSize, direction_normalized, sphereUp_normalized, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.solid, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + + static void WriteTextAtBoxCastOrigin(Vector3 origin, Vector3 direction_normalized, Vector3 boxSize, bool atLeastOneBoxDimIsNegative, Vector3 boxUp_normalized, Color color, string nameText, int hitCount, float maxDistance, float averageBoxSize, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + if (boxUp_normalized.y < 0.0f) { boxUp_normalized = -boxUp_normalized; } + float absBoxHalfHeight = Mathf.Abs(0.5f * boxSize.y); + float textSize = 0.1f * averageBoxSize; + textSize = Mathf.Max(textSize, 0.02f); + Color textColor = Color.Lerp(color, Color.black, 0.75f); + string additinalWarningText = atLeastOneBoxDimIsNegative ? "[ box contains negative dimensions
-> invalid results and/or hitting box may be inside other colliders
-> cast visualisation displays box silhouette errorneous]
" : null; + string castText = GetVolumeCastStartTextString("Boxcast

number of hits: ", nameText, hitCount, maxDistance, additinalWarningText); + Vector3 textPos = origin + boxUp_normalized * (absBoxHalfHeight + 0.65f * textSize); + bool directionAndUp_areApproxParallel = UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(direction_normalized, boxUp_normalized); + Vector3 textUp = directionAndUp_areApproxParallel ? default(Vector3) : boxUp_normalized; + UtilitiesDXXL_Text.WriteFramed(castText, textPos, textColor, textSize, direction_normalized, textUp, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.solid, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + + static void WriteTextAtCapsuleCastOrigin(bool capsuleAppearsAsSphereAlongCastDir, Vector3 posOfCapsuleSphere1_atCastStart, Vector3 posOfCapsuleSphere2_atCastStart, Vector3 direction_normalized, float capsuleRadius, bool capsuleHasNegativeRadius, Color color, string nameText, int hitCount, float maxDistance, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + Vector3 posOfHigherCapsule = (posOfCapsuleSphere1_atCastStart.y > posOfCapsuleSphere2_atCastStart.y) ? posOfCapsuleSphere1_atCastStart : posOfCapsuleSphere2_atCastStart; + Vector3 higherSphereUp = (posOfCapsuleSphere1_atCastStart.y > posOfCapsuleSphere2_atCastStart.y) ? (posOfCapsuleSphere1_atCastStart - posOfCapsuleSphere2_atCastStart) : (posOfCapsuleSphere2_atCastStart - posOfCapsuleSphere1_atCastStart); + Vector3 higherSphereUp_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(higherSphereUp); + if (capsuleAppearsAsSphereAlongCastDir) + { + higherSphereUp_normalized = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(direction_normalized); + } + if (higherSphereUp_normalized.y < 0.0f) { higherSphereUp_normalized = -higherSphereUp_normalized; } + float textSize = 0.2f * capsuleRadius; + textSize = Mathf.Max(textSize, 0.02f); + Color textColor = Color.Lerp(color, Color.black, 0.75f); + string additinalWarningText = capsuleHasNegativeRadius ? "[ negative capsule radius -> invalid results and/or hitting capsule will be inside other colliders]
" : null; + string castText = GetVolumeCastStartTextString("Capsulecast

number of hits: ", nameText, hitCount, maxDistance, additinalWarningText); + Vector3 textPos = posOfHigherCapsule + higherSphereUp_normalized * (capsuleRadius + 0.65f * textSize); + UtilitiesDXXL_Text.WriteFramed(castText, textPos, textColor, textSize, direction_normalized, higherSphereUp_normalized, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.solid, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + + static string GetVolumeCastStartTextString(string volumeCastTypeIdentifyingStringPart, string nameText, int hitCount, float maxDistance, string additinalWarningText) + { + additinalWarningText = UtilitiesDXXL_Math.ApproximatelyZero(maxDistance) ? "[ cast distance is zero]
" + additinalWarningText : additinalWarningText; + additinalWarningText = (maxDistance < 0.0f) ? "[ negative cast direction -> no hits will be detected]
" + additinalWarningText : additinalWarningText; + + string startText; + if (DrawPhysics.drawCastNameTag_atCastOrigin && nameText != null && nameText.Length != 0) + { + startText = (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? additinalWarningText + GetSizeMarkupStartStringForCastNames(nameText) + nameText + "

hits: " + hitCount : additinalWarningText + GetSizeMarkupStartStringForCastNames(nameText) + nameText + "

number of hits: " + hitCount; + } + else + { + startText = (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? additinalWarningText + "hits: " + hitCount : additinalWarningText + volumeCastTypeIdentifyingStringPart + hitCount; + } + + return startText; + } + + static void DrawSpherecastHitInfo(Vector3 castOrigin, Vector3 direction_normalized, float sphereRadius, bool sphereHasNegativeRadius, RaycastHit hitInfo, int i_hit, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.FloatIsInvalid(hitInfo.distance)) + { + Debug.LogError("Draw XXL: A 'Physics.SphereCast()' returned an invalid hit distance of '" + hitInfo.distance + "'. The drawn cast visualization may be incorrect."); + } + else + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo.point) || UtilitiesDXXL_Math.VectorIsInvalid(hitInfo.normal)) + { + Debug.LogError("Draw XXL: A 'Physics.SphereCast()' returned an invalid hit position (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + ") or normal (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.normal) + "). The drawn cast visualization may be incorrect."); + } + else + { + bool saveDrawnLines = i_hit >= DrawPhysics.hitResultsWithMoreDetailedDisplay; + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.high_withFullDetails) { saveDrawnLines = true; } + + DrawSphereAtHitPos(castOrigin, direction_normalized, hitInfo, i_hit, sphereRadius, durationInSec, hiddenByNearerObjects); + DrawNormalAtVolumeCastHitPos(saveDrawnLines, hitInfo, direction_normalized, durationInSec, hiddenByNearerObjects); + string text = GetTextAtHitPos_forVolumeCast("Spherecast hit #", saveDrawnLines, hitInfo, i_hit, nameText); + string additionalWarningText = sphereHasNegativeRadius ? "
[ negative sphere radius -> hitting sphere inside other collider]" : null; + DrawTextDescriptionAtVolumeCastHitPos(hitInfo, nameText, text, durationInSec, hiddenByNearerObjects, additionalWarningText); + } + } + } + + static void DrawBoxcastHitInfo(Vector3 castOrigin, Vector3 direction_normalized, Vector3 boxSize, bool atLeastOneBoxDimIsNegative, Vector3 boxForward_normalized, Vector3 boxUp_normalized, RaycastHit hitInfo, int i_hit, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.FloatIsInvalid(hitInfo.distance)) + { + Debug.LogError("Draw XXL: A 'Physics.BoxCast()' returned an invalid hit distance of '" + hitInfo.distance + "'. The drawn cast visualization may be incorrect."); + } + else + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo.point) || UtilitiesDXXL_Math.VectorIsInvalid(hitInfo.normal)) + { + Debug.LogError("Draw XXL: A 'Physics.BoxCast()' returned an invalid hit position (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + ") or normal (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.normal) + "). The drawn cast visualization may be incorrect."); + } + else + { + bool saveDrawnLines = i_hit >= DrawPhysics.hitResultsWithMoreDetailedDisplay; + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.high_withFullDetails) { saveDrawnLines = true; } + + DrawBoxAtHitPos(castOrigin, direction_normalized, boxSize, boxForward_normalized, boxUp_normalized, hitInfo, durationInSec, hiddenByNearerObjects); + DrawNormalAtVolumeCastHitPos(saveDrawnLines, hitInfo, direction_normalized, durationInSec, hiddenByNearerObjects); + string text = GetTextAtHitPos_forVolumeCast("Boxcast hit #", saveDrawnLines, hitInfo, i_hit, nameText); + string additionalWarningText = atLeastOneBoxDimIsNegative ? "
[ box contains negative dimensions -> hitting box may be inside other collider]" : null; + DrawTextDescriptionAtVolumeCastHitPos(hitInfo, nameText, text, durationInSec, hiddenByNearerObjects, additionalWarningText); + } + } + } + + static void DrawCapsulecastHitInfo(Vector3 posOfCapsuleSphere1_atCastStart, Vector3 posOfCapsuleSphere2_atCastStart, Vector3 direction_normalized, float capsuleRadius, bool capsuleHasNegativeRadius, RaycastHit hitInfo, int i_hit, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.FloatIsInvalid(hitInfo.distance)) + { + Debug.LogError("Draw XXL: A 'Physics.CapsuleCast()' returned an invalid hit distance of '" + hitInfo.distance + "'. The drawn cast visualization may be incorrect."); + } + else + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo.point) || UtilitiesDXXL_Math.VectorIsInvalid(hitInfo.normal)) + { + Debug.LogError("Draw XXL: A 'Physics.CapsuleCast()' returned an invalid hit position (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + ") or normal (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.normal) + "). The drawn cast visualization may be incorrect."); + } + else + { + bool saveDrawnLines = i_hit >= DrawPhysics.hitResultsWithMoreDetailedDisplay; + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.high_withFullDetails) { saveDrawnLines = true; } + + DrawCapsuleAtHitPos(posOfCapsuleSphere1_atCastStart, posOfCapsuleSphere2_atCastStart, direction_normalized, capsuleRadius, hitInfo, i_hit, durationInSec, hiddenByNearerObjects); + DrawNormalAtVolumeCastHitPos(saveDrawnLines, hitInfo, direction_normalized, durationInSec, hiddenByNearerObjects); + string text = GetTextAtHitPos_forVolumeCast("Capsulecast hit #", saveDrawnLines, hitInfo, i_hit, nameText); + string additionalWarningText = capsuleHasNegativeRadius ? "
[ negative capsule radius -> hitting capsule inside other collider]" : null; + DrawTextDescriptionAtVolumeCastHitPos(hitInfo, nameText, text, durationInSec, hiddenByNearerObjects, additionalWarningText); + } + } + } + + public static void DrawSilhouettesAroundHitPos(float volumeSize, Vector3 origin, Vector3 direction_normalized, RaycastHit hitInfo, float maxDistance, int usedSlotsIn_verticesPerOutlineCircle, Color color, Color color_ofCastEnd, float distanceOfFarestHit, float durationInSec, bool hiddenByNearerObjects) + { + //"DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes" not defined yet + if (UtilitiesDXXL_Math.FloatIsInvalid(hitInfo.distance)) + { + Debug.LogError("Draw XXL: A 'Physics.Cast()' returned an invalid hit distance of '" + hitInfo.distance + "'. The drawn cast visualization may be incorrect."); + } + else + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.high_withFullDetails) + { + int silhouettesPerHitPos = 7; + float distanceBetweenSilhouettes = 0.75f * volumeSize; + float distanceOfFirstSilhouette = hitInfo.distance - distanceBetweenSilhouettes * 3; + for (int i_silhouette = 0; i_silhouette < silhouettesPerHitPos; i_silhouette++) + { + float distance_ofCurrSilhouette = distanceOfFirstSilhouette + distanceBetweenSilhouettes * i_silhouette; + if (distance_ofCurrSilhouette > 0.0f && distance_ofCurrSilhouette < maxDistance) + { + Vector3 posOfCurrSilhouetteOnRayLine = origin + distance_ofCurrSilhouette * direction_normalized; + bool isAfterLastHit = (distance_ofCurrSilhouette > distanceOfFarestHit); + for (int i_lineOfSilhouette = 0; i_lineOfSilhouette < usedSlotsIn_verticesPerOutlineCircle; i_lineOfSilhouette++) + { + Line_fadeableAnimSpeed.InternalDraw(posOfCurrSilhouetteOnRayLine + volumeCastOutlineVertices_local[i_lineOfSilhouette], posOfCurrSilhouetteOnRayLine + volumeCastOutlineVertices_local[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i_lineOfSilhouette + 1, usedSlotsIn_verticesPerOutlineCircle)], isAfterLastHit ? color_ofCastEnd : color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + } + } + } + + static void DrawSphereAtHitPos(Vector3 castOrigin, Vector3 direction_normalized, RaycastHit hitInfo, int i_hit, float sphereRadius, float durationInSec, bool hiddenByNearerObjects) + { + int usedSphereStruts = strutsPerCastSphere; + Vector3 hittingSpherePosition = castOrigin + direction_normalized * hitInfo.distance; + + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { usedSphereStruts = 2; } + if ((DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) && i_hit > 1) { usedSphereStruts = 6; } + if ((DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) && i_hit > 3) { usedSphereStruts = 4; } + if ((DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) && i_hit > 5) { usedSphereStruts = 2; } + + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(64); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(32); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(16); + break; + default: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(64); + break; + } + + Color color_ofHittingVolume = Color.Lerp(DrawPhysics.colorForHittingCasts, Color.white, 0.6f); + DrawShapes.Sphere(hittingSpherePosition, sphereRadius, color_ofHittingVolume, direction_normalized, default(Vector3), 0.0f, null, usedSphereStruts, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + } + + static void DrawBoxAtHitPos(Vector3 castOrigin, Vector3 direction_normalized, Vector3 boxSize, Vector3 boxForward, Vector3 boxUp, RaycastHit hitInfo, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 hittingBoxPosition = castOrigin + direction_normalized * hitInfo.distance; + Color color_ofHittingVolume_ofEdges = Color.Lerp(DrawPhysics.colorForHittingCasts, Color.white, 0.6f); + Color color_ofHittingVolume_ofPlaneFillLines = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofHittingVolume_ofEdges, 0.4f); //-> This helps to distinguish boxes that intersect each other. + + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + DrawShapes.Cube(hittingBoxPosition, boxSize, color_ofHittingVolume_ofPlaneFillLines, boxUp, boxForward, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + else + { + DrawShapes.CubeFilled(hittingBoxPosition, boxSize, color_ofHittingVolume_ofPlaneFillLines, boxUp, boxForward, 0.0f, 4, null, DrawBasics.LineStyle.solid, color_ofHittingVolume_ofEdges, 0.0f, 1.0f, true, false, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawCapsuleAtHitPos(Vector3 posOfCapsuleSphere1_atCastStart, Vector3 posOfCapsuleSphere2_atCastStart, Vector3 direction_normalized, float capsuleRadius, RaycastHit hitInfo, int i_hit, float durationInSec, bool hiddenByNearerObjects) + { + int usedCapsuleStruts = strutsPerCastCapsule; + Vector3 hittingCapsuleSphere1Position = posOfCapsuleSphere1_atCastStart + direction_normalized * hitInfo.distance; + Vector3 hittingCapsuleSphere2Position = posOfCapsuleSphere2_atCastStart + direction_normalized * hitInfo.distance; + + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { usedCapsuleStruts = 2; } + if ((DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) && i_hit > 1) { usedCapsuleStruts = 6; } + if ((DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) && i_hit > 3) { usedCapsuleStruts = 4; } + if ((DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) && i_hit > 5) { usedCapsuleStruts = 2; } + + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(64); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(32); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(16); + break; + default: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(64); + break; + } + + Color color_ofHittingVolume = Color.Lerp(DrawPhysics.colorForHittingCasts, Color.white, 0.6f); + DrawShapes.Capsule(hittingCapsuleSphere1Position, hittingCapsuleSphere2Position, capsuleRadius, color_ofHittingVolume, direction_normalized, 0.0f, null, usedCapsuleStruts, false, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + } + + static void DrawNormalAtVolumeCastHitPos(bool saveDrawnLines, RaycastHit hitInfo, Vector3 direction_normalized, float durationInSec, bool hiddenByNearerObjects) + { + Color color_ofNormal = Get_color_ofNormal(); + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + DrawBasics.LineFrom(hitInfo.point, hitInfo.normal, color_ofNormal, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + float relConeLength_ofNormalVector = 0.17f; + string normalText = (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? null : (saveDrawnLines ? "normal" : "normal
of hit surface"); + + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics.VectorFrom(hitInfo.point, hitInfo.normal, color_ofNormal, saveDrawnLines ? 0.0f : 0.006f, normalText, relConeLength_ofNormalVector, false, false, default(Vector3), false, 0.01f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + //normal socket: + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + DrawShapes.Decagon(hitInfo.point, 0.02f, color_ofNormal, hitInfo.normal, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Decagon(hitInfo.point, 0.04f, color_ofNormal, hitInfo.normal, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + DrawShapes.Decagon(hitInfo.point, 0.06f, color_ofNormal, hitInfo.normal, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + DrawShapes.Decagon(hitInfo.point, 0.06f, color_ofNormal, hitInfo.normal, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + DrawShapes.Square(hitInfo.point, 0.12f, color_ofNormal, hitInfo.normal, direction_normalized, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + break; + default: + break; + } + + } + + static Color Get_color_ofNormal() + { + if (UtilitiesDXXL_Colors.IsDefaultColor(DrawPhysics.overwriteColorForCastsHitNormals)) + { + return Get_defaultColor_ofNormal(); + } + else + { + return DrawPhysics.overwriteColorForCastsHitNormals; + } + } + + public static Color Get_defaultColor_ofNormal() + { + return ((DrawPhysics.colorForHittingCasts.grayscale < 0.175f) ? Color.Lerp(DrawPhysics.colorForHittingCasts, Color.white, 0.7f) : Color.Lerp(DrawPhysics.colorForHittingCasts, Color.black, 0.7f)); + } + + static string GetTextAtHitPos_forVolumeCast(string volumeCastTypeSpecifyingStringPart, bool saveDrawnLines, RaycastHit hitInfo, int i_hit, string nameText) + { + if (DrawPhysics.drawCastNameTag_atHitPositions && nameText != null && nameText.Length != 0) + { + return (saveDrawnLines ? (nameText + " / #" + i_hit + ":
hit GO: " + hitInfo.transform.gameObject.name + "
pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + "
dist = " + hitInfo.distance) : (GetStrokeWidthMarkupStartStringForHitPosDesctiptionHeaders(nameText) + nameText + " / hit #" + i_hit + ":
GameObject that was hit: " + hitInfo.transform.gameObject.name + "
hit pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + "
distance = " + hitInfo.distance)); + } + else + { + return (saveDrawnLines ? ("hit #" + i_hit + ":
hit GO: " + hitInfo.transform.gameObject.name + "
pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + "
dist = " + hitInfo.distance) : (volumeCastTypeSpecifyingStringPart + i_hit + ":
GameObject that was hit: " + hitInfo.transform.gameObject.name + "
hit pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo.point) + "
distance = " + hitInfo.distance)); + } + } + + static void DrawTextDescriptionAtVolumeCastHitPos(RaycastHit hitInfo, string nameText, string text, float durationInSec, bool hiddenByNearerObjects, string additionalWarningText) + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + if (DrawPhysics.drawCastNameTag_atHitPositions && nameText != null && nameText.Length != 0) + { + UtilitiesDXXL_Text.WriteFramed(nameText + additionalWarningText, hitInfo.point, DrawPhysics.colorForCastsHitText, 0.1f * DrawPhysics.scaleFactor_forCastHitTextSize, default(Vector3), default(Vector3), DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + } + else + { + Vector3 textOffsetDir = default(Vector3); + float textOffsetDistance = DrawPhysics.scaleFactor_forCastHitTextSize; + + TrySet_default_textOffsetDirection_forPointTags_reversible(); + DrawBasics.PointTag(hitInfo.point, text + additionalWarningText, DrawPhysics.colorForCastsHitText, 0.0f, textOffsetDistance, textOffsetDir, 1.0f, false, durationInSec, hiddenByNearerObjects); + TryReverse_default_textOffsetDirection_forPointTags(); + } + } + + static float GetDistanceOfSingleHit(bool hasHit, RaycastHit hitInfo) + { + if (hasHit) + { + if (UtilitiesDXXL_Math.FloatIsInvalid(hitInfo.distance)) + { + Debug.LogError("Draw XXL: A 'Physics.Cast()' returned an invalid hit distance of '" + hitInfo.distance + "'. The drawn cast visualization may be incorrect."); + return 1.0f; + } + else + { + return hitInfo.distance; + } + } + else + { + return 0.0f; + } + } + + static float GetDistanceOfFarestHit(RaycastHit[] hitInfos, int numberOfUsedSlotsInHitInfoArray) + { + float farestDistance = 0.0f; + if (hitInfos != null) + { + numberOfUsedSlotsInHitInfoArray = Mathf.Min(numberOfUsedSlotsInHitInfoArray, hitInfos.Length); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + if (UtilitiesDXXL_Math.FloatIsInvalid(hitInfos[i].distance)) + { + Debug.LogError("Draw XXL: A 'Physics.Cast()' returned an invalid hit distance of '" + hitInfos[i].distance + "'. The drawn cast visualization may be incorrect."); + } + else + { + farestDistance = Mathf.Max(farestDistance, hitInfos[i].distance); + } + } + } + return farestDistance; + } + + public static void DrawCheckedBox(bool doesOverlap, Vector3 center, Vector3 halfExtents, Quaternion orientation, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(halfExtents, "halfExtents")) { return; } + + Color color = doesOverlap ? DrawPhysics.colorForHittingCasts : DrawPhysics.colorForNonHittingCasts; + Color color_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.3f); + bool atLeastOneBoxDimIsNegative = UtilitiesDXXL_Math.ContainsNegativeComponents(halfExtents); + Vector3 boxSize = 2.0f * halfExtents; //Note: inconsistent naming inside Unity: Here: "halfExtents" = "halfSize", while in "Bounds": "extents" = "halfSize" + + string text = null; + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string additinalWarningText = atLeastOneBoxDimIsNegative ? "[ box contains negative dimensions -> invalid results and/or box must be inside other colliders]
" : null; + text = additinalWarningText + GetTextForVolumeCheck("Box: Check collider intersections
Result: ", doesOverlap, nameTag); + } + + UtilitiesDXXL_Shapes.Set_bothForcedConstantTextSizes_forTextAtShapes_reversible(DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts, DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts); + + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + DrawShapes.CubeFilled(center, boxSize, color_lowAlpha, orientation, 0.0f, 4, text, DrawBasics.LineStyle.solid, color, 0.0f, 1.0f, true, true, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + DrawShapes.CubeFilled(center, boxSize, color_lowAlpha, orientation, 0.0f, 4, text, DrawBasics.LineStyle.solid, color, 0.0f, 1.0f, true, true, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + DrawShapes.Cube(center, boxSize, color_lowAlpha, orientation, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + break; + default: + break; + } + + UtilitiesDXXL_Shapes.Reverse_disable_bothForcedConstantTextSizes_forTextAtShapes(); + } + + public static void DrawCheckedCapsule(bool doesOverlap, Vector3 start, Vector3 end, float radius, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return; } + + Color color = doesOverlap ? DrawPhysics.colorForHittingCasts : DrawPhysics.colorForNonHittingCasts; + + string text = null; + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string additinalWarningText = (radius < 0.0f) ? "[ negative capsule radius -> invalid results and/or capsule must be inside other colliders]
" : null; + text = additinalWarningText + GetTextForVolumeCheck("Capsule: Check collider intersections
Result: ", doesOverlap, nameTag); + } + + if (Mathf.Abs(radius) < 0.0001f && UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(start, end)) + { + DrawBasics.PointTag(start, text, color, 0.0f, 1.0f, default(Vector3), 1.0f, false, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Shapes.Set_bothForcedConstantTextSizes_forTextAtShapes_reversible(DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts, DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts); + + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(64); + DrawShapes.Capsule(start, end, radius, color, default(Vector3), 0.0f, text, strutsPerCastCapsule, false, DrawBasics.LineStyle.solid, 1.0f, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(32); + DrawShapes.Capsule(start, end, radius, color, default(Vector3), 0.0f, text, 4, false, DrawBasics.LineStyle.solid, 1.0f, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(16); + DrawShapes.Capsule(start, end, radius, color, default(Vector3), 0.0f, text, 2, false, DrawBasics.LineStyle.solid, 1.0f, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + default: + break; + } + + UtilitiesDXXL_Shapes.Reverse_disable_bothForcedConstantTextSizes_forTextAtShapes(); + } + } + + public static void DrawCheckedSphere(bool doesOverlap, Vector3 position, float radius, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + Color color = doesOverlap ? DrawPhysics.colorForHittingCasts : DrawPhysics.colorForNonHittingCasts; + + string text = null; + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string additinalWarningText = (radius < 0.0f) ? "[ negative sphere radius -> invalid results and/or sphere must be inside other colliders]
" : null; + text = additinalWarningText + GetTextForVolumeCheck("Sphere: Check collider intersections
Result: ", doesOverlap, nameTag); + } + + if (Mathf.Abs(radius) < 0.0001f) + { + DrawBasics.PointTag(position, text, color, 0.0f, 1.0f, default(Vector3), 1.0f, false, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Shapes.Set_bothForcedConstantTextSizes_forTextAtShapes_reversible(DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts, DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts); + + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(64); + DrawShapes.Sphere(position, radius, color, Vector3.up, Vector3.forward, 0.0f, text, strutsPerCastSphere, false, DrawBasics.LineStyle.solid, 1.0f, false, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(32); + DrawShapes.Sphere(position, radius, color, Vector3.up, Vector3.forward, 0.0f, text, 4, false, DrawBasics.LineStyle.solid, 1.0f, false, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(16); + DrawShapes.Sphere(position, radius, color, Vector3.up, Vector3.forward, 0.0f, text, 2, false, DrawBasics.LineStyle.solid, 1.0f, false, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + default: + break; + } + + UtilitiesDXXL_Shapes.Reverse_disable_bothForcedConstantTextSizes_forTextAtShapes(); + } + } + + static string GetTextForVolumeCheck(string volumeTypeIdentifyingStringPart, bool doesOverlap, string nameTag) + { + if (nameTag != null && nameTag.Length != 0) + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + return nameTag; + } + else + { + return (nameTag + "
Result: " + (doesOverlap ? "Is overlapping with at least one collider" : "Is not overlapping with any collider")); + } + } + else + { + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + return null; + } + else + { + return (volumeTypeIdentifyingStringPart + (doesOverlap ? "Is overlapping with at least one collider" : "Is not overlapping with any collider")); + } + } + } + + public static void DrawOverlapResultBox(bool doesOverlap, int numberOfOverlappingColliders, Collider[] overlappingColliders, Vector3 center, Vector3 halfExtents, Quaternion orientation, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + Color color = doesOverlap ? DrawPhysics.colorForHittingCasts : DrawPhysics.colorForNonHittingCasts; + Color color_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.3f); + bool atLeastOneBoxDimIsNegative = UtilitiesDXXL_Math.ContainsNegativeComponents(halfExtents); + Vector3 boxSize = 2.0f * halfExtents; //Note: inconsistent naming inside Unity: Here: "halfExtents" = "halfSize", while in "Bounds": "extents" = "halfSize" + + string text = null; + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string additinalWarningText = atLeastOneBoxDimIsNegative ? "[ box contains negative dimensions -> invalid results and/or box must be inside other colliders]
" : null; + string overlappingCollidersListAsText = GetOverlappingCollidersListAsText(overlappingColliders, numberOfOverlappingColliders); + text = additinalWarningText + GetTextForVolumeOverlapCheck("Box: Overlap check", doesOverlap, numberOfOverlappingColliders, nameTag, overlappingCollidersListAsText); + } + + UtilitiesDXXL_Shapes.Set_bothForcedConstantTextSizes_forTextAtShapes_reversible(DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts, DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts); + + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + DrawShapes.CubeFilled(center, boxSize, color_lowAlpha, orientation, 0.0f, 4, text, DrawBasics.LineStyle.solid, color, 0.0f, 1.0f, true, true, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + DrawShapes.CubeFilled(center, boxSize, color_lowAlpha, orientation, 0.0f, 4, text, DrawBasics.LineStyle.solid, color, 0.0f, 1.0f, true, true, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + DrawShapes.Cube(center, boxSize, color_lowAlpha, orientation, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + break; + default: + break; + } + + UtilitiesDXXL_Shapes.Reverse_disable_bothForcedConstantTextSizes_forTextAtShapes(); + } + + public static void DrawOverlapResultCapsule(bool doesOverlap, int numberOfOverlappingColliders, Collider[] overlappingColliders, Vector3 point0, Vector3 point1, float radius, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + Color color = doesOverlap ? DrawPhysics.colorForHittingCasts : DrawPhysics.colorForNonHittingCasts; + + string text = null; + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string additinalWarningText = (radius < 0.0f) ? "[ negative capsule radius -> invalid results and/or capsule must be inside other colliders]
" : null; + string overlappingCollidersListAsText = GetOverlappingCollidersListAsText(overlappingColliders, numberOfOverlappingColliders); + text = additinalWarningText + GetTextForVolumeOverlapCheck("Capsule: Overlap check", doesOverlap, numberOfOverlappingColliders, nameTag, overlappingCollidersListAsText); + } + + if (Mathf.Abs(radius) < 0.0001f && UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(point0, point1)) + { + DrawBasics.PointTag(point0, text, color, 0.0f, 1.0f, default(Vector3), 1.0f, false, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Shapes.Set_bothForcedConstantTextSizes_forTextAtShapes_reversible(DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts, DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts); + + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(64); + DrawShapes.Capsule(point0, point1, radius, color, default(Vector3), 0.0f, text, strutsPerCastCapsule, false, DrawBasics.LineStyle.solid, 1.0f, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(32); + DrawShapes.Capsule(point0, point1, radius, color, default(Vector3), 0.0f, text, 4, false, DrawBasics.LineStyle.solid, 1.0f, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(16); + DrawShapes.Capsule(point0, point1, radius, color, default(Vector3), 0.0f, text, 2, false, DrawBasics.LineStyle.solid, 1.0f, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + default: + break; + } + + UtilitiesDXXL_Shapes.Reverse_disable_bothForcedConstantTextSizes_forTextAtShapes(); + } + } + + public static void DrawOverlapResultSphere(bool doesOverlap, int numberOfOverlappingColliders, Collider[] overlappingColliders, Vector3 position, float radius, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + Color color = doesOverlap ? DrawPhysics.colorForHittingCasts : DrawPhysics.colorForNonHittingCasts; + + string text = null; + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string additinalWarningText = (radius < 0.0f) ? "[ negative sphere radius -> invalid results and/or sphere must be inside other colliders]
" : null; + string overlappingCollidersListAsText = GetOverlappingCollidersListAsText(overlappingColliders, numberOfOverlappingColliders); + text = additinalWarningText + GetTextForVolumeOverlapCheck("Sphere: Overlap check", doesOverlap, numberOfOverlappingColliders, nameTag, overlappingCollidersListAsText); + } + + if (Mathf.Abs(radius) < 0.0001f) + { + DrawBasics.PointTag(position, text, color, 0.0f, 1.0f, default(Vector3), 1.0f, false, durationInSec, hiddenByNearerObjects); + } + else + { + UtilitiesDXXL_Shapes.Set_bothForcedConstantTextSizes_forTextAtShapes_reversible(DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts, DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts); + + switch (DrawPhysics.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(64); + DrawShapes.Sphere(position, radius, color, Vector3.up, Vector3.forward, 0.0f, text, strutsPerCastSphere, false, DrawBasics.LineStyle.solid, 1.0f, false, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(32); + DrawShapes.Sphere(position, radius, color, Vector3.up, Vector3.forward, 0.0f, text, 4, false, DrawBasics.LineStyle.solid, 1.0f, false, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + UtilitiesDXXL_Shapes.Set_linesPerSphereCircle_reversible(16); + DrawShapes.Sphere(position, radius, color, Vector3.up, Vector3.forward, 0.0f, text, 2, false, DrawBasics.LineStyle.solid, 1.0f, false, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_linesPerSphereCircle(); + break; + default: + break; + } + + UtilitiesDXXL_Shapes.Reverse_disable_bothForcedConstantTextSizes_forTextAtShapes(); + } + } + + static string GetOverlappingCollidersListAsText(Collider[] overlappingColliders, int numberOfOverlappingColliders) + { + if (overlappingColliders == null) + { + return null; + } + else + { + if (overlappingColliders.Length == 0) + { + return null; + } + else + { + if (numberOfOverlappingColliders <= 0) + { + return null; + } + else + { + string collidersList = null; + for (int i = 0; i < numberOfOverlappingColliders; i++) + { + if (i < DrawPhysics.MaxListedColliders_inOverlapVolumesTextList) + { + //collidersList = overlappingColliders[i].GetType().ToString() + " (on GameObject '" + overlappingColliders[i].gameObject.name + "')
" + collidersList; //-> first found collider is on bottom. This contradicts the "DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes"-hitPos-display, which only displays the index-number + collidersList = collidersList + "
" + overlappingColliders[i].GetType().ToString() + " (on GameObject '" + overlappingColliders[i].gameObject.name + "')"; //-> first found collider is on top. This corresponds to the "DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes"-hitPos-display, which only, which only displays the index-number + } + else + { + collidersList = collidersList + "
...and " + (numberOfOverlappingColliders - DrawPhysics.MaxListedColliders_inOverlapVolumesTextList) + " more."; + break; + } + } + return collidersList; + } + } + } + } + + static string GetTextForVolumeOverlapCheck(string volumeTypeIdentifyingStringPart, bool doesOverlap, int numberOfOverlappingColliders, string nameTag, string overlappingCollidersListAsText) + { + if (nameTag != null && nameTag.Length != 0) + { + //has user specified "nameTag": + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + if (doesOverlap) + { + return (nameTag + "
Overlapping with these " + numberOfOverlappingColliders + " collider(s):
" + overlappingCollidersListAsText); + } + else + { + return nameTag; + } + } + else + { + if (doesOverlap) + { + return (nameTag + "
Overlapping with these " + numberOfOverlappingColliders + " collider(s):
" + overlappingCollidersListAsText); + } + else + { + return (nameTag + "
Result: Is not overlapping with any collider"); + } + } + } + else + { + //has NO user specified "nameTag": + if (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + if (doesOverlap) + { + return ("Overlapping with these " + numberOfOverlappingColliders + " collider(s):
" + overlappingCollidersListAsText); + } + else + { + return null; + } + } + else + { + if (doesOverlap) + { + return (volumeTypeIdentifyingStringPart + "
Overlapping with these " + numberOfOverlappingColliders + " collider(s):
" + overlappingCollidersListAsText); + } + else + { + return (volumeTypeIdentifyingStringPart + "
Result: Is not overlapping with any collider"); + } + } + } + } + + public static void DrawMarkersAtOverlappingColliders(Vector3 volumeCenter, bool doesOverlap, Collider[] overlappingColliders, int numberOfOverlappingColliders, float approxSize_ofOverlapVolume, float durationInSec, bool hiddenByNearerObjects) + { + if (doesOverlap) + { + Color color_ofMarkers = (DrawPhysics.colorForHittingCasts.grayscale < 0.175f) ? Color.Lerp(DrawPhysics.colorForHittingCasts, Color.white, 0.7f) : Color.Lerp(DrawPhysics.colorForHittingCasts, Color.black, 0.7f); + Color color_ofMarkerExtentionLinesToShapeCenter = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawPhysics.colorForHittingCasts, 0.1f); + float relTextSizeScaling = 1.0f; + float textOffsetDistance = 1.0f; + float sizeOfMarkingCross = Mathf.Max(0.1f * approxSize_ofOverlapVolume, 0.001f); + numberOfOverlappingColliders = Mathf.Min(numberOfOverlappingColliders, overlappingColliders.Length); + for (int i = 0; i < numberOfOverlappingColliders; i++) + { + Vector3 nearestPosOnCollider = overlappingColliders[i].ClosestPoint(volumeCenter); + Line_fadeableAnimSpeed.InternalDraw(volumeCenter, nearestPosOnCollider, color_ofMarkerExtentionLinesToShapeCenter, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + bool drawCoordsAsText = (DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.high_withFullDetails); + DrawBasics.Point(nearestPosOnCollider, DrawPhysics.colorForHittingCasts, sizeOfMarkingCross, default(Quaternion), 0.0f, null, DrawPhysics.colorForHittingCasts, false, drawCoordsAsText, false, durationInSec, hiddenByNearerObjects); + + if (DrawPhysics.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string text; + if ((DrawPhysics.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) || (i >= DrawPhysics.maxOverlapingCollidersWithUntruncatedText)) + { + text = "" + i; + } + else + { + text = overlappingColliders[i].GetType().ToString() + " (on GameObject '" + overlappingColliders[i].gameObject.name + "')"; + } + Vector3 textOffsetDir = nearestPosOnCollider - volumeCenter; + DrawBasics.PointTag(nearestPosOnCollider, text, color_ofMarkers, 0.0f, textOffsetDistance, textOffsetDir, relTextSizeScaling, true, durationInSec, hiddenByNearerObjects); + } + } + } + } + + public static bool ExtentNameTagForNonSuitingResultArray(ref string nameTag, int numberOfUsedSlotsInHitInfoArray, RaycastHit[] resultsArray) + { + bool resultsArrayIsNull = (resultsArray == null); + ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoArray, resultsArrayIsNull, resultsArrayIsNull ? 0 : resultsArray.Length); + return resultsArrayIsNull; + } + + public static bool ExtentNameTagForNonSuitingResultArray(ref string nameTag, int numberOfOverlappingColliders, Collider[] resultsArray) + { + bool resultsArrayIsNull = (resultsArray == null); + ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, resultsArrayIsNull, resultsArrayIsNull ? 0 : resultsArray.Length); + return resultsArrayIsNull; + } + + public static void ExtentNameTagForNonSuitingResultArray(ref string nameTag, int numberOfUsedSlotsInResultsArray, bool resultsArrayIsNull, int length_ofResultsArray) + { + if (resultsArrayIsNull) + { + nameTag = "[ results buffer array is null]
" + nameTag; + } + else + { + if (length_ofResultsArray == 0) + { + nameTag = "[ results buffer array has 0 slots -> no ray results possible]
" + nameTag; + } + else + { + if (numberOfUsedSlotsInResultsArray >= length_ofResultsArray) + { + //note: the "int numberOfCollisions" return value of Unitys physics cast is already limited to "resultsArray.Length" -> no outOfBounds-Checks necessary + nameTag = "[ results buffer array has all " + length_ofResultsArray + " slots filled -> further results potentially missing]
" + nameTag; + } + } + } + } + + public static void ExtentNameTagForNonSuitingResultList(ref string nameTag, bool resultsListIsNull, int numberOfUsedSlotsInList) + { + if (resultsListIsNull) + { + nameTag = "[ results buffer list is null]
" + nameTag; + } + else + { + if (numberOfUsedSlotsInList > DrawPhysics2D.MaxNumberOfPreallocatedHits) + { + nameTag = "[ Only " + DrawPhysics2D.MaxNumberOfPreallocatedHits + " of the " + numberOfUsedSlotsInList + " hit results are displayed
-> Increase 'DrawXXL.DrawPhysics2D.MaxNumberOfPreallocatedHits' to see all hits]
" + nameTag; + } + } + } + + public static string GetSizeMarkupStartStringForCastNames(string nameText) + { + if (nameText.Length < 25) + { + return ""; + } + else + { + //additionalWarningMessages get encoded into the "nameText", which would lead to very big text walls, if the would be magnified to "27" + return ""; + } + } + + public static string GetStrokeWidthMarkupStartStringForHitPosDesctiptionHeaders(string nameText) + { + if (nameText.Length < 25) + { + return ""; + } + else + { + //additionalWarningMessages get encoded into the "nameText", which would lead to many strokeWidth duplicate lines, if a stroke width of non-0 would be used. + return ""; + } + } + + static float scaleFactor_forCastHitTextSize_before; + public static void Set_scaleFactor_forCastHitTextSize_reversible(float new_scaleFactor_forCastHitTextSize) + { + scaleFactor_forCastHitTextSize_before = DrawPhysics.scaleFactor_forCastHitTextSize; + DrawPhysics.scaleFactor_forCastHitTextSize = new_scaleFactor_forCastHitTextSize; + } + public static void Reverse_scaleFactor_forCastHitTextSize() + { + DrawPhysics.scaleFactor_forCastHitTextSize = scaleFactor_forCastHitTextSize_before; + } + + static float castSilhouetteVisualizerDensity_before; + public static void Set_castSilhouetteVisualizerDensity_reversible(float new_castSilhouetteVisualizerDensity) + { + castSilhouetteVisualizerDensity_before = DrawPhysics.castSilhouetteVisualizerDensity; + DrawPhysics.castSilhouetteVisualizerDensity = new_castSilhouetteVisualizerDensity; + } + public static void Reverse_castSilhouetteVisualizerDensity() + { + DrawPhysics.castSilhouetteVisualizerDensity = castSilhouetteVisualizerDensity_before; + } + + static DrawPhysics.VisualizationQuality visualizationQuality_before; + public static void Set_visualizationQuality_reversible(DrawPhysics.VisualizationQuality new_visualizationQuality) + { + visualizationQuality_before = DrawPhysics.visualizationQuality; + DrawPhysics.visualizationQuality = new_visualizationQuality; + } + public static void Reverse_visualizationQuality() + { + DrawPhysics.visualizationQuality = visualizationQuality_before; + } + + static float forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before; + public static void Set_forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_reversible(float new_forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts) + { + forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before = DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts; + DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = new_forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts; + } + public static void Reverse_forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts() + { + DrawPhysics.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before; + } + + static float forcedConstantWorldspaceTextSize_forOverlapResultTexts_before; + public static void Set_forcedConstantWorldspaceTextSize_forOverlapResultTexts_reversible(float new_forcedConstantWorldspaceTextSize_forOverlapResultTexts) + { + forcedConstantWorldspaceTextSize_forOverlapResultTexts_before = DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts; + DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts = new_forcedConstantWorldspaceTextSize_forOverlapResultTexts; + } + public static void Reverse_forcedConstantWorldspaceTextSize_forOverlapResultTexts() + { + DrawPhysics.forcedConstantWorldspaceTextSize_forOverlapResultTexts = forcedConstantWorldspaceTextSize_forOverlapResultTexts_before; + } + + static Vector2 directionOfHitResultText_before; + public static void Set_directionOfHitResultText_reversible(Vector2 new_directionOfHitResultText) + { + directionOfHitResultText_before = DrawPhysics.directionOfHitResultText; + DrawPhysics.directionOfHitResultText = new_directionOfHitResultText; + } + public static void Reverse_directionOfHitResultText() + { + DrawPhysics.directionOfHitResultText = directionOfHitResultText_before; + } + + static Vector3 default_textOffsetDirection_forPointTags_before; + public static void TrySet_default_textOffsetDirection_forPointTags_reversible() + { + if (UtilitiesDXXL_Math.IsDefaultVector(DrawPhysics.directionOfHitResultText) == false) + { + default_textOffsetDirection_forPointTags_before = DrawBasics.Default_textOffsetDirection_forPointTags; + DrawBasics.Default_textOffsetDirection_forPointTags = new Vector3(DrawPhysics.directionOfHitResultText.x, DrawPhysics.directionOfHitResultText.y, 0.0f); + } + } + public static void TryReverse_default_textOffsetDirection_forPointTags() + { + if (UtilitiesDXXL_Math.IsDefaultVector(DrawPhysics.directionOfHitResultText) == false) + { + DrawBasics.Default_textOffsetDirection_forPointTags = default_textOffsetDirection_forPointTags_before; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics.cs.meta new file mode 100644 index 0000000..e15e879 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b6cdf44fa4a2824888d1b64e8fbc915 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics2D.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics2D.cs new file mode 100644 index 0000000..d848c93 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics2D.cs @@ -0,0 +1,1815 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_Physics2D + { + public static RaycastHit2D[] preallocatedRayHit2DResultsArray_copiedFromList = new RaycastHit2D[DrawPhysics2D.MaxNumberOfPreallocatedHits]; + public static Collider2D[] preallocatedCollider2DResultsArray_copiedFromList = new Collider2D[DrawPhysics2D.MaxNumberOfPreallocatedHits]; + + public static void DrawRaycastTillFirstHit(bool hasHit, Vector2 originV2, Vector2 directionV2, float maxDistance, RaycastHit2D hitInfo2D, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(directionV2)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(originV2, GetZPosForDrawVisualisation(), "[ DrawRaycast2D with direction of zero]
" + nameText, DrawPhysics2D.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + float distanceOfFarestHit = GetDistanceOfSingleHit(hasHit, hitInfo2D); + DrawRayOfRaycast(hasHit ? 1 : 0, originV2, directionV2, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + if (hasHit) + { + DrawRaycastHitInfo(hitInfo2D, 0, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawRaycastPotMultipleHits(Vector2 originV2, Vector2 directionV2, float maxDistance, RaycastHit2D[] hitInfos2D, int numberOfUsedSlotsInHitInfoArray, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(directionV2)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(originV2, GetZPosForDrawVisualisation(), "[ DrawRaycast2D with direction of zero]
" + nameText, DrawPhysics2D.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + float distanceOfFarestHit = GetDistanceOfFarestHit(hitInfos2D, numberOfUsedSlotsInHitInfoArray); + DrawRayOfRaycast(numberOfUsedSlotsInHitInfoArray, originV2, directionV2, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + DrawRaycastHitInfo(hitInfos2D[i], i, nameText, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawRayOfRaycast(int hitCount, Vector2 originV2, Vector2 directionV2, float maxDistance, string nameText, float distanceOfFarestHit, float durationInSec, bool hiddenByNearerObjects) + { + bool hasHit = hitCount > 0; + Color color = hasHit ? DrawPhysics2D.colorForHittingCasts : DrawPhysics2D.colorForNonHittingCasts; + Vector3 direction_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(new Vector3(directionV2.x, directionV2.y, 0.0f)); + bool hasUnlimitedLength = float.IsInfinity(maxDistance); + float absMaxDistance = Mathf.Abs(maxDistance); + float lengthOfRayDirIndicator = Mathf.Min(1.0f, 0.9f * absMaxDistance); + maxDistance = Mathf.Min(maxDistance, 100000.0f); + maxDistance = Mathf.Max(maxDistance, -100000.0f); + Vector3 origin = new Vector3(originV2.x, originV2.y, GetZPosForDrawVisualisation()); + Vector3 endPos = origin + direction_normalized * maxDistance; + Line_fadeableAnimSpeed.InternalDraw(origin, endPos, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //at origin: + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + float width_ofBase = 0.1f * lengthOfRayDirIndicator; + DrawShapes.Pyramid(origin, lengthOfRayDirIndicator, 0.0f, width_ofBase, color, direction_normalized, Vector3.up, DrawShapes.Shape2DType.square, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + else + { + string rayText = GetRayText(nameText, hitCount, maxDistance, "Raycast 2D

number of hits: "); + DrawEngineBasics.RayLineExtended2D(origin, direction_normalized * lengthOfRayDirIndicator, color, 0.0f, rayText, GetZPosForDrawVisualisation(), 0.0f, false, 0.01f, 0.0f, durationInSec, hiddenByNearerObjects); + } + + //overdraw line after last hit: + if (hasHit) + { + if (maxDistance < 0.0f) + { + //unity.RaycastHit2D always returns positve values for "distance", also if the cast goes backward due to negative "maxDistance" + distanceOfFarestHit = -distanceOfFarestHit; + } + Line_fadeableAnimSpeed.InternalDraw(origin + direction_normalized * distanceOfFarestHit, endPos, DrawPhysics2D.colorForCastLineBeyondHit, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + //end cap: + if (hasUnlimitedLength == false) + { + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + DrawShapes.Decagon(endPos, 0.025f, hasHit ? DrawPhysics2D.colorForCastLineBeyondHit : DrawPhysics2D.colorForNonHittingCasts, direction_normalized, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + } + } + + static void DrawRaycastHitInfo(RaycastHit2D hitInfo2D, int i_hit, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.point) || UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.normal)) + { + Debug.LogError("Draw XXL: A 'Physics2D.RayCast()' returned an invalid hit position (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + ") or normal (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.normal) + "). The drawn cast visualization may be incorrect."); + } + else + { + bool saveDrawnLines = i_hit >= DrawPhysics2D.hitResultsWithMoreDetailedDisplay; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.high_withFullDetails) { saveDrawnLines = true; } + + Vector3 impactPos_v3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(hitInfo2D.point, hitInfo2D.transform.position.z); + + //dashed connection line along z: + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(hitInfo2D.transform.position.z, GetZPosForDrawVisualisation()) == false) + { + float absZDistance = Mathf.Abs(hitInfo2D.transform.position.z - GetZPosForDrawVisualisation()); + Vector3 impactPos_projectedOntoDrawVisualisation_V3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(hitInfo2D.point, GetZPosForDrawVisualisation()); + Color color_forDashedLineAlongZ = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawPhysics2D.colorForHittingCasts, 0.6f); + DrawBasics.LineStyle lineStyleAlongZ = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) ? DrawBasics.LineStyle.solid : DrawBasics.LineStyle.dashedLong; + Line_fadeableAnimSpeed.InternalDraw(impactPos_v3, impactPos_projectedOntoDrawVisualisation_V3, color_forDashedLineAlongZ, 0.0f, null, lineStyleAlongZ, absZDistance, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + //Normal: + Vector3 normal_V3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(hitInfo2D.normal); + Color color_ofNormal = Get_color_ofNormal(); + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + DrawBasics2D.LineFrom(impactPos_v3, normal_V3, color_ofNormal, 0.0f, null, DrawBasics.LineStyle.solid, hitInfo2D.transform.position.z, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + float relConeLength_ofNormalVector = 0.17f; + string normalText = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? null : (saveDrawnLines ? "normal" : "normal
of hit surface"); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics2D.VectorFrom(impactPos_v3, normal_V3, color_ofNormal, saveDrawnLines ? 0.0f : 0.006f, normalText, relConeLength_ofNormalVector, false, hitInfo2D.transform.position.z, false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + + //Normal Socket and Text Description: + switch (DrawPhysics2D.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + DrawNormalSocketAndText_highQuality(impactPos_v3, normal_V3, color_ofNormal, hitInfo2D, i_hit, nameText, saveDrawnLines, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + DrawNormalSocketAndText_mediumQuality(impactPos_v3, normal_V3, color_ofNormal, nameText, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + //normal socket: + DrawShapes.Square(impactPos_v3, 0.12f, color_ofNormal, normal_V3, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + break; + default: + break; + } + } + } + + static void DrawNormalSocketAndText_highQuality(Vector3 impactPos_v3, Vector3 normal_V3, Color color_ofNormal, RaycastHit2D hitInfo2D, int i_hit, string nameText, bool saveDrawnLines, float durationInSec, bool hiddenByNearerObjects) + { + //normal socket: + DrawShapes.Decagon(impactPos_v3, 0.03f, color_ofNormal, normal_V3, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + //text description: + float textOffsetDistance = DrawPhysics2D.scaleFactor_forCastHitTextSize; + string text; + if (DrawPhysics2D.drawCastNameTag_atHitPositions && nameText != null && nameText.Length != 0) + { + text = (saveDrawnLines ? (nameText + " / #" + i_hit + ":
hit GO: " + hitInfo2D.transform.gameObject.name + "
pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
dist = " + hitInfo2D.distance) : (UtilitiesDXXL_Physics.GetStrokeWidthMarkupStartStringForHitPosDesctiptionHeaders(nameText) + nameText + " / hit #" + i_hit + ":
GameObject that was hit: " + hitInfo2D.transform.gameObject.name + "
position = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
distance = " + hitInfo2D.distance)); + } + else + { + text = (saveDrawnLines ? ("hit #" + i_hit + ":
hit GO: " + hitInfo2D.transform.gameObject.name + "
pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
dist = " + hitInfo2D.distance) : ("Raycast2D hit #" + i_hit + ":
GameObject that was hit: " + hitInfo2D.transform.gameObject.name + "
position = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
distance = " + hitInfo2D.distance)); + } + + TrySet_default_textOffsetDirection_forPointTags_reversible(); + DrawBasics2D.PointTag(hitInfo2D.point, text, DrawPhysics2D.colorForCastsHitText, 0.0f, textOffsetDistance, default(Vector2), hitInfo2D.transform.position.z, 1.0f, false, durationInSec, hiddenByNearerObjects); + TryReverse_default_textOffsetDirection_forPointTags(); + } + + static void DrawNormalSocketAndText_mediumQuality(Vector3 impactPos_v3, Vector3 normal_V3, Color color_ofNormal, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + //normal socket: + DrawShapes.Decagon(impactPos_v3, 0.03f, color_ofNormal, normal_V3, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + //text description: + if (DrawPhysics2D.drawCastNameTag_atHitPositions && nameText != null && nameText.Length != 0) + { + UtilitiesDXXL_Text.Write(nameText, impactPos_v3, DrawPhysics2D.colorForCastsHitText, 0.1f * DrawPhysics2D.scaleFactor_forCastHitTextSize, Vector3.right, Vector3.up, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + + public static void DrawRaycast3DTillFirstHit(bool hasHit, Ray ray, float maxDistance, RaycastHit2D hitInfo2D, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(ray.direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(ray.origin, "[ DrawRay3D against 2D colliders with direction of zero]
" + nameText, DrawPhysics2D.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + float distanceOfFarestHit = GetDistanceOfSingleHit(hasHit, hitInfo2D); + DrawRayOfRaycast3D(hasHit ? 1 : 0, ray, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + if (hasHit) + { + DrawRaycast3DHitInfo(hitInfo2D, 0, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawRaycast3DPotMultipleHits(Ray ray, float maxDistance, RaycastHit2D[] hitInfos2D, int numberOfUsedSlotsInHitInfoArray, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(ray.direction)) + { + UtilitiesDXXL_DrawBasics.PointFallback(ray.origin, "[ DrawRay3D against 2D colliders with direction of zero]
" + nameText, DrawPhysics2D.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + float distanceOfFarestHit = GetDistanceOfFarestHit(hitInfos2D, numberOfUsedSlotsInHitInfoArray); + DrawRayOfRaycast3D(numberOfUsedSlotsInHitInfoArray, ray, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + DrawRaycast3DHitInfo(hitInfos2D[i], i, nameText, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawRayOfRaycast3D(int hitCount, Ray ray, float maxDistance, string nameText, float distanceOfFarestHit, float durationInSec, bool hiddenByNearerObjects) + { + bool hasHit = hitCount > 0; + Color color = hasHit ? DrawPhysics2D.colorForHittingCasts : DrawPhysics2D.colorForNonHittingCasts; + Vector3 direction_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(ray.direction); + bool hasUnlimitedLength = float.IsInfinity(maxDistance); + float absMaxDistance = Mathf.Abs(maxDistance); + float lengthOfRayDirIndicator = Mathf.Min(1.0f, 0.9f * absMaxDistance); + maxDistance = Mathf.Min(maxDistance, 100000.0f); + maxDistance = Mathf.Max(maxDistance, -100000.0f); + Vector3 endPos = ray.origin + direction_normalized * maxDistance; + Line_fadeableAnimSpeed.InternalDraw(ray.origin, endPos, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //at origin: + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + float width_ofBase = 0.1f * lengthOfRayDirIndicator; + DrawShapes.Pyramid(ray.origin, lengthOfRayDirIndicator, width_ofBase, width_ofBase, color, direction_normalized, Vector3.up, DrawShapes.Shape2DType.square, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + else + { + string rayText = GetRayText(nameText, hitCount, maxDistance, "Ray3D against
2D colliders

number of hits: "); + DrawEngineBasics.RayLineExtended(ray.origin, direction_normalized * lengthOfRayDirIndicator, color, 0.0f, rayText, 0.0f, false, 0.01f, 0.0f, durationInSec, hiddenByNearerObjects); + } + + //overdraw line after last hit: + if (hasHit) + { + if (maxDistance < 0.0f) + { + //unity.RaycastHit2D always returns positve values for "distance", also if the cast goes backward due to negative "maxDistance" + distanceOfFarestHit = -distanceOfFarestHit; + } + Line_fadeableAnimSpeed.InternalDraw(ray.origin + direction_normalized * distanceOfFarestHit, endPos, DrawPhysics2D.colorForCastLineBeyondHit, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + //end cap: + if (hasUnlimitedLength == false) + { + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + DrawShapes.Decagon(endPos, 0.025f, hasHit ? DrawPhysics2D.colorForCastLineBeyondHit : DrawPhysics2D.colorForNonHittingCasts, direction_normalized, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + } + } + + static string GetRayText(string nameText, int hitCount, float maxDistance, string fallbackTextFragment_forNoSpecifiedName) + { + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + return null; + } + else + { + string rayText; + if (DrawPhysics2D.drawCastNameTag_atCastOrigin && nameText != null && nameText.Length != 0) + { + rayText = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? UtilitiesDXXL_Physics.GetSizeMarkupStartStringForCastNames(nameText) + nameText + "

hits: " + hitCount : UtilitiesDXXL_Physics.GetSizeMarkupStartStringForCastNames(nameText) + nameText + "

number of hits: " + hitCount; + } + else + { + rayText = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? "hits: " + hitCount : fallbackTextFragment_forNoSpecifiedName + hitCount; + } + + if (maxDistance < 0.0f) + { + rayText = "[ negative ray direction]
" + rayText; + } + return rayText; + } + } + + static void DrawRaycast3DHitInfo(RaycastHit2D hitInfo2D, int i_hit, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.point)) + { + Debug.LogError("Draw XXL: A 'Physics2D.Cast()' returned an invalid hit position (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "). The drawn cast visualization may be incorrect."); + } + else + { + bool saveDrawnLines = i_hit >= DrawPhysics2D.hitResultsWithMoreDetailedDisplay; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.high_withFullDetails) { saveDrawnLines = true; } + + Vector3 impactPos_v3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(hitInfo2D.point, hitInfo2D.transform.position.z); + Color color_ofImpactPosCircle = (DrawPhysics2D.colorForHittingCasts.grayscale < 0.175f) ? Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.white, 0.7f) : Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.black, 0.7f); + switch (DrawPhysics2D.visualizationQuality) + { + case DrawPhysics.VisualizationQuality.high_withFullDetails: + DrawNormalSocketAndText_forRaycast3D_highQuality(hitInfo2D, i_hit, nameText, impactPos_v3, color_ofImpactPosCircle, saveDrawnLines, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes: + DrawNormalSocketAndText_forRaycast3D_mediumQuality(nameText, impactPos_v3, color_ofImpactPosCircle, durationInSec, hiddenByNearerObjects); + break; + case DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes: + DrawShapes.Square(impactPos_v3, 0.03f, color_ofImpactPosCircle, Vector3.forward, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + break; + default: + break; + } + } + } + + static void DrawNormalSocketAndText_forRaycast3D_highQuality(RaycastHit2D hitInfo2D, int i_hit, string nameText, Vector3 impactPos_v3, Color color_ofImpactPosCircle, bool saveDrawnLines, float durationInSec, bool hiddenByNearerObjects) + { + DrawShapes.Decagon(impactPos_v3, 0.03f, color_ofImpactPosCircle, Vector3.forward, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + //text description: + float textOffsetDistance = DrawPhysics2D.scaleFactor_forCastHitTextSize; + string text; + if (DrawPhysics2D.drawCastNameTag_atHitPositions && nameText != null && nameText.Length != 0) + { + text = (saveDrawnLines ? (nameText + " / #" + i_hit + ":
hit GO: " + hitInfo2D.transform.gameObject.name + "
pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
dist = " + hitInfo2D.distance) : (UtilitiesDXXL_Physics.GetStrokeWidthMarkupStartStringForHitPosDesctiptionHeaders(nameText) + nameText + " / hit #" + i_hit + ":
GameObject that was hit: " + hitInfo2D.transform.gameObject.name + "
position = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
distance = " + hitInfo2D.distance)); + } + else + { + text = (saveDrawnLines ? ("hit #" + i_hit + ":
hit GO: " + hitInfo2D.transform.gameObject.name + "
pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
dist = " + hitInfo2D.distance) : ("Ray3D against 2D colliders / hit #" + i_hit + ":
GameObject that was hit: " + hitInfo2D.transform.gameObject.name + "
position = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
distance = " + hitInfo2D.distance)); + } + + TrySet_default_textOffsetDirection_forPointTags_reversible(); + DrawBasics2D.PointTag(hitInfo2D.point, text, DrawPhysics2D.colorForCastsHitText, 0.0f, textOffsetDistance, default(Vector2), hitInfo2D.transform.position.z, 1.0f, false, durationInSec, hiddenByNearerObjects); + TryReverse_default_textOffsetDirection_forPointTags(); + } + + static void DrawNormalSocketAndText_forRaycast3D_mediumQuality(string nameText, Vector3 impactPos_v3, Color color_ofImpactPosCircle, float durationInSec, bool hiddenByNearerObjects) + { + DrawShapes.Decagon(impactPos_v3, 0.03f, color_ofImpactPosCircle, Vector3.forward, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + + //text description: + if (DrawPhysics2D.drawCastNameTag_atHitPositions && nameText != null && nameText.Length != 0) + { + UtilitiesDXXL_Text.Write(nameText, impactPos_v3, DrawPhysics2D.colorForCastsHitText, 0.1f * DrawPhysics2D.scaleFactor_forCastHitTextSize, Vector3.right, Vector3.up, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + } + } + + public static void DrawCirclecastTillFirstHit(float circleRadius, bool hasHit, Vector2 origin_V2, Vector2 direction_V2, float maxDistance, RaycastHit2D hitInfo2D, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction_V2)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(origin_V2, GetZPosForDrawVisualisation(), "[ DrawCircleCast2D with direction of zero]
" + nameText, DrawPhysics2D.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool radiusIsZero = UtilitiesDXXL_Math.ApproximatelyZero(circleRadius); + bool circleRadiusTooSmall = circleRadius < 0.00011f; //Unity returns no hits, if a radius is equal or smaller than "0.0001f" + circleRadius = Mathf.Abs(circleRadius); + float distanceOfFarestHit = GetDistanceOfSingleHit(hasHit, hitInfo2D); + DrawRayOfCirclecast(circleRadius, circleRadiusTooSmall, radiusIsZero, hasHit ? 1 : 0, origin_V2, direction_V2, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + if (hasHit) + { + DrawCirclecastHitInfo(circleRadius, hitInfo2D, 0, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawCirclecastPotMultipleHits(float circleRadius, Vector2 origin_V2, Vector2 direction_V2, float maxDistance, RaycastHit2D[] hitInfos2D, int numberOfUsedSlotsInHitInfoArray, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction_V2)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(origin_V2, GetZPosForDrawVisualisation(), "[ DrawCircleCast2D with direction of zero]
" + nameText, DrawPhysics2D.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool radiusIsZero = UtilitiesDXXL_Math.ApproximatelyZero(circleRadius); + bool circleRadiusTooSmall = circleRadius < 0.00011f; //Unity returns no hits, if a radius is equal or smaller than "0.0001f" + circleRadius = Mathf.Abs(circleRadius); + float distanceOfFarestHit = GetDistanceOfFarestHit(hitInfos2D, numberOfUsedSlotsInHitInfoArray); + DrawRayOfCirclecast(circleRadius, circleRadiusTooSmall, radiusIsZero, numberOfUsedSlotsInHitInfoArray, origin_V2, direction_V2, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + DrawCirclecastHitInfo(circleRadius, hitInfos2D[i], i, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawBoxcastTillFirstHit(bool hasHit, Vector2 origin_V2, Vector2 size_V2, float angleDegCC, Vector2 direction_V2, float maxDistance, RaycastHit2D hitInfo2D, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction_V2)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(origin_V2, GetZPosForDrawVisualisation(), "[ DrawBoxcast2D with direction of zero]
" + nameText, DrawPhysics2D.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool atLeastOneBoxDimIsSmallerThan0d00011 = (size_V2.x < 0.00011f) || (size_V2.y < 0.00011f); //Unity returns no hits, if a box dimension is equal or smaller than "0.0001f" + float distanceOfFarestHit = GetDistanceOfSingleHit(hasHit, hitInfo2D); + DrawRayOfBoxcast(hasHit ? 1 : 0, origin_V2, size_V2, angleDegCC, atLeastOneBoxDimIsSmallerThan0d00011, direction_V2, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + if (hasHit) + { + DrawBoxcastHitInfo(size_V2, angleDegCC, hitInfo2D, 0, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawBoxcastPotMultipleHits(Vector2 origin_V2, Vector2 size_V2, float angleDegCC, Vector2 direction_V2, float maxDistance, RaycastHit2D[] hitInfos2D, int numberOfUsedSlotsInHitInfoArray, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction_V2)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(origin_V2, GetZPosForDrawVisualisation(), "[ DrawBoxcast2D with direction of zero]
" + nameText, DrawPhysics2D.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool atLeastOneBoxDimIsSmallerThan0d00011 = (size_V2.x < 0.00011f) || (size_V2.y < 0.00011f); //Unity returns no hits, if a box dimension is equal or smaller than "0.0001f" + float distanceOfFarestHit = GetDistanceOfFarestHit(hitInfos2D, numberOfUsedSlotsInHitInfoArray); + DrawRayOfBoxcast(numberOfUsedSlotsInHitInfoArray, origin_V2, size_V2, angleDegCC, atLeastOneBoxDimIsSmallerThan0d00011, direction_V2, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + DrawBoxcastHitInfo(size_V2, angleDegCC, hitInfos2D[i], i, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawCapsulecastTillFirstHit(bool hasHit, Vector2 origin_V2, Vector2 size_V2, Vector2 direction_V2, CapsuleDirection2D capsuleDirection, float angleDegCC, float maxDistance, RaycastHit2D hitInfo2D, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction_V2)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(origin_V2, GetZPosForDrawVisualisation(), "[ DrawCapsulecast2D with direction of zero]
" + nameText, DrawPhysics2D.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool atLeastOneBoxDimIsSmallerThan0d00011 = (size_V2.x < 0.00011f) || (size_V2.y < 0.00011f); //Unity returns no hits, if a capsule dimension is equal or smaller than "0.0001f" + float distanceOfFarestHit = GetDistanceOfSingleHit(hasHit, hitInfo2D); + DrawRayOfCapsulecast(origin_V2, size_V2, atLeastOneBoxDimIsSmallerThan0d00011, capsuleDirection, angleDegCC, hasHit ? 1 : 0, direction_V2, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + if (hasHit) + { + DrawCapsulecastHitInfo(size_V2, capsuleDirection, angleDegCC, hitInfo2D, 0, nameText, durationInSec, hiddenByNearerObjects); + } + } + + public static void DrawCapsulecastPotMultipleHits(Vector2 origin_V2, Vector2 size_V2, Vector2 direction_V2, CapsuleDirection2D capsuleDirection, float angleDegCC, float maxDistance, RaycastHit2D[] hitInfos2D, int numberOfUsedSlotsInHitInfoArray, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(direction_V2)) + { + UtilitiesDXXL_DrawBasics2D.PointFallback(origin_V2, GetZPosForDrawVisualisation(), "[ DrawCapsulecast2D with direction of zero]
" + nameText, DrawPhysics2D.colorForNonHittingCasts, 0.0f, durationInSec, hiddenByNearerObjects); + return; + } + + bool atLeastOneBoxDimIsSmallerThan0d00011 = (size_V2.x < 0.00011f) || (size_V2.y < 0.00011f); //Unity returns no hits, if a capsule dimension is equal or smaller than "0.0001f" + float distanceOfFarestHit = GetDistanceOfFarestHit(hitInfos2D, numberOfUsedSlotsInHitInfoArray); + DrawRayOfCapsulecast(origin_V2, size_V2, atLeastOneBoxDimIsSmallerThan0d00011, capsuleDirection, angleDegCC, numberOfUsedSlotsInHitInfoArray, direction_V2, maxDistance, nameText, distanceOfFarestHit, durationInSec, hiddenByNearerObjects); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + DrawCapsulecastHitInfo(size_V2, capsuleDirection, angleDegCC, hitInfos2D[i], i, nameText, durationInSec, hiddenByNearerObjects); + } + } + + static Vector2 volumeCastOutlineVertice1_local; + static Vector2 volumeCastOutlineVertice2_local; + static Vector2 volumeCastOutlineVertice1_projectedIntoPerpToCastDirPlane_local; + static Vector2 volumeCastOutlineVertice2_projectedIntoPerpToCastDirPlane_local; + static float distanceOfOutlineVerticesToOrigin_alongCastsUp; + + static void DrawRayOfCirclecast(float circleRadius, bool circleRadiusTooSmall, bool radiusIsZero, int hitCount, Vector2 origin_V2, Vector2 direction_V2, float maxDistance, string nameText, float distanceOfFarestHit, float durationInSec, bool hiddenByNearerObjects) + { + bool hasHit = hitCount > 0; + Vector2 direction_normalized_V2 = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(direction_V2); + bool hasUnlimitedLength = float.IsInfinity(maxDistance); + maxDistance = Mathf.Min(maxDistance, 100000.0f); + maxDistance = Mathf.Max(maxDistance, -100000.0f); + Vector2 endPos_V2 = origin_V2 + direction_normalized_V2 * maxDistance; + Vector3 castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3 = Vector3.Cross(Vector3.forward, direction_normalized_V2); + + Color color = hasHit ? DrawPhysics2D.colorForHittingCasts : DrawPhysics2D.colorForNonHittingCasts; + Color color_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.5f); + Color color_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.25f); + + Color color_ofCastEnd = hasHit ? DrawPhysics2D.colorForCastLineBeyondHit : DrawPhysics2D.colorForNonHittingCasts; + Color color_ofCastEnd_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.5f); + Color color_ofCastEnd_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.25f); + + if (radiusIsZero == false) + { + FillCircleCastOutlineVertices(direction_normalized_V2, circleRadius); + FillVolumeCastOutlineVertices_projectedIntoPerpToCastDirPlane(direction_V2); + float arrowWidth = circleRadius * 0.5f; + float arrowLength = circleRadius * 1.0f; + float arrowsRelConeLenth = 0.45f; + float circleDiameter = 2.0f * circleRadius; + + DrawCircleAtCastStartAndEnd(origin_V2, endPos_V2, circleRadius, color, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + float startArrows_startDistanceFromStart = circleDiameter; + DrawArrowsAtVolumeCastStartAndEnd(out float distance_ofStartArrowsStartPos, out float distance_ofEndArrowsStartPos, hasHit, origin_V2, direction_normalized_V2, startArrows_startDistanceFromStart, maxDistance, distanceOfFarestHit, arrowLength, color_lowerAlpha, color_ofCastEnd_lowerAlpha, arrowsRelConeLenth, arrowWidth, durationInSec, hiddenByNearerObjects); + + float sizeApproximationOfVolume = circleDiameter; + DrawCascadeOfArrows(distance_ofStartArrowsStartPos, distance_ofEndArrowsStartPos, sizeApproximationOfVolume, hasHit, hasUnlimitedLength, origin_V2, direction_normalized_V2, distanceOfFarestHit, arrowLength, arrowWidth, arrowsRelConeLenth, color_lowerAlpha, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + DrawCascadeOfVolumeSilhouette2Dslices(sizeApproximationOfVolume, hasHit, hasUnlimitedLength, origin_V2, direction_normalized_V2, maxDistance, distanceOfFarestHit, color_lowAlpha, color_ofCastEnd_lowAlpha, durationInSec, hiddenByNearerObjects); + } + else + { + volumeCastOutlineVertice1_local = Vector2.zero; + volumeCastOutlineVertice2_local = Vector2.zero; + } + + DrawVolumeCastDirOutline(hasHit, origin_V2, endPos_V2, direction_normalized_V2, distanceOfFarestHit, maxDistance, color, color_ofCastEnd, durationInSec, hiddenByNearerObjects); + WriteTextAtCircleCastOrigin(origin_V2, direction_normalized_V2, circleRadius, castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3, circleRadiusTooSmall, color, nameText, hitCount, maxDistance, durationInSec, hiddenByNearerObjects); + } + + static void DrawRayOfBoxcast(int hitCount, Vector2 origin_V2, Vector2 boxSize_V2, float angleDegCC, bool atLeastOneBoxDimIsSmallerThan0d00011, Vector2 direction_V2, float maxDistance, string nameText, float distanceOfFarestHit, float durationInSec, bool hiddenByNearerObjects) + { + bool hasHit = hitCount > 0; + Vector2 direction_normalized_V2 = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(direction_V2); + bool hasUnlimitedLength = float.IsInfinity(maxDistance); + maxDistance = Mathf.Min(maxDistance, 100000.0f); + maxDistance = Mathf.Max(maxDistance, -100000.0f); + Vector2 endPos_V2 = origin_V2 + direction_normalized_V2 * maxDistance; + Vector3 castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3 = Vector3.Cross(Vector3.forward, direction_normalized_V2); + + Color color = hasHit ? DrawPhysics2D.colorForHittingCasts : DrawPhysics2D.colorForNonHittingCasts; + Color color_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.5f); + Color color_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.25f); + + Color color_ofCastEnd = hasHit ? DrawPhysics2D.colorForCastLineBeyondHit : DrawPhysics2D.colorForNonHittingCasts; + Color color_ofCastEnd_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.5f); + Color color_ofCastEnd_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.25f); + + bool boxScaleIsZero = UtilitiesDXXL_Math.ApproximatelyZero(boxSize_V2); + Vector2 absBoxSize_V2 = UtilitiesDXXL_Math.Abs(boxSize_V2); + float averageBoxSize = 0.5f * (absBoxSize_V2.x + absBoxSize_V2.y); + + if (boxScaleIsZero == false) + { + FillBoxCastOutlineVertices(direction_normalized_V2, boxSize_V2, angleDegCC); + FillVolumeCastOutlineVertices_projectedIntoPerpToCastDirPlane(direction_V2); + float heightOfCastCorridor_perpToCastDir = (volumeCastOutlineVertice1_projectedIntoPerpToCastDirPlane_local - volumeCastOutlineVertice2_projectedIntoPerpToCastDirPlane_local).magnitude; + float arrowWidth = heightOfCastCorridor_perpToCastDir * 0.25f; + float arrowLength = heightOfCastCorridor_perpToCastDir * 0.5f; + float arrowsRelConeLenth = 0.45f; + + DrawBoxAtCastStartAndEnd(origin_V2, endPos_V2, boxSize_V2, angleDegCC, color, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + float startArrows_startDistanceFromStart = averageBoxSize * 0.5f + arrowLength; + DrawArrowsAtVolumeCastStartAndEnd(out float distance_ofStartArrowsStartPos, out float distance_ofEndArrowsStartPos, hasHit, origin_V2, direction_normalized_V2, startArrows_startDistanceFromStart, maxDistance, distanceOfFarestHit, arrowLength, color_lowerAlpha, color_ofCastEnd_lowerAlpha, arrowsRelConeLenth, arrowWidth, durationInSec, hiddenByNearerObjects); + + float sizeApproximationOfVolume = averageBoxSize; + DrawCascadeOfArrows(distance_ofStartArrowsStartPos, distance_ofEndArrowsStartPos, sizeApproximationOfVolume, hasHit, hasUnlimitedLength, origin_V2, direction_normalized_V2, distanceOfFarestHit, arrowLength, arrowWidth, arrowsRelConeLenth, color_lowerAlpha, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + DrawCascadeOfVolumeSilhouette2Dslices(sizeApproximationOfVolume, hasHit, hasUnlimitedLength, origin_V2, direction_normalized_V2, maxDistance, distanceOfFarestHit, color_lowAlpha, color_ofCastEnd_lowAlpha, durationInSec, hiddenByNearerObjects); + } + else + { + volumeCastOutlineVertice1_local = Vector2.zero; + volumeCastOutlineVertice2_local = Vector2.zero; + } + + DrawVolumeCastDirOutline(hasHit, origin_V2, endPos_V2, direction_normalized_V2, distanceOfFarestHit, maxDistance, color, color_ofCastEnd, durationInSec, hiddenByNearerObjects); + WriteTextAtBoxCastOrigin(origin_V2, direction_normalized_V2, castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3, atLeastOneBoxDimIsSmallerThan0d00011, color, nameText, hitCount, maxDistance, averageBoxSize, durationInSec, hiddenByNearerObjects); + } + + + static void DrawRayOfCapsulecast(Vector2 origin_V2, Vector2 size_V2, bool atLeastOneBoxDimIsSmallerThan0d00011, CapsuleDirection2D capsuleDirection, float angleDegCC, int hitCount, Vector2 direction_V2, float maxDistance, string nameText, float distanceOfFarestHit, float durationInSec, bool hiddenByNearerObjects) + { + bool hasHit = hitCount > 0; + Vector2 direction_normalized_V2 = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(direction_V2); + Vector3 castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3 = Vector3.Cross(Vector3.forward, direction_normalized_V2); + bool hasUnlimitedLength = float.IsInfinity(maxDistance); + maxDistance = Mathf.Min(maxDistance, 100000.0f); + maxDistance = Mathf.Max(maxDistance, -100000.0f); + + Color color = hasHit ? DrawPhysics2D.colorForHittingCasts : DrawPhysics2D.colorForNonHittingCasts; + Color color_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.5f); + Color color_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.25f); + + Color color_ofCastEnd = hasHit ? DrawPhysics2D.colorForCastLineBeyondHit : DrawPhysics2D.colorForNonHittingCasts; + Color color_ofCastEnd_lowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.5f); + Color color_ofCastEnd_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofCastEnd, 0.25f); + + Vector2 endPos_V2 = origin_V2 + direction_normalized_V2 * maxDistance; + bool capsuleSizeIsZero = UtilitiesDXXL_Math.ApproximatelyZero(size_V2); + Vector2 absSize_V2 = UtilitiesDXXL_Math.Abs(size_V2); + absSize_V2 = ExpandCapsuleDimsToSufficeCapsuleDirectionType(absSize_V2, capsuleDirection); + float capsuleRadius = (capsuleDirection == CapsuleDirection2D.Vertical) ? (0.5f * absSize_V2.x) : (0.5f * absSize_V2.y); + + if (capsuleSizeIsZero == false) + { + float sizeAlongAbsLongerCapsuleDir = Mathf.Max(absSize_V2.x, absSize_V2.y); + Vector2 unturned_vectorToACircleCenter_local = (capsuleDirection == CapsuleDirection2D.Vertical) ? (Vector2.up * (0.5f * sizeAlongAbsLongerCapsuleDir - capsuleRadius)) : (Vector2.right * (0.5f * sizeAlongAbsLongerCapsuleDir - capsuleRadius)); + float distanceBetweenCircles = (capsuleDirection == CapsuleDirection2D.Vertical) ? (absSize_V2.y - 2.0f * capsuleRadius) : (absSize_V2.x - 2.0f * capsuleRadius); + float capsuleCirclesDiameter = 2.0f * capsuleRadius; + float sizeApproximationOfCapsule = capsuleCirclesDiameter + 0.5f * distanceBetweenCircles; + Quaternion capsuleRotation = Quaternion.AngleAxis(angleDegCC, Vector3.forward); + Vector2 turned_vectorToACircleCenter_local = capsuleRotation * unturned_vectorToACircleCenter_local; + + FillCapsuleCastOutlineVertices(turned_vectorToACircleCenter_local, -turned_vectorToACircleCenter_local, direction_normalized_V2, capsuleRadius); + FillVolumeCastOutlineVertices_projectedIntoPerpToCastDirPlane(direction_V2); + float heightOfCastCorridor_perpToCastDir = (volumeCastOutlineVertice1_projectedIntoPerpToCastDirPlane_local - volumeCastOutlineVertice2_projectedIntoPerpToCastDirPlane_local).magnitude; + float arrowWidth = heightOfCastCorridor_perpToCastDir * 0.25f; + float arrowLength = heightOfCastCorridor_perpToCastDir * 0.5f; + float arrowsRelConeLenth = 0.45f; + + DrawCapsuleAtCastStartAndEnd(origin_V2, endPos_V2, size_V2, capsuleDirection, angleDegCC, color, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + float distanceOfCapsulesFarestPosFromOrigin_alongCastDir = GetDistanceOfCapsulesFarestPosFromOrigin_alongCastDir(direction_normalized_V2, turned_vectorToACircleCenter_local, capsuleRadius); + float startArrows_startDistanceFromStart = distanceOfCapsulesFarestPosFromOrigin_alongCastDir + capsuleRadius; + DrawArrowsAtVolumeCastStartAndEnd(out float distance_ofStartArrowsStartPos, out float distance_ofEndArrowsStartPos, hasHit, origin_V2, direction_normalized_V2, startArrows_startDistanceFromStart, maxDistance, distanceOfFarestHit, arrowLength, color_lowerAlpha, color_ofCastEnd_lowerAlpha, arrowsRelConeLenth, arrowWidth, durationInSec, hiddenByNearerObjects); + DrawCascadeOfArrows(distance_ofStartArrowsStartPos, distance_ofEndArrowsStartPos, sizeApproximationOfCapsule, hasHit, hasUnlimitedLength, origin_V2, direction_normalized_V2, distanceOfFarestHit, arrowLength, arrowWidth, arrowsRelConeLenth, color_lowerAlpha, color_ofCastEnd_lowerAlpha, durationInSec, hiddenByNearerObjects); + DrawCascadeOfVolumeSilhouette2Dslices(sizeApproximationOfCapsule, hasHit, hasUnlimitedLength, origin_V2, direction_normalized_V2, maxDistance, distanceOfFarestHit, color_lowAlpha, color_ofCastEnd_lowAlpha, durationInSec, hiddenByNearerObjects); + } + else + { + volumeCastOutlineVertice1_local = Vector2.zero; + volumeCastOutlineVertice2_local = Vector2.zero; + } + + DrawVolumeCastDirOutline(hasHit, origin_V2, endPos_V2, direction_normalized_V2, distanceOfFarestHit, maxDistance, color, color_ofCastEnd, durationInSec, hiddenByNearerObjects); + WriteTextAtCapsuleCastOrigin(origin_V2, direction_normalized_V2, capsuleRadius, castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3, atLeastOneBoxDimIsSmallerThan0d00011, color, nameText, hitCount, maxDistance, durationInSec, hiddenByNearerObjects); + } + + static void DrawCircleAtCastStartAndEnd(Vector2 origin_V2, Vector2 endPos_V2, float circleRadius, Color color, Color color_ofCastEnd_lowerAlpha, float durationInSec, bool hiddenByNearerObjects) + { + //start circle: + DrawShapes.Circle2D(origin_V2, circleRadius, color, GetZPosForDrawVisualisation(), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.solid, false, durationInSec, hiddenByNearerObjects); + + //end circle: + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + DrawShapes.Circle2D(endPos_V2, circleRadius, color_ofCastEnd_lowerAlpha, GetZPosForDrawVisualisation(), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.solid, false, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawBoxAtCastStartAndEnd(Vector2 origin_V2, Vector2 endPos_V2, Vector2 boxSize_V2, float angleDegCC, Color color, Color color_ofCastEnd_lowerAlpha, float durationInSec, bool hiddenByNearerObjects) + { + //start box: + DrawShapes.Box2D(origin_V2, boxSize_V2, color, GetZPosForDrawVisualisation(), angleDegCC, DrawShapes.Shape2DType.square, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.solid, false, durationInSec, hiddenByNearerObjects); + + //end box: + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + DrawShapes.Box2D(endPos_V2, boxSize_V2, color_ofCastEnd_lowerAlpha, GetZPosForDrawVisualisation(), angleDegCC, DrawShapes.Shape2DType.square, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.solid, false, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawCapsuleAtCastStartAndEnd(Vector2 origin_atCastStart_V2, Vector2 origin_atCastEnd_V2, Vector2 size_V2, CapsuleDirection2D capsuleDirection, float angleDegCC, Color color, Color color_ofCastEnd_lowerAlpha, float durationInSec, bool hiddenByNearerObjects) + { + //start capsule: + DrawShapes.Capsule2D(origin_atCastStart_V2, size_V2, color, GetZPosForDrawVisualisation(), capsuleDirection, angleDegCC, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.solid, false, false, durationInSec, hiddenByNearerObjects); + + //end capsule: + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + DrawShapes.Capsule2D(origin_atCastEnd_V2, size_V2, color_ofCastEnd_lowerAlpha, GetZPosForDrawVisualisation(), capsuleDirection, angleDegCC, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.solid, false, false, durationInSec, hiddenByNearerObjects); + } + } + + static Vector2 ExpandCapsuleDimsToSufficeCapsuleDirectionType(Vector2 absSize_preExpanding_V2, CapsuleDirection2D capsuleDirection) + { + if (capsuleDirection == CapsuleDirection2D.Vertical) + { + absSize_preExpanding_V2.y = Mathf.Max(absSize_preExpanding_V2.x, absSize_preExpanding_V2.y); + } + else + { + absSize_preExpanding_V2.x = Mathf.Max(absSize_preExpanding_V2.x, absSize_preExpanding_V2.y); + } + return absSize_preExpanding_V2; + } + + static float GetDistanceOfCapsulesFarestPosFromOrigin_alongCastDir(Vector2 direction_normalized_V2, Vector2 turned_vectorToACircleCenter_local, float capsuleRadius) + { + Vector2 circle1Pos_local = turned_vectorToACircleCenter_local; + Vector2 circle2Pos_local = -turned_vectorToACircleCenter_local; + + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized_V2, circle1Pos_local)) + { + return circle1Pos_local.magnitude + capsuleRadius; + } + else + { + return circle2Pos_local.magnitude + capsuleRadius; + } + } + + static void DrawArrowsAtVolumeCastStartAndEnd(out float distance_ofStartArrowsStartPos, out float distance_ofEndArrowsStartPos, bool hasHit, Vector2 origin_V2, Vector2 direction_normalized_V2, float distanceFromOrigin_toStartOfStartArrow, float maxDistance, float distanceOfFarestHit, float arrowLength, Color color_lowerAlpha, Color color_ofCastEnd_lowerAlpha, float arrowsRelConeLenth, float arrowWidth, float durationInSec, bool hiddenByNearerObjects) + { + distance_ofStartArrowsStartPos = 0.0f; + distance_ofEndArrowsStartPos = 0.0f; + + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + if (arrowLength > UtilitiesDXXL_Physics.minArrowLength) + { + //at start: + float original_distanceFromOrigin_toStartOfStartArrow = distanceFromOrigin_toStartOfStartArrow; + distanceFromOrigin_toStartOfStartArrow = Mathf.Min(distanceFromOrigin_toStartOfStartArrow, 0.5f * maxDistance); + if (hasHit) { distanceFromOrigin_toStartOfStartArrow = Mathf.Min(distanceFromOrigin_toStartOfStartArrow, 0.5f * distanceOfFarestHit); } + if (distanceFromOrigin_toStartOfStartArrow <= 0.0f) { distanceFromOrigin_toStartOfStartArrow = original_distanceFromOrigin_toStartOfStartArrow; } + bool isAfterLastHit = hasHit && ((distanceFromOrigin_toStartOfStartArrow + 0.5f * arrowLength) > distanceOfFarestHit); + distance_ofStartArrowsStartPos = distanceFromOrigin_toStartOfStartArrow; + Vector2 startVector_startPos_V2 = origin_V2 + direction_normalized_V2 * distanceFromOrigin_toStartOfStartArrow; + Vector2 startVector_endPos_V2 = origin_V2 + direction_normalized_V2 * (distanceFromOrigin_toStartOfStartArrow + arrowLength); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics2D.Vector(startVector_startPos_V2, startVector_endPos_V2, isAfterLastHit ? color_ofCastEnd_lowerAlpha : color_lowerAlpha, arrowWidth, null, arrowsRelConeLenth, false, GetZPosForDrawVisualisation(), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + + //at end: + float distanceFromOrigin_toStartOfEndArrow = maxDistance - original_distanceFromOrigin_toStartOfStartArrow - arrowLength; + distance_ofEndArrowsStartPos = distanceFromOrigin_toStartOfEndArrow; + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.high_withFullDetails) + { + if (maxDistance > (distanceFromOrigin_toStartOfStartArrow + 12.0f * arrowLength)) + { + isAfterLastHit = hasHit && ((distanceFromOrigin_toStartOfEndArrow + 0.5f * arrowLength) > distanceOfFarestHit); + Vector2 endVector_startPos_V2 = origin_V2 + direction_normalized_V2 * distanceFromOrigin_toStartOfEndArrow; + Vector2 endVector_endPos_V2 = origin_V2 + direction_normalized_V2 * (distanceFromOrigin_toStartOfEndArrow + arrowLength); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics2D.Vector(endVector_startPos_V2, endVector_endPos_V2, isAfterLastHit ? color_ofCastEnd_lowerAlpha : color_lowerAlpha, arrowWidth, null, arrowsRelConeLenth, false, GetZPosForDrawVisualisation(), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + } + } + } + + static void FillCircleCastOutlineVertices(Vector2 direction_normalized_V2, float circleRadius) + { + volumeCastOutlineVertice1_local = Vector3.Cross(Vector3.forward, direction_normalized_V2) * circleRadius; + volumeCastOutlineVertice2_local = -volumeCastOutlineVertice1_local; + } + + ///cube definition: + //viewed along z-forward: + //starts with: nearer square, lowLeft, then counterclockwise + static Vector2[] unscaledUnrotatedBox2D = new Vector2[4] { new Vector2(-0.5f, -0.5f), new Vector2(0.5f, -0.5f), new Vector2(0.5f, 0.5f), new Vector2(-0.5f, 0.5f) }; + static void FillBoxCastOutlineVertices(Vector2 direction_normalized_V2, Vector2 boxSize_V2, float angleDegCC) + { + Quaternion boxRotation = Quaternion.AngleAxis(angleDegCC, Vector3.forward); + Vector2 toUp_ofBox = boxRotation * Vector3.up; + Vector2 toRight_ofBox = boxRotation * Vector3.right; + + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized_V2, toRight_ofBox)) + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized_V2, toUp_ofBox)) + { + volumeCastOutlineVertice1_local = boxRotation * Vector2.Scale(unscaledUnrotatedBox2D[1], boxSize_V2); + volumeCastOutlineVertice2_local = boxRotation * Vector2.Scale(unscaledUnrotatedBox2D[3], boxSize_V2); + } + else + { + volumeCastOutlineVertice1_local = boxRotation * Vector2.Scale(unscaledUnrotatedBox2D[0], boxSize_V2); + volumeCastOutlineVertice2_local = boxRotation * Vector2.Scale(unscaledUnrotatedBox2D[2], boxSize_V2); + } + } + else + { + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(direction_normalized_V2, toUp_ofBox)) + { + volumeCastOutlineVertice1_local = boxRotation * Vector2.Scale(unscaledUnrotatedBox2D[0], boxSize_V2); + volumeCastOutlineVertice2_local = boxRotation * Vector2.Scale(unscaledUnrotatedBox2D[2], boxSize_V2); + } + else + { + volumeCastOutlineVertice1_local = boxRotation * Vector2.Scale(unscaledUnrotatedBox2D[1], boxSize_V2); + volumeCastOutlineVertice2_local = boxRotation * Vector2.Scale(unscaledUnrotatedBox2D[3], boxSize_V2); + } + } + } + + static void FillCapsuleCastOutlineVertices(Vector2 posOfCapsuleCircle1_local, Vector2 posOfCapsuleCircle2_local, Vector2 direction_normalized_V2, float capsuleRadius) + { + Vector2 up_insideXYPlane_ofCastDir_normalized = Vector3.Cross(Vector3.forward, direction_normalized_V2); + bool circle1_isHigher_seenAlongCastDir = UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(posOfCapsuleCircle1_local, up_insideXYPlane_ofCastDir_normalized); + if (circle1_isHigher_seenAlongCastDir) + { + volumeCastOutlineVertice1_local = posOfCapsuleCircle1_local + up_insideXYPlane_ofCastDir_normalized * capsuleRadius; + volumeCastOutlineVertice2_local = posOfCapsuleCircle2_local - up_insideXYPlane_ofCastDir_normalized * capsuleRadius; + } + else + { + volumeCastOutlineVertice1_local = posOfCapsuleCircle1_local - up_insideXYPlane_ofCastDir_normalized * capsuleRadius; + volumeCastOutlineVertice2_local = posOfCapsuleCircle2_local + up_insideXYPlane_ofCastDir_normalized * capsuleRadius; + } + } + + static InternalDXXL_Plane plane_throughWorldOrigin_containingZAxis_perpToCastDir = new InternalDXXL_Plane(); + static void FillVolumeCastOutlineVertices_projectedIntoPerpToCastDirPlane(Vector2 direction_V2) + { + Vector3 direction_V3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(direction_V2); + plane_throughWorldOrigin_containingZAxis_perpToCastDir.Recreate(Vector3.zero, direction_V3); + volumeCastOutlineVertice1_projectedIntoPerpToCastDirPlane_local = plane_throughWorldOrigin_containingZAxis_perpToCastDir.Get_perpProjectionOfPointOnPlane(volumeCastOutlineVertice1_local); + volumeCastOutlineVertice2_projectedIntoPerpToCastDirPlane_local = -volumeCastOutlineVertice1_projectedIntoPerpToCastDirPlane_local; + distanceOfOutlineVerticesToOrigin_alongCastsUp = volumeCastOutlineVertice1_projectedIntoPerpToCastDirPlane_local.magnitude; + } + + static void DrawVolumeCastDirOutline(bool hasHit, Vector2 origin_V2, Vector2 endPos_V2, Vector2 direction_normalized_V2, float distanceOfFarestHit, float maxDistance, Color color, Color color_ofCastEnd, float durationInSec, bool hiddenByNearerObjects) + { + if (hasHit) + { + if (maxDistance < 0.0f) + { + //unity.RaycastHit2D always returns positve values for "distance", also if the cast goes backward due to negative "maxDistance" + distanceOfFarestHit = -distanceOfFarestHit; + } + + Vector2 posOfFarestHit_V2 = origin_V2 + direction_normalized_V2 * distanceOfFarestHit; + + //vertice1 toFarest hit, then to end: + Line_fadeableAnimSpeed_2D.InternalDraw(origin_V2 + volumeCastOutlineVertice1_local, posOfFarestHit_V2 + volumeCastOutlineVertice1_local, color, 0.0f, null, DrawBasics.LineStyle.solid, GetZPosForDrawVisualisation(), 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed_2D.InternalDraw(posOfFarestHit_V2 + volumeCastOutlineVertice1_local, endPos_V2 + volumeCastOutlineVertice1_local, color_ofCastEnd, 0.0f, null, DrawBasics.LineStyle.solid, GetZPosForDrawVisualisation(), 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //vertice2 toFarest hit, then to end: + Line_fadeableAnimSpeed_2D.InternalDraw(origin_V2 + volumeCastOutlineVertice2_local, posOfFarestHit_V2 + volumeCastOutlineVertice2_local, color, 0.0f, null, DrawBasics.LineStyle.solid, GetZPosForDrawVisualisation(), 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + Line_fadeableAnimSpeed_2D.InternalDraw(posOfFarestHit_V2 + volumeCastOutlineVertice2_local, endPos_V2 + volumeCastOutlineVertice2_local, color_ofCastEnd, 0.0f, null, DrawBasics.LineStyle.solid, GetZPosForDrawVisualisation(), 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + //vertice1 to end: + Line_fadeableAnimSpeed_2D.InternalDraw(origin_V2 + volumeCastOutlineVertice1_local, endPos_V2 + volumeCastOutlineVertice1_local, color, 0.0f, null, DrawBasics.LineStyle.solid, GetZPosForDrawVisualisation(), 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + //vertice2 to end: + Line_fadeableAnimSpeed_2D.InternalDraw(origin_V2 + volumeCastOutlineVertice2_local, endPos_V2 + volumeCastOutlineVertice2_local, color, 0.0f, null, DrawBasics.LineStyle.solid, GetZPosForDrawVisualisation(), 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + + static void DrawCascadeOfVolumeSilhouette2Dslices(float sizeApproximationOfVolume, bool hasHit, bool hasUnlimitedLength, Vector2 origin_V2, Vector2 direction_normalized_V2, float maxDistance, float distanceOfFarestHit, Color color_lowAlpha, Color color_ofCastEnd_lowAlpha, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + if (UtilitiesDXXL_Math.ApproximatelyZero(DrawPhysics2D.castCorridorVisualizerDensity) == false) + { + float distanceBetweenSilhouettes = hasUnlimitedLength ? (4.0f * sizeApproximationOfVolume) : (2.2f * sizeApproximationOfVolume); + int maxSilhouettesPerVolumeCast = hasUnlimitedLength ? 50 : 200; + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + maxSilhouettesPerVolumeCast = hasUnlimitedLength ? 20 : 40; + } + + float used_castSilhouetteVisualizerDensity = DrawPhysics2D.castCorridorVisualizerDensity; + used_castSilhouetteVisualizerDensity = Mathf.Max(used_castSilhouetteVisualizerDensity, 0.01f); + used_castSilhouetteVisualizerDensity = Mathf.Min(used_castSilhouetteVisualizerDensity, 1000.0f); + distanceBetweenSilhouettes = distanceBetweenSilhouettes / used_castSilhouetteVisualizerDensity; + if (used_castSilhouetteVisualizerDensity > 1.0f) { maxSilhouettesPerVolumeCast = Mathf.RoundToInt(used_castSilhouetteVisualizerDensity * maxSilhouettesPerVolumeCast); } + maxSilhouettesPerVolumeCast = Mathf.Min(maxSilhouettesPerVolumeCast, DrawPhysics2D.maxCorridorVisualizersPerCastVisualization); + + distanceBetweenSilhouettes = Mathf.Max(distanceBetweenSilhouettes, 0.1f); + float distance_ofCurrSilhouette = 0.0f; + for (int i_silhouette = 0; i_silhouette < maxSilhouettesPerVolumeCast; i_silhouette++) + { + distance_ofCurrSilhouette = distance_ofCurrSilhouette + distanceBetweenSilhouettes; + bool isAfterLastHit = hasHit && (distance_ofCurrSilhouette > distanceOfFarestHit); + if (distance_ofCurrSilhouette < maxDistance) + { + Vector2 posOfCurrSilhouetteOnRayLine_V2 = origin_V2 + distance_ofCurrSilhouette * direction_normalized_V2; + Line_fadeableAnimSpeed_2D.InternalDraw(posOfCurrSilhouetteOnRayLine_V2 + volumeCastOutlineVertice1_projectedIntoPerpToCastDirPlane_local, posOfCurrSilhouetteOnRayLine_V2 + volumeCastOutlineVertice2_projectedIntoPerpToCastDirPlane_local, isAfterLastHit ? color_ofCastEnd_lowAlpha : color_lowAlpha, 0.0f, null, DrawBasics.LineStyle.solid, GetZPosForDrawVisualisation(), 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + else + { + break; + } + + if (hasUnlimitedLength) + { + distanceBetweenSilhouettes = (1.0f + (0.4f / used_castSilhouetteVisualizerDensity)) * distanceBetweenSilhouettes; + } + else + { + if (i_silhouette > 3) + { + distanceBetweenSilhouettes = (1.0f + (0.25f / used_castSilhouetteVisualizerDensity)) * distanceBetweenSilhouettes; + } + } + } + } + } + + static void DrawCascadeOfArrows(float distance_ofStartArrowsStartPos, float distance_ofEndArrowsStartPos, float sizeApproximationOfVolume, bool hasHit, bool hasUnlimitedLength, Vector2 origin_V2, Vector2 direction_normalized_V2, float distanceOfFarestHit, float arrowLength, float arrowWidth, float arrowsRelConeLenth, Color color_lowerAlpha, Color color_ofCastEnd_lowerAlpha, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.high_withFullDetails) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(DrawPhysics2D.castCorridorVisualizerDensity) == false) + { + if (arrowLength > UtilitiesDXXL_Physics.minArrowLength) + { + float distanceBetweenArrows = hasUnlimitedLength ? (6.0f * sizeApproximationOfVolume) : (3.25f * sizeApproximationOfVolume); + int maxArrowsPerVolumeCast = hasUnlimitedLength ? 5 : 15; + + distanceBetweenArrows = Mathf.Max(distanceBetweenArrows, 0.5f); + float distance_ofCurrArrowsStart = distance_ofStartArrowsStartPos + distanceBetweenArrows; + for (int i_arrow = 0; i_arrow < maxArrowsPerVolumeCast; i_arrow++) + { + if (distance_ofCurrArrowsStart < distance_ofEndArrowsStartPos) + { + bool isAfterLastHit = hasHit && ((distance_ofCurrArrowsStart + 0.5f * arrowLength) > distanceOfFarestHit); + Vector2 vectorStartPos_V2 = origin_V2 + distance_ofCurrArrowsStart * direction_normalized_V2; + Vector2 vectorEndPos_V2 = origin_V2 + (distance_ofCurrArrowsStart + arrowLength) * direction_normalized_V2; + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics2D.Vector(vectorStartPos_V2, vectorEndPos_V2, isAfterLastHit ? color_ofCastEnd_lowerAlpha : color_lowerAlpha, arrowWidth, null, arrowsRelConeLenth, false, GetZPosForDrawVisualisation(), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + } + else + { + break; + } + + if (hasUnlimitedLength) + { + distanceBetweenArrows = 2.0f * distanceBetweenArrows; + } + else + { + if (i_arrow > 3) + { + distanceBetweenArrows = 1.5f * distanceBetweenArrows; + } + } + distance_ofCurrArrowsStart = distance_ofCurrArrowsStart + distanceBetweenArrows; + } + } + } + } + } + + static void WriteTextAtCircleCastOrigin(Vector2 origin_V2, Vector2 direction_normalized_V2, float circleRadius, Vector3 castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3, bool circleRadiusTooSmall, Color color, string nameText, int hitCount, float maxDistance, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + float textSize = 0.2f * circleRadius; + string additinalWarningText = circleRadiusTooSmall ? "[ circle radius too small -> potentially collisions missing]
" : null; + string castText = GetVolumeCastStartTextString("Circlecast2D

number of hits: ", nameText, hitCount, maxDistance, additinalWarningText); + WriteTextAtVolumeCastOrigin(castText, origin_V2, castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3, direction_normalized_V2, textSize, color, durationInSec, hiddenByNearerObjects); + } + + static void WriteTextAtBoxCastOrigin(Vector2 origin_V2, Vector2 direction_normalized_V2, Vector3 castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3, bool atLeastOneBoxDimIsSmallerThan0d00011, Color color, string nameText, int hitCount, float maxDistance, float averageBoxSize, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + float textSize = 0.1f * averageBoxSize; + string additinalWarningText = atLeastOneBoxDimIsSmallerThan0d00011 ? "[ box dimension is very small -> potentially collisions missing]
" : null; + string castText = GetVolumeCastStartTextString("Boxcast2D

number of hits: ", nameText, hitCount, maxDistance, additinalWarningText); + WriteTextAtVolumeCastOrigin(castText, origin_V2, castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3, direction_normalized_V2, textSize, color, durationInSec, hiddenByNearerObjects); + } + + static void WriteTextAtCapsuleCastOrigin(Vector2 origin_V2, Vector2 direction_normalized_V2, float capsuleRadius, Vector3 castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3, bool atLeastOneBoxDimIsSmallerThan0d00011, Color color, string nameText, int hitCount, float maxDistance, float durationInSec, bool hiddenByNearerObjects) + { + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + float textSize = 0.2f * capsuleRadius; + string additinalWarningText = atLeastOneBoxDimIsSmallerThan0d00011 ? "[ capsule dimension is very small -> potentially collisions missing]
" : null; + string castText = GetVolumeCastStartTextString("Capsulecast2D

number of hits: ", nameText, hitCount, maxDistance, additinalWarningText); + WriteTextAtVolumeCastOrigin(castText, origin_V2, castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3, direction_normalized_V2, textSize, color, durationInSec, hiddenByNearerObjects); + } + + static void WriteTextAtVolumeCastOrigin(string castText, Vector2 origin_V2, Vector3 castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3, Vector2 direction_normalized_V2, float textSize, Color color, float durationInSec, bool hiddenByNearerObjects) + { + textSize = Mathf.Max(textSize, 0.02f); + Color textColor = Color.Lerp(color, Color.black, 0.75f); + Vector2 textPos = origin_V2 + (Vector2)castsUp_insideXYPlane_90degCCFromCastDir_normalized_V3 * (distanceOfOutlineVerticesToOrigin_alongCastsUp + 0.65f * textSize); + bool direction_isTowardsRight = (direction_normalized_V2.x >= 0.0f); + Vector2 textDir = direction_isTowardsRight ? direction_normalized_V2 : (-direction_normalized_V2); + DrawText.TextAnchorDXXL textAnchor = direction_isTowardsRight ? DrawText.TextAnchorDXXL.LowerLeft : DrawText.TextAnchorDXXL.UpperRight; + UtilitiesDXXL_Text.Write2DFramed(castText, textPos, textColor, textSize, textDir, textAnchor, GetZPosForDrawVisualisation(), DrawBasics.LineStyle.solid, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + + static string GetVolumeCastStartTextString(string volumeCastTypeIdentifyingStringPart, string nameText, int hitCount, float maxDistance, string additinalWarningText) + { + additinalWarningText = UtilitiesDXXL_Math.ApproximatelyZero(maxDistance) ? "[ cast distance is zero]
" + additinalWarningText : additinalWarningText; + additinalWarningText = (maxDistance < 0.0f) ? "[ negative cast direction]
" + additinalWarningText : additinalWarningText; + + string startText; + if (DrawPhysics2D.drawCastNameTag_atCastOrigin && nameText != null && nameText.Length != 0) + { + startText = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? additinalWarningText + UtilitiesDXXL_Physics.GetSizeMarkupStartStringForCastNames(nameText) + nameText + "

hits: " + hitCount : additinalWarningText + UtilitiesDXXL_Physics.GetSizeMarkupStartStringForCastNames(nameText) + nameText + "

number of hits: " + hitCount; + } + else + { + startText = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? additinalWarningText + "hits: " + hitCount : additinalWarningText + volumeCastTypeIdentifyingStringPart + hitCount; + } + + return startText; + } + + static void DrawCirclecastHitInfo(float circleRadius, RaycastHit2D hitInfo2D, int i_hit, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.point) || UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.normal)) + { + Debug.LogError("Draw XXL: A 'Physics2D.CircleCast()' returned an invalid hit position (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + ") or normal (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.normal) + "). The drawn cast visualization may be incorrect."); + } + else + { + bool saveDrawnLines = i_hit >= DrawPhysics2D.hitResultsWithMoreDetailedDisplay; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.high_withFullDetails) { saveDrawnLines = true; } + + Vector3 impactPos_V3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(hitInfo2D.point, hitInfo2D.transform.position.z); + DrawCircleAtHitPos(hitInfo2D, circleRadius, durationInSec, hiddenByNearerObjects); + DrawNormalAtVolumeCastHitPos(impactPos_V3, saveDrawnLines, hitInfo2D, durationInSec, hiddenByNearerObjects); + DrawDashedLineAlongZ(impactPos_V3, hitInfo2D, durationInSec, hiddenByNearerObjects); + string text = GetTextAtHitPos_forVolumeCast("Circlecast2D hit #", saveDrawnLines, hitInfo2D, i_hit, nameText); + string additionalWarningText = null; + DrawTextDescriptionAtVolumeCastHitPos(impactPos_V3, hitInfo2D, nameText, text, durationInSec, hiddenByNearerObjects, additionalWarningText); + } + } + + static void DrawBoxcastHitInfo(Vector2 boxSize_V2, float angleDegCC, RaycastHit2D hitInfo2D, int i_hit, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.point) || UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.normal)) + { + Debug.LogError("Draw XXL: A 'Physics2D.BoxCast()' returned an invalid hit position (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + ") or normal (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.normal) + "). The drawn cast visualization may be incorrect."); + } + else + { + bool saveDrawnLines = i_hit >= DrawPhysics2D.hitResultsWithMoreDetailedDisplay; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.high_withFullDetails) { saveDrawnLines = true; } + + Vector3 impactPos_V3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(hitInfo2D.point, hitInfo2D.transform.position.z); + DrawBoxAtHitPos(boxSize_V2, angleDegCC, hitInfo2D, durationInSec, hiddenByNearerObjects); + DrawNormalAtVolumeCastHitPos(impactPos_V3, saveDrawnLines, hitInfo2D, durationInSec, hiddenByNearerObjects); + DrawDashedLineAlongZ(impactPos_V3, hitInfo2D, durationInSec, hiddenByNearerObjects); + string text = GetTextAtHitPos_forVolumeCast("Boxcast2D hit #", saveDrawnLines, hitInfo2D, i_hit, nameText); + string additionalWarningText = null; + DrawTextDescriptionAtVolumeCastHitPos(impactPos_V3, hitInfo2D, nameText, text, durationInSec, hiddenByNearerObjects, additionalWarningText); + } + } + + static void DrawCapsulecastHitInfo(Vector2 size_V2, CapsuleDirection2D capsuleDirection, float angleDegCC, RaycastHit2D hitInfo2D, int i_hit, string nameText, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.point) || UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.normal)) + { + Debug.LogError("Draw XXL: A 'Physics2D.CapsuleCast()' returned an invalid hit position (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + ") or normal (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.normal) + "). The drawn cast visualization may be incorrect."); + } + else + { + bool saveDrawnLines = i_hit >= DrawPhysics2D.hitResultsWithMoreDetailedDisplay; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.high_withFullDetails) { saveDrawnLines = true; } + + Vector3 impactPos_V3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(hitInfo2D.point, hitInfo2D.transform.position.z); + DrawCapsuleAtHitPos(size_V2, capsuleDirection, angleDegCC, hitInfo2D, i_hit, durationInSec, hiddenByNearerObjects); + DrawNormalAtVolumeCastHitPos(impactPos_V3, saveDrawnLines, hitInfo2D, durationInSec, hiddenByNearerObjects); + DrawDashedLineAlongZ(impactPos_V3, hitInfo2D, durationInSec, hiddenByNearerObjects); + string text = GetTextAtHitPos_forVolumeCast("Capsulecast2D hit #", saveDrawnLines, hitInfo2D, i_hit, nameText); + string additionalWarningText = null; + DrawTextDescriptionAtVolumeCastHitPos(impactPos_V3, hitInfo2D, nameText, text, durationInSec, hiddenByNearerObjects, additionalWarningText); + } + } + + static void DrawCircleAtHitPos(RaycastHit2D hitInfo2D, float circleRadius, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.centroid)) + { + Debug.LogError("Draw XXL: A 'Physics2D.CircleCast()' returned an invalid hit position centroid (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.centroid) + "). The drawn cast visualization may be incorrect."); + } + else + { + Color color_ofHittingVolume = Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.white, 0.6f); + DrawShapes.Circle2D(hitInfo2D.centroid, circleRadius, color_ofHittingVolume, hitInfo2D.transform.position.z, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.solid, false, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawBoxAtHitPos(Vector2 boxSize_V2, float angleDegCC, RaycastHit2D hitInfo2D, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.centroid)) + { + Debug.LogError("Draw XXL: A 'Physics2D.BoxCast()' returned an invalid hit position centroid (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.centroid) + "). The drawn cast visualization may be incorrect."); + } + else + { + Color color_ofHittingVolume = Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.white, 0.6f); + DrawShapes.Box2D(hitInfo2D.centroid, boxSize_V2, color_ofHittingVolume, hitInfo2D.transform.position.z, angleDegCC, DrawShapes.Shape2DType.square, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.solid, false, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawCapsuleAtHitPos(Vector2 size_V2, CapsuleDirection2D capsuleDirection, float angleDegCC, RaycastHit2D hitInfo2D, int i_hit, float durationInSec, bool hiddenByNearerObjects) + { + if (UtilitiesDXXL_Math.VectorIsInvalid(hitInfo2D.centroid)) + { + Debug.LogError("Draw XXL: A 'Physics2D.CapsuleCast()' returned an invalid hit position centroid (namely " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.centroid) + "). The drawn cast visualization may be incorrect."); + } + else + { + Color color_ofHittingVolume = Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.white, 0.6f); + DrawShapes.Capsule2D(hitInfo2D.centroid, size_V2, color_ofHittingVolume, hitInfo2D.transform.position.z, capsuleDirection, angleDegCC, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.solid, false, false, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawNormalAtVolumeCastHitPos(Vector3 impactPos_V3, bool saveDrawnLines, RaycastHit2D hitInfo2D, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 normal_V3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(hitInfo2D.normal); + Color color_ofNormal = Get_color_ofNormal(); + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + //normal: + DrawBasics2D.LineFrom(impactPos_V3, normal_V3, color_ofNormal, 0.0f, null, DrawBasics.LineStyle.solid, hitInfo2D.transform.position.z, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + //normal socket: + DrawShapes.Square(impactPos_V3, 0.12f, color_ofNormal, normal_V3, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + else + { + //normal: + float relConeLength_ofNormalVector = 0.17f; + string normalText = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? null : (saveDrawnLines ? "normal" : "normal
of hit surface"); + UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); + DrawBasics2D.VectorFrom(impactPos_V3, normal_V3, color_ofNormal, saveDrawnLines ? 0.0f : 0.006f, normalText, relConeLength_ofNormalVector, false, hitInfo2D.transform.position.z, false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); + + //normal socket: + DrawShapes.Decagon(impactPos_V3, 0.03f, color_ofNormal, normal_V3, default, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + } + + static Color Get_color_ofNormal() + { + if (UtilitiesDXXL_Colors.IsDefaultColor(DrawPhysics2D.overwriteColorForCastsHitNormals)) + { + return Get_defaultColor_ofNormal(); + } + else + { + return DrawPhysics2D.overwriteColorForCastsHitNormals; + } + } + + public static Color Get_defaultColor_ofNormal() + { + return ((DrawPhysics2D.colorForHittingCasts.grayscale < 0.175f) ? Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.white, 0.7f) : Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.black, 0.7f)); + } + + static void DrawDashedLineAlongZ(Vector3 impactPos_V3, RaycastHit2D hitInfo2D, float durationInSec, bool hiddenByNearerObjects) + { + float absZDistance = Mathf.Abs(hitInfo2D.transform.position.z - GetZPosForDrawVisualisation()); + Color color_forDashedLineAlongZ = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawPhysics2D.colorForHittingCasts, 0.6f); + Vector3 impactPos_projectedOntoDrawVisualisation_V3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(hitInfo2D.point, GetZPosForDrawVisualisation()); + DrawBasics.LineStyle lineStyleAlongZ = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) ? DrawBasics.LineStyle.solid : DrawBasics.LineStyle.dashedLong; + Line_fadeableAnimSpeed.InternalDraw(impactPos_V3, impactPos_projectedOntoDrawVisualisation_V3, color_forDashedLineAlongZ, 0.0f, null, lineStyleAlongZ, absZDistance, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + + static string GetTextAtHitPos_forVolumeCast(string volumeCastTypeSpecifyingStringPart, bool saveDrawnLines, RaycastHit2D hitInfo2D, int i_hit, string nameText) + { + if (DrawPhysics2D.drawCastNameTag_atHitPositions && nameText != null && nameText.Length != 0) + { + return (saveDrawnLines ? (nameText + " / #" + i_hit + ":
hit GO: " + hitInfo2D.transform.gameObject.name + "
pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
dist = " + hitInfo2D.distance) : (UtilitiesDXXL_Physics.GetStrokeWidthMarkupStartStringForHitPosDesctiptionHeaders(nameText) + nameText + " / hit #" + i_hit + ":
GameObject that was hit: " + hitInfo2D.transform.gameObject.name + "
hit pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
distance = " + hitInfo2D.distance)); + } + else + { + return (saveDrawnLines ? ("hit #" + i_hit + ":
hit GO: " + hitInfo2D.transform.gameObject.name + "
pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
dist = " + hitInfo2D.distance) : (volumeCastTypeSpecifyingStringPart + i_hit + ":
GameObject that was hit: " + hitInfo2D.transform.gameObject.name + "
hit pos = " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(hitInfo2D.point) + "
distance = " + hitInfo2D.distance)); + } + } + + static void DrawTextDescriptionAtVolumeCastHitPos(Vector3 impactPos_V3, RaycastHit2D hitInfo2D, string nameText, string text, float durationInSec, bool hiddenByNearerObjects, string additionalWarningText) + { + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) { return; } + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + if (DrawPhysics2D.drawCastNameTag_atHitPositions && nameText != null && nameText.Length != 0) + { + UtilitiesDXXL_Text.Write2DFramed(nameText + additionalWarningText, impactPos_V3, DrawPhysics2D.colorForCastsHitText, 0.1f * DrawPhysics2D.scaleFactor_forCastHitTextSize, 0.0f, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, hitInfo2D.transform.position.z, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + } + else + { + Vector2 textOffsetDir = default(Vector2); + float textOffsetDistance = DrawPhysics2D.scaleFactor_forCastHitTextSize; + + TrySet_default_textOffsetDirection_forPointTags_reversible(); + DrawBasics2D.PointTag(impactPos_V3, text + additionalWarningText, DrawPhysics2D.colorForCastsHitText, 0.0f, textOffsetDistance, textOffsetDir, hitInfo2D.transform.position.z, 1.0f, false, durationInSec, hiddenByNearerObjects); + TryReverse_default_textOffsetDirection_forPointTags(); + } + } + + static float GetDistanceOfSingleHit(bool hasHit, RaycastHit2D hitInfo2D) + { + if (hasHit) + { + if (UtilitiesDXXL_Math.FloatIsInvalid(hitInfo2D.distance)) + { + Debug.LogError("Draw XXL: A 'Physics2D.Cast()' returned an invalid hit distance of '" + hitInfo2D.distance + "'. The drawn cast visualization may be incorrect."); + return 1.0f; + } + else + { + return hitInfo2D.distance; + } + } + else + { + return 0.0f; + } + } + + static float GetDistanceOfFarestHit(RaycastHit2D[] hitInfos2D, int numberOfUsedSlotsInHitInfoArray) + { + float farestDistance = 0.0f; + if (hitInfos2D != null) + { + numberOfUsedSlotsInHitInfoArray = Mathf.Min(numberOfUsedSlotsInHitInfoArray, hitInfos2D.Length); + for (int i = 0; i < numberOfUsedSlotsInHitInfoArray; i++) + { + //"RaycastHit2D.distance" is always positive, also when the castDistance is negative. + if (UtilitiesDXXL_Math.FloatIsInvalid(hitInfos2D[i].distance)) + { + Debug.LogError("Draw XXL: A 'Physics2D.Cast()' returned an invalid hit distance of '" + hitInfos2D[i].distance + "'. The drawn cast visualization may be incorrect."); + } + else + { + farestDistance = Mathf.Max(farestDistance, hitInfos2D[i].distance); + } + } + } + return farestDistance; + } + + public static void DrawBoxOverlapResultOfMax1Collision(bool calledAsArea_insteadOfBox, Vector2 pos_V2, Vector2 size_V2, float angleDegCC, Collider2D overlappingCollider, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + DrawOverlapResultBoxOfMax1Collision(calledAsArea_insteadOfBox, overlappingCollider, pos_V2, size_V2, angleDegCC, nameTag, durationInSec, hiddenByNearerObjects); + bool shapeIsShrinkedToPoint = UtilitiesDXXL_Math.ApproximatelyZero(size_V2); + float approxSize_ofOverlapVolume = UtilitiesDXXL_Math.GetAverageBoxExtent(size_V2); + DrawMarkersAtOverlappingCollidersOfMax1Collision(shapeIsShrinkedToPoint, pos_V2, overlappingCollider, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + } + + public static void DrawBoxOverlapResultOfPotMultipleCollisions(bool calledAsArea_insteadOfBox, Vector2 pos_V2, Vector2 size_V2, float angleDegCC, int numberOfOverlappingColliders, Collider2D[] overlappingColliders, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + bool doesOverlap = numberOfOverlappingColliders > 0; + DrawOverlapResultBoxOfPotMultipleCollisions(calledAsArea_insteadOfBox, doesOverlap, numberOfOverlappingColliders, overlappingColliders, pos_V2, size_V2, angleDegCC, nameTag, durationInSec, hiddenByNearerObjects); + bool shapeIsShrinkedToPoint = UtilitiesDXXL_Math.ApproximatelyZero(size_V2); + float approxSize_ofOverlapVolume = UtilitiesDXXL_Math.GetAverageBoxExtent(size_V2); + DrawMarkersAtOverlappingCollidersOfPotMultipleCollisions(shapeIsShrinkedToPoint, pos_V2, doesOverlap, overlappingColliders, numberOfOverlappingColliders, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + } + + public static void DrawCapsuleOverlapResultOfMax1Collision(Vector2 pos_V2, Vector2 size_V2, CapsuleDirection2D capsuleDirection, float angleDegCC, Collider2D overlappingCollider, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + DrawOverlapResultCapsuleOfMax1Collision(overlappingCollider, pos_V2, size_V2, capsuleDirection, angleDegCC, nameTag, durationInSec, hiddenByNearerObjects); + bool shapeIsShrinkedToPoint = UtilitiesDXXL_Math.ApproximatelyZero(size_V2); + float approxSize_ofOverlapVolume = UtilitiesDXXL_Math.GetAverageBoxExtent(size_V2); + DrawMarkersAtOverlappingCollidersOfMax1Collision(shapeIsShrinkedToPoint, pos_V2, overlappingCollider, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + } + + public static void DrawCapsuleOverlapResultOfPotMultipleCollisions(Vector2 pos_V2, Vector2 size_V2, CapsuleDirection2D capsuleDirection, float angleDegCC, int numberOfOverlappingColliders, Collider2D[] overlappingColliders, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + bool doesOverlap = numberOfOverlappingColliders > 0; + DrawOverlapResultCapsuleOfPotMultipleCollisions(doesOverlap, numberOfOverlappingColliders, overlappingColliders, pos_V2, size_V2, capsuleDirection, angleDegCC, nameTag, durationInSec, hiddenByNearerObjects); + bool shapeIsShrinkedToPoint = UtilitiesDXXL_Math.ApproximatelyZero(size_V2); + float approxSize_ofOverlapVolume = UtilitiesDXXL_Math.GetAverageBoxExtent(size_V2); + DrawMarkersAtOverlappingCollidersOfPotMultipleCollisions(shapeIsShrinkedToPoint, pos_V2, doesOverlap, overlappingColliders, numberOfOverlappingColliders, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + } + + public static void DrawCircleOverlapResultOfMax1Collision(Vector2 pos_V2, float radius, Collider2D overlappingCollider, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + DrawOverlapResultCircleOfMax1Collision(overlappingCollider, pos_V2, radius, nameTag, durationInSec, hiddenByNearerObjects); + bool shapeIsShrinkedToPoint = UtilitiesDXXL_Math.ApproximatelyZero(radius); + float approxSize_ofOverlapVolume = 2.0f * radius; + DrawMarkersAtOverlappingCollidersOfMax1Collision(shapeIsShrinkedToPoint, pos_V2, overlappingCollider, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + } + + public static void DrawCircleOverlapResultOfPotMultipleCollisions(Vector2 pos_V2, float radius, int numberOfOverlappingColliders, Collider2D[] overlappingColliders, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + bool doesOverlap = numberOfOverlappingColliders > 0; + DrawOverlapResultCircleOfPotMultipleCollisions(doesOverlap, numberOfOverlappingColliders, overlappingColliders, pos_V2, radius, nameTag, durationInSec, hiddenByNearerObjects); + bool shapeIsShrinkedToPoint = UtilitiesDXXL_Math.ApproximatelyZero(radius); + float approxSize_ofOverlapVolume = 2.0f * radius; + DrawMarkersAtOverlappingCollidersOfPotMultipleCollisions(shapeIsShrinkedToPoint, pos_V2, doesOverlap, overlappingColliders, numberOfOverlappingColliders, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + } + + public static void DrawPointOverlapResultOfMax1Collision(Vector2 pos_V2, Collider2D overlappingCollider, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + DrawOverlapResultPointOfMax1Collision(overlappingCollider, pos_V2, nameTag, durationInSec, hiddenByNearerObjects); + bool shapeIsShrinkedToPoint = true; + float approxSize_ofOverlapVolume = 0.5f; + DrawMarkersAtOverlappingCollidersOfMax1Collision(shapeIsShrinkedToPoint, pos_V2, overlappingCollider, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + } + + public static void DrawPointOverlapResultOfPotMultipleCollisions(Vector2 pos_V2, int numberOfOverlappingColliders, Collider2D[] overlappingColliders, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + bool doesOverlap = numberOfOverlappingColliders > 0; + DrawOverlapResultPointOfPotMultipleCollisions(doesOverlap, numberOfOverlappingColliders, overlappingColliders, pos_V2, nameTag, durationInSec, hiddenByNearerObjects); + bool shapeIsShrinkedToPoint = true; + float approxSize_ofOverlapVolume = 0.5f; + DrawMarkersAtOverlappingCollidersOfPotMultipleCollisions(shapeIsShrinkedToPoint, pos_V2, doesOverlap, overlappingColliders, numberOfOverlappingColliders, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + } + + static void DrawOverlapResultBoxOfMax1Collision(bool calledAsArea_insteadOfBox, Collider2D overlappingCollider, Vector2 pos_V2, Vector2 size_V2, float angleDegCC, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + bool doesOverlap = overlappingCollider != null; + string text = null; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string additinalWarningText = null; + if (calledAsArea_insteadOfBox == false) + { + bool shapeContainsNegativeDimensions = UtilitiesDXXL_Math.ContainsNegativeComponents(size_V2); + additinalWarningText = shapeContainsNegativeDimensions ? "[ box contains negative dimensions -> potentially collisions missing]
" : null; + } + text = additinalWarningText + GetTextForVolumeOverlapCheckOfMax1Collision(calledAsArea_insteadOfBox ? "Area2D: Overlap check (max 1)" : "Box2D: Overlap check (max 1)", doesOverlap, nameTag, overlappingCollider); + } + DrawOverlapBox(doesOverlap, pos_V2, size_V2, angleDegCC, text, durationInSec, hiddenByNearerObjects); + } + + static void DrawOverlapResultCapsuleOfMax1Collision(Collider2D overlappingCollider, Vector2 pos_V2, Vector2 size_V2, CapsuleDirection2D capsuleDirection, float angleDegCC, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + bool doesOverlap = overlappingCollider != null; + string text = null; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + bool shapeContainsNegativeDimensions = UtilitiesDXXL_Math.ContainsNegativeComponents(size_V2); + string additinalWarningText = shapeContainsNegativeDimensions ? "[ capsule contains negative dimensions -> potentially collisions missing]
" : null; + text = additinalWarningText + GetTextForVolumeOverlapCheckOfMax1Collision("Capsule2D: Overlap check (max 1)", doesOverlap, nameTag, overlappingCollider); + } + DrawOverlapCapsule(doesOverlap, pos_V2, size_V2, capsuleDirection, angleDegCC, text, durationInSec, hiddenByNearerObjects); + } + + static void DrawOverlapResultCircleOfMax1Collision(Collider2D overlappingCollider, Vector2 pos_V2, float radius, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + bool doesOverlap = overlappingCollider != null; + string text = null; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string additinalWarningText = (radius < 0.0f) ? "[ negative circle radius -> collision test only with circle center and/or potentially collisions missing]
" : null; + text = additinalWarningText + GetTextForVolumeOverlapCheckOfMax1Collision("Circle2D: Overlap check (max 1)", doesOverlap, nameTag, overlappingCollider); + } + DrawOverlapCircle(doesOverlap, pos_V2, radius, text, durationInSec, hiddenByNearerObjects); + } + + static void DrawOverlapResultPointOfMax1Collision(Collider2D overlappingCollider, Vector2 pos_V2, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + bool doesOverlap = overlappingCollider != null; + string text = null; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + text = GetTextForVolumeOverlapCheckOfMax1Collision("Point2D: Overlap check (max 1)", doesOverlap, nameTag, overlappingCollider); + } + DrawOverlapPoint(doesOverlap, pos_V2, text, durationInSec, hiddenByNearerObjects); + } + + static void DrawOverlapResultBoxOfPotMultipleCollisions(bool calledAsArea_insteadOfBox, bool doesOverlap, int numberOfOverlappingColliders, Collider2D[] overlappingColliders, Vector2 pos_V2, Vector2 size_V2, float angleDegCC, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + string text = null; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string additinalWarningText = null; + if (calledAsArea_insteadOfBox == false) + { + bool shapeContainsNegativeDimensions = UtilitiesDXXL_Math.ContainsNegativeComponents(size_V2); + additinalWarningText = shapeContainsNegativeDimensions ? "[ box contains negative dimensions -> potentially collisions missing]
" : null; + } + string overlappingCollidersListAsText = GetOverlappingCollidersListAsText(overlappingColliders, numberOfOverlappingColliders); + text = additinalWarningText + GetTextForVolumeOverlapCheckOfPotMultipleCollisions(calledAsArea_insteadOfBox ? "Area2D: Overlap check" : "Box2D: Overlap check", doesOverlap, numberOfOverlappingColliders, nameTag, overlappingCollidersListAsText); + } + DrawOverlapBox(doesOverlap, pos_V2, size_V2, angleDegCC, text, durationInSec, hiddenByNearerObjects); + } + + static void DrawOverlapResultCapsuleOfPotMultipleCollisions(bool doesOverlap, int numberOfOverlappingColliders, Collider2D[] overlappingColliders, Vector2 pos_V2, Vector2 size_V2, CapsuleDirection2D capsuleDirection, float angleDegCC, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + string text = null; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + bool shapeContainsNegativeDimensions = UtilitiesDXXL_Math.ContainsNegativeComponents(size_V2); + string additinalWarningText = shapeContainsNegativeDimensions ? "[ capsule contains negative dimensions -> potentially collisions missing]
" : null; + string overlappingCollidersListAsText = GetOverlappingCollidersListAsText(overlappingColliders, numberOfOverlappingColliders); + text = additinalWarningText + GetTextForVolumeOverlapCheckOfPotMultipleCollisions("Capsule2D: Overlap check", doesOverlap, numberOfOverlappingColliders, nameTag, overlappingCollidersListAsText); + } + DrawOverlapCapsule(doesOverlap, pos_V2, size_V2, capsuleDirection, angleDegCC, text, durationInSec, hiddenByNearerObjects); + } + + static void DrawOverlapResultCircleOfPotMultipleCollisions(bool doesOverlap, int numberOfOverlappingColliders, Collider2D[] overlappingColliders, Vector2 pos_V2, float radius, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + string text = null; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string additinalWarningText = (radius < 0.0f) ? "[ negative circle radius -> collision test only with circle center and/or potentially collisions missing]
" : null; + string overlappingCollidersListAsText = GetOverlappingCollidersListAsText(overlappingColliders, numberOfOverlappingColliders); + text = additinalWarningText + GetTextForVolumeOverlapCheckOfPotMultipleCollisions("Circle2D: Overlap check", doesOverlap, numberOfOverlappingColliders, nameTag, overlappingCollidersListAsText); + } + DrawOverlapCircle(doesOverlap, pos_V2, radius, text, durationInSec, hiddenByNearerObjects); + } + + static void DrawOverlapResultPointOfPotMultipleCollisions(bool doesOverlap, int numberOfOverlappingColliders, Collider2D[] overlappingColliders, Vector2 pos_V2, string nameTag, float durationInSec, bool hiddenByNearerObjects) + { + string text = null; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string overlappingCollidersListAsText = GetOverlappingCollidersListAsText(overlappingColliders, numberOfOverlappingColliders); + text = GetTextForVolumeOverlapCheckOfPotMultipleCollisions("Point2D: Overlap check", doesOverlap, numberOfOverlappingColliders, nameTag, overlappingCollidersListAsText); + } + + UtilitiesDXXL_DrawBasics.Set_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM_reversible(0); + DrawOverlapPoint(doesOverlap, pos_V2, text, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_DrawBasics.Reverse_strokeWidth_forCoordinateTexts_onPointVisualiation_inPPM(); + } + + static string GetOverlappingCollidersListAsText(Collider2D[] overlappingColliders, int numberOfOverlappingColliders) + { + if (overlappingColliders == null) + { + return null; + } + else + { + if (overlappingColliders.Length == 0) + { + return null; + } + else + { + if (numberOfOverlappingColliders <= 0) + { + return null; + } + else + { + string collidersList = null; + for (int i = 0; i < numberOfOverlappingColliders; i++) + { + if (i < DrawPhysics2D.MaxListedColliders_inOverlapVolumesTextList) + { + //collidersList = overlappingColliders[i].GetType().ToString() + " (on GameObject '" + overlappingColliders[i].gameObject.name + "')
" + collidersList; //-> first found collider is on bottom. This contradicts the "DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes"-hitPos-display, which only displays the index-number + collidersList = collidersList + "
" + overlappingColliders[i].GetType().ToString() + " (on GameObject '" + overlappingColliders[i].gameObject.name + "')"; //-> first found collider is on top. This corresponds to the "DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes"-hitPos-display, which only, which only displays the index-number + } + else + { + collidersList = collidersList + "
...and " + (numberOfOverlappingColliders - DrawPhysics2D.MaxListedColliders_inOverlapVolumesTextList) + " more."; + break; + } + } + return collidersList; + } + } + } + } + + static string GetTextForVolumeOverlapCheckOfMax1Collision(string volumeTypeIdentifyingStringPart, bool doesOverlap, string nameTag, Collider2D overlappingCollider) + { + if (nameTag != null && nameTag.Length != 0) + { + //has user specified "nameTag": + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + if (doesOverlap) + { + return (nameTag + "
Overlapping at least with:
" + overlappingCollider.GetType().ToString() + " (on GameObject '" + overlappingCollider.gameObject.name + "')"); + } + else + { + return nameTag; + } + } + else + { + if (doesOverlap) + { + return (nameTag + "
Overlapping at least with this collider:
" + overlappingCollider.GetType().ToString() + " (on GameObject '" + overlappingCollider.gameObject.name + "')"); + } + else + { + return (nameTag + "
Result: Is not overlapping with any collider"); + } + } + } + else + { + //has NO user specified "nameTag": + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + if (doesOverlap) + { + return ("Overlapping at least with:
" + overlappingCollider.GetType().ToString() + " (on GameObject '" + overlappingCollider.gameObject.name + "')"); + } + else + { + return null; + } + } + else + { + if (doesOverlap) + { + return (volumeTypeIdentifyingStringPart + "
Overlapping at least with this collider:
" + overlappingCollider.GetType().ToString() + " (on GameObject '" + overlappingCollider.gameObject.name + "')"); + } + else + { + return (volumeTypeIdentifyingStringPart + "
Result: Is not overlapping with any collider"); + } + } + } + } + + static string GetTextForVolumeOverlapCheckOfPotMultipleCollisions(string volumeTypeIdentifyingStringPart, bool doesOverlap, int numberOfOverlappingColliders, string nameTag, string overlappingCollidersListAsText) + { + if (nameTag != null && nameTag.Length != 0) + { + //has user specified "nameTag": + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + if (doesOverlap) + { + return (nameTag + "
Overlapping with these " + numberOfOverlappingColliders + ":
" + overlappingCollidersListAsText); + } + else + { + return nameTag; + } + } + else + { + if (doesOverlap) + { + return (nameTag + "
Overlapping with these " + numberOfOverlappingColliders + " collider(s):
" + overlappingCollidersListAsText); + } + else + { + return (nameTag + "
Result: Is not overlapping with any collider"); + } + } + } + else + { + //has NO user specified "nameTag": + if (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) + { + if (doesOverlap) + { + return ("Overlapping with these " + numberOfOverlappingColliders + ":
" + overlappingCollidersListAsText); + } + else + { + return null; + } + } + else + { + if (doesOverlap) + { + return (volumeTypeIdentifyingStringPart + "
Overlapping with these " + numberOfOverlappingColliders + " collider(s):
" + overlappingCollidersListAsText); + } + else + { + return (volumeTypeIdentifyingStringPart + "
Result: Is not overlapping with any collider"); + } + } + } + } + + static void DrawOverlapBox(bool doesOverlap, Vector2 pos_V2, Vector2 size_V2, float angleDegCC, string text, float durationInSec, bool hiddenByNearerObjects) + { + Color color = doesOverlap ? DrawPhysics2D.colorForHittingCasts : DrawPhysics2D.colorForNonHittingCasts; + + UtilitiesDXXL_Shapes.Set_bothForcedConstantTextSizes_forTextAtShapes_reversible(DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts, DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts); + DrawShapes.Box2D(pos_V2, size_V2, color, GetZPosForDrawVisualisation(), angleDegCC, DrawShapes.Shape2DType.square, 0.0f, text, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_disable_bothForcedConstantTextSizes_forTextAtShapes(); + } + + static void DrawOverlapCapsule(bool doesOverlap, Vector2 pos_V2, Vector2 size_V2, CapsuleDirection2D capsuleDirection, float angleDegCC, string text, float durationInSec, bool hiddenByNearerObjects) + { + Color color = doesOverlap ? DrawPhysics2D.colorForHittingCasts : DrawPhysics2D.colorForNonHittingCasts; + + UtilitiesDXXL_Shapes.Set_bothForcedConstantTextSizes_forTextAtShapes_reversible(DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts, DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts); + DrawShapes.Capsule2D(pos_V2, size_V2, color, GetZPosForDrawVisualisation(), capsuleDirection, angleDegCC, 0.0f, text, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_disable_bothForcedConstantTextSizes_forTextAtShapes(); + } + + static void DrawOverlapCircle(bool doesOverlap, Vector2 pos_V2, float radius, string text, float durationInSec, bool hiddenByNearerObjects) + { + Color color = doesOverlap ? DrawPhysics2D.colorForHittingCasts : DrawPhysics2D.colorForNonHittingCasts; + + UtilitiesDXXL_Shapes.Set_bothForcedConstantTextSizes_forTextAtShapes_reversible(DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts, DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts); + DrawShapes.Circle2D(pos_V2, radius, color, GetZPosForDrawVisualisation(), 0.0f, text, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, true, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_Shapes.Reverse_disable_bothForcedConstantTextSizes_forTextAtShapes(); + } + + static void DrawOverlapPoint(bool doesOverlap, Vector2 pos_V2, string text, float durationInSec, bool hiddenByNearerObjects) + { + Color color = doesOverlap ? DrawPhysics2D.colorForHittingCasts : DrawPhysics2D.colorForNonHittingCasts; + bool drawCoordsAsText = (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes); + DrawBasics2D.Point(pos_V2, text, color, 0.5f, 0.0f, GetZPosForDrawVisualisation(), color, 0.0f, true, drawCoordsAsText, durationInSec, hiddenByNearerObjects); + } + + static void DrawMarkersAtOverlappingCollidersOfMax1Collision(bool shapeIsShrinkedToPoint, Vector2 posOfCheckingShape_V2, Collider2D overlappingCollider, float approxSize_ofOverlapVolume, float durationInSec, bool hiddenByNearerObjects) + { + bool doesOverlap = overlappingCollider != null; + if (doesOverlap) + { + Color color_ofMarkers = (DrawPhysics2D.colorForHittingCasts.grayscale < 0.175f) ? Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.white, 0.7f) : Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.black, 0.7f); + Color color_ofMarkerExtentionLineToShapeCenter = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawPhysics2D.colorForHittingCasts, 0.2f); + Color color_forDashedLineAlongZ = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawPhysics2D.colorForHittingCasts, 0.6f); + int i_collisionOfPointShrinkedShape = shapeIsShrinkedToPoint ? 0 : (-1); + string shorterFallbackNameText = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) ? "hit" : null; + DrawMarkersAtOverlappingColliders(i_collisionOfPointShrinkedShape, posOfCheckingShape_V2, overlappingCollider, color_ofMarkers, color_ofMarkerExtentionLineToShapeCenter, color_forDashedLineAlongZ, shorterFallbackNameText, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + } + } + + static void DrawMarkersAtOverlappingCollidersOfPotMultipleCollisions(bool shapeIsShrinkedToPoint, Vector2 posOfCheckingShape_V2, bool doesOverlap, Collider2D[] overlappingColliders, int numberOfOverlappingColliders, float approxSize_ofOverlapVolume, float durationInSec, bool hiddenByNearerObjects) + { + if (doesOverlap) + { + Color color_ofMarkers = (DrawPhysics2D.colorForHittingCasts.grayscale < 0.175f) ? Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.white, 0.7f) : Color.Lerp(DrawPhysics2D.colorForHittingCasts, Color.black, 0.7f); + Color color_ofMarkerExtentionLineToShapeCenter = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawPhysics2D.colorForHittingCasts, 0.1f); + Color color_forDashedLineAlongZ = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(DrawPhysics2D.colorForHittingCasts, 0.6f); + numberOfOverlappingColliders = Mathf.Min(numberOfOverlappingColliders, overlappingColliders.Length); + for (int i = 0; i < numberOfOverlappingColliders; i++) + { + string shorterFallbackNameText = null; + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + if ((DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.medium_meaningReducedTextAndSilhouettes) || (i >= DrawPhysics2D.maxOverlapingCollidersWithUntruncatedText)) + { + shorterFallbackNameText = "" + i; + } + } + + int i_collisionOfPointShrinkedShape = shapeIsShrinkedToPoint ? i : (-1); + DrawMarkersAtOverlappingColliders(i_collisionOfPointShrinkedShape, posOfCheckingShape_V2, overlappingColliders[i], color_ofMarkers, color_ofMarkerExtentionLineToShapeCenter, color_forDashedLineAlongZ, shorterFallbackNameText, approxSize_ofOverlapVolume, durationInSec, hiddenByNearerObjects); + } + } + } + + static void DrawMarkersAtOverlappingColliders(int i_collisionOfPointShrinkedShape, Vector2 posOfCheckingShape_V2, Collider2D overlappingCollider, Color color_ofMarkers, Color color_ofMarkerExtentionLineToShapeCenter, Color color_forDashedLineAlongZ, string shorterFallbackNameText, float approxSize_ofOverlapVolume, float durationInSec, bool hiddenByNearerObjects) + { + //thin line from shape center: + Vector2 nearestPosOnCollider_V2 = overlappingCollider.ClosestPoint(posOfCheckingShape_V2); + Line_fadeableAnimSpeed_2D.InternalDraw(posOfCheckingShape_V2, nearestPosOnCollider_V2, color_ofMarkerExtentionLineToShapeCenter, 0.0f, null, DrawBasics.LineStyle.solid, GetZPosForDrawVisualisation(), 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //dashed line along z to collider: + float absZDistance = Mathf.Abs(overlappingCollider.transform.position.z - GetZPosForDrawVisualisation()); + Vector3 nearestPosOnCollider_V3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(nearestPosOnCollider_V2, overlappingCollider.transform.position.z); + Vector3 nearestPosOnCollider_insideDrawXYplane_V3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(nearestPosOnCollider_V2, GetZPosForDrawVisualisation()); + DrawBasics.LineStyle lineStyleAlongZ = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) ? DrawBasics.LineStyle.solid : DrawBasics.LineStyle.dashedLong; + Line_fadeableAnimSpeed.InternalDraw(nearestPosOnCollider_V3, nearestPosOnCollider_insideDrawXYplane_V3, color_forDashedLineAlongZ, 0.0f, null, lineStyleAlongZ, absZDistance, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + //collider marking: + float sizeOfMarkingCross = Mathf.Max(0.1f * approxSize_ofOverlapVolume, 0.001f); + bool drawCoordsAsText = (DrawPhysics2D.visualizationQuality == DrawPhysics.VisualizationQuality.high_withFullDetails); + DrawBasics2D.Point(nearestPosOnCollider_V2, DrawPhysics2D.colorForHittingCasts, sizeOfMarkingCross, 0.0f, 0.0f, null, DrawPhysics2D.colorForHittingCasts, overlappingCollider.transform.position.z, false, drawCoordsAsText, durationInSec, hiddenByNearerObjects); + + if (DrawPhysics2D.visualizationQuality != DrawPhysics.VisualizationQuality.low_withoutAnyTextOrSilhouettes) + { + string text = (shorterFallbackNameText != null) ? shorterFallbackNameText : (overlappingCollider.GetType().ToString() + " (on GameObject '" + overlappingCollider.gameObject.name + "')"); + float textOffsetDistance; + Vector2 textOffsetDir_V2; + float relTextSizeScaling; + if (i_collisionOfPointShrinkedShape < 0) + { + textOffsetDir_V2 = nearestPosOnCollider_V2 - posOfCheckingShape_V2; + textOffsetDistance = 1.0f; + relTextSizeScaling = 1.0f; + } + else + { + Quaternion rotation = Quaternion.AngleAxis(-75.0f - 2.22f * i_collisionOfPointShrinkedShape, Vector3.forward); + textOffsetDir_V2 = rotation * Vector3.right; + textOffsetDistance = 1.0f + 0.2f + i_collisionOfPointShrinkedShape; + relTextSizeScaling = 1.0f / textOffsetDistance; + } + DrawBasics2D.PointTag(nearestPosOnCollider_V2, text, color_ofMarkers, 0.0f, textOffsetDistance, textOffsetDir_V2, overlappingCollider.transform.position.z, relTextSizeScaling, true, durationInSec, hiddenByNearerObjects); + } + } + + static float GetZPosForDrawVisualisation() + { + if (float.IsNaN(DrawPhysics2D.custom_zPos_forCastVisualisation) || float.IsInfinity(DrawPhysics2D.custom_zPos_forCastVisualisation)) + { + return DrawBasics2D.Default_zPos_forDrawing; + + } + else + { + return DrawPhysics2D.custom_zPos_forCastVisualisation; + } + } + + public static bool ExtentNameTagForNonSuitingResultArray(ref string nameTag, int numberOfOverlappingColliders, Collider2D[] resultsArray) + { + bool resultsArrayIsNull = (resultsArray == null); + UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfOverlappingColliders, resultsArrayIsNull, resultsArrayIsNull ? 0 : resultsArray.Length); + return resultsArrayIsNull; + } + + public static bool ExtentNameTagForNonSuitingResultArray(ref string nameTag, int numberOfUsedSlotsInHitInfoArray, RaycastHit2D[] resultsArray) + { + bool resultsArrayIsNull = (resultsArray == null); + UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultArray(ref nameTag, numberOfUsedSlotsInHitInfoArray, resultsArrayIsNull, resultsArrayIsNull ? 0 : resultsArray.Length); + return resultsArrayIsNull; + } + + public static bool ExtentNameTagForNonSuitingResultList(ref string nameTag, int numberOfUsedSlotsInList, List resultsList) + { + bool resultsListIsNull = (resultsList == null); + UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultList(ref nameTag, resultsListIsNull, resultsListIsNull ? 0 : numberOfUsedSlotsInList); + return resultsListIsNull; + } + + public static bool ExtentNameTagForNonSuitingResultList(ref string nameTag, int numberOfUsedSlotsInList, List resultsList) + { + bool resultsListIsNull = (resultsList == null); + UtilitiesDXXL_Physics.ExtentNameTagForNonSuitingResultList(ref nameTag, resultsListIsNull, resultsListIsNull ? 0 : numberOfUsedSlotsInList); + return resultsListIsNull; + } + + public static int CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, List resultsList, int numberOfUsedSlotsInResultsList) + { + if (resultsList != null) + { + preallocatedArrayIsTooSmall = numberOfUsedSlotsInResultsList > preallocatedRayHit2DResultsArray_copiedFromList.Length; + int numberOfCopiedSlots = Mathf.Min(numberOfUsedSlotsInResultsList, preallocatedRayHit2DResultsArray_copiedFromList.Length); + for (int i = 0; i < numberOfCopiedSlots; i++) + { + preallocatedRayHit2DResultsArray_copiedFromList[i] = resultsList[i]; + } + return numberOfCopiedSlots; + } + else + { + preallocatedArrayIsTooSmall = false; + return 0; + } + } + + public static int CopyHitResultsFromListToPreallocatedArray(out bool preallocatedArrayIsTooSmall, List colliderList, int numberOfUsedSlotsInResultsList) + { + if (colliderList != null) + { + preallocatedArrayIsTooSmall = numberOfUsedSlotsInResultsList > preallocatedCollider2DResultsArray_copiedFromList.Length; + int numberOfCopiedSlots = Mathf.Min(numberOfUsedSlotsInResultsList, preallocatedCollider2DResultsArray_copiedFromList.Length); + for (int i = 0; i < numberOfCopiedSlots; i++) + { + preallocatedCollider2DResultsArray_copiedFromList[i] = colliderList[i]; + } + return numberOfCopiedSlots; + } + else + { + preallocatedArrayIsTooSmall = false; + return 0; + } + } + + public static void ExtentNameTagForPreallocatedArrayIsTooSmallForFilledInListResults(bool preallocatedArrayIsTooSmall, ref string nameTag, int numberOfUsedSlotsInResultsList) + { + //"ExtentNameTagForNonSuitingResultList" already cares for this + return; + //if (preallocatedArrayIsTooSmall) + //{ + // int numberOfNotDrawnCollisions = numberOfUsedSlotsInResultsList - DrawPhysics2D.MaxNumberOfPreallocatedHits; + // nameTag = "[ DrawPhysics2D internal result buffer (of " + DrawPhysics2D.MaxNumberOfPreallocatedHits + ") is full
-> " + numberOfNotDrawnCollisions + " results are not drawn
-> Fix by increasing 'DrawPhysics2D.MaxNumberOfPreallocatedHits']
" + nameTag; + //} + } + + public static void Area2D_to_Box2D(out Vector2 boxCenterPos_V2, out Vector2 boxSize_V2, Vector2 areaPointA, Vector2 areaPointB) + { + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(areaPointA, areaPointB)) + { + boxSize_V2 = Vector2.zero; + } + else + { + boxSize_V2 = UtilitiesDXXL_Math.Abs(areaPointB - areaPointA); + } + boxCenterPos_V2 = 0.5f * (areaPointA + areaPointB); + } + + static float scaleFactor_forCastHitTextSize_before; + public static void Set_scaleFactor_forCastHitTextSize_reversible(float new_scaleFactor_forCastHitTextSize) + { + scaleFactor_forCastHitTextSize_before = DrawPhysics2D.scaleFactor_forCastHitTextSize; + DrawPhysics2D.scaleFactor_forCastHitTextSize = new_scaleFactor_forCastHitTextSize; + } + public static void Reverse_scaleFactor_forCastHitTextSize() + { + DrawPhysics2D.scaleFactor_forCastHitTextSize = scaleFactor_forCastHitTextSize_before; + } + + static float castCorridorVisualizerDensity_before; + public static void Set_castCorridorVisualizerDensity_reversible(float new_castCorridorVisualizerDensity) + { + castCorridorVisualizerDensity_before = DrawPhysics2D.castCorridorVisualizerDensity; + DrawPhysics2D.castCorridorVisualizerDensity = new_castCorridorVisualizerDensity; + } + public static void Reverse_castCorridorVisualizerDensity() + { + DrawPhysics2D.castCorridorVisualizerDensity = castCorridorVisualizerDensity_before; + } + + static float forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before; + public static void Set_forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_reversible(float new_forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts) + { + forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before = DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts; + DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = new_forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts; + } + public static void Reverse_forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts() + { + DrawPhysics2D.forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts = forcedConstantScreenspaceTextSize_relToScreenHeight_forOverlapResultTexts_before; + } + + static float forcedConstantWorldspaceTextSize_forOverlapResultTexts_before; + public static void Set_forcedConstantWorldspaceTextSize_forOverlapResultTexts_reversible(float new_forcedConstantWorldspaceTextSize_forOverlapResultTexts) + { + forcedConstantWorldspaceTextSize_forOverlapResultTexts_before = DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts; + DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts = new_forcedConstantWorldspaceTextSize_forOverlapResultTexts; + } + public static void Reverse_forcedConstantWorldspaceTextSize_forOverlapResultTexts() + { + DrawPhysics2D.forcedConstantWorldspaceTextSize_forOverlapResultTexts = forcedConstantWorldspaceTextSize_forOverlapResultTexts_before; + } + + static Vector2 directionOfHitResultText_before; + public static void Set_directionOfHitResultText_reversible(Vector2 new_directionOfHitResultText) + { + directionOfHitResultText_before = DrawPhysics2D.directionOfHitResultText; + DrawPhysics2D.directionOfHitResultText = new_directionOfHitResultText; + } + public static void Reverse_directionOfHitResultText() + { + DrawPhysics2D.directionOfHitResultText = directionOfHitResultText_before; + } + + static Vector3 default_textOffsetDirection_forPointTags_before; + public static void TrySet_default_textOffsetDirection_forPointTags_reversible() + { + if (UtilitiesDXXL_Math.IsDefaultVector(DrawPhysics2D.directionOfHitResultText) == false) + { + default_textOffsetDirection_forPointTags_before = DrawBasics.Default_textOffsetDirection_forPointTags; + DrawBasics.Default_textOffsetDirection_forPointTags = new Vector3(DrawPhysics2D.directionOfHitResultText.x, DrawPhysics2D.directionOfHitResultText.y, 0.0f); + } + } + public static void TryReverse_default_textOffsetDirection_forPointTags() + { + if (UtilitiesDXXL_Math.IsDefaultVector(DrawPhysics2D.directionOfHitResultText) == false) + { + DrawBasics.Default_textOffsetDirection_forPointTags = default_textOffsetDirection_forPointTags_before; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics2D.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics2D.cs.meta new file mode 100644 index 0000000..e804883 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Physics2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 126e8096454f25346b4b303852291b77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Quaternion.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Quaternion.cs new file mode 100644 index 0000000..0411192 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Quaternion.cs @@ -0,0 +1,385 @@ +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(); + } + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Quaternion.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Quaternion.cs.meta new file mode 100644 index 0000000..fae0f77 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Quaternion.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a136853210bcfaf4ca6bbe4d014e6f3f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Screenspace.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Screenspace.cs new file mode 100644 index 0000000..d7d358d --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Screenspace.cs @@ -0,0 +1,906 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_Screenspace + { + public static List vertices_inViewportSpace0to1 = new List(); + public static InternalDXXL_Plane camPlane = new InternalDXXL_Plane(); + + public static Vector2 WorldPos_to_ViewportPos0to1(Camera camera, Vector3 worldPos, bool clampPosBetween0and1) + { + if (camera == null) + { + return default(Vector2); + } + else + { + Vector2 viewportPos_0to1 = camera.WorldToViewportPoint(worldPos); + if (clampPosBetween0and1) + { + return new Vector2(Mathf.Clamp01(viewportPos_0to1.x), Mathf.Clamp01(viewportPos_0to1.y)); + } + else + { + return viewportPos_0to1; + } + } + } + + public static Vector3 ViewportSpacePos_to_WorldPosOnDrawPlane(Camera camera, Vector2 viewportPos0to1, bool clampPosBetween0and1BeforeTransforming) + { + if (clampPosBetween0and1BeforeTransforming) + { + viewportPos0to1 = new Vector2(Mathf.Clamp01(viewportPos0to1.x), Mathf.Clamp01(viewportPos0to1.y)); + } + return camera.ViewportToWorldPoint(new Vector3(viewportPos0to1.x, viewportPos0to1.y, camera.nearClipPlane + DrawScreenspace.drawOffsetBehindCamsNearPlane)); + } + + public static Vector3 ViewportSpacePos_to_WorldPosOnDrawPlane_customClamp(Camera camera, Vector2 viewportPos0to1, float minX, float maxX, float minY, float maxY) + { + viewportPos0to1 = new Vector2(Mathf.Clamp(viewportPos0to1.x, minX, maxX), Mathf.Clamp(viewportPos0to1.y, minY, maxY)); + return camera.ViewportToWorldPoint(new Vector3(viewportPos0to1.x, viewportPos0to1.y, camera.nearClipPlane + DrawScreenspace.drawOffsetBehindCamsNearPlane)); + } + + public static float VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(Camera camera, Vector2 posOnViewportWhereToConvert_0to1, bool clampPosBetween0and1BeforeTransforming, float extentInsideViewport0to1) + { + if (clampPosBetween0and1BeforeTransforming) + { + posOnViewportWhereToConvert_0to1 = new Vector2(Mathf.Clamp01(posOnViewportWhereToConvert_0to1.x), Mathf.Clamp01(posOnViewportWhereToConvert_0to1.y)); + } + float halfExtentInsideViewport = 0.5f * extentInsideViewport0to1; + float nearClipPlane_plus_offset = camera.nearClipPlane + DrawScreenspace.drawOffsetBehindCamsNearPlane; + + //Known issue: + //-> The following three code lines with their "ViewportToWorldPoint()" and ".magnitude" produce in some situations slightly different values, probably due to limited float precision. + //-> When drawing in sceenspace it is sufficient that the screenspace-camera moves or rotates for this error to appear + //-> The error forwards and magnifies till the "UtilitiesDXXL_LineStyles.GetAnimationProgess_for*()"-functions and can lead to jittery animation of Screenspace lines. + + Vector3 highEndWorldPos = camera.ViewportToWorldPoint(new Vector3(posOnViewportWhereToConvert_0to1.x, posOnViewportWhereToConvert_0to1.y + halfExtentInsideViewport, nearClipPlane_plus_offset)); + Vector3 lowEndWorldPos = camera.ViewportToWorldPoint(new Vector3(posOnViewportWhereToConvert_0to1.x, posOnViewportWhereToConvert_0to1.y - halfExtentInsideViewport, nearClipPlane_plus_offset)); + return (highEndWorldPos - lowEndWorldPos).magnitude; + } + + public static float HorizExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(Camera camera, Vector2 posOnViewportWhereToConvert_0to1, bool clampPosBetween0and1BeforeTransforming, float extentInsideViewport0to1) + { + if (clampPosBetween0and1BeforeTransforming) + { + posOnViewportWhereToConvert_0to1 = new Vector2(Mathf.Clamp01(posOnViewportWhereToConvert_0to1.x), Mathf.Clamp01(posOnViewportWhereToConvert_0to1.y)); + } + float halfExtentInsideViewport = 0.5f * extentInsideViewport0to1; + float nearClipPlane_plus_offset = camera.nearClipPlane + DrawScreenspace.drawOffsetBehindCamsNearPlane; + Vector3 rightEndWorldPos = camera.ViewportToWorldPoint(new Vector3(posOnViewportWhereToConvert_0to1.x + halfExtentInsideViewport, posOnViewportWhereToConvert_0to1.y, nearClipPlane_plus_offset)); + Vector3 leftEndWorldPos = camera.ViewportToWorldPoint(new Vector3(posOnViewportWhereToConvert_0to1.x - halfExtentInsideViewport, posOnViewportWhereToConvert_0to1.y, nearClipPlane_plus_offset)); + return (rightEndWorldPos - leftEndWorldPos).magnitude; + } + + public static float Get_vertExtentOfViewport_at_distanceFromCam(Camera camera, float distanceFromCam) + { + if (camera != null) + { + Vector3 lowerScreenCenter_atDistanceFromCam = camera.ViewportToWorldPoint(new Vector3(0.5f, 0.0f, distanceFromCam)); + Vector3 upperScreenCenter_atDistanceFromCam = camera.ViewportToWorldPoint(new Vector3(0.5f, 1.0f, distanceFromCam)); + return (lowerScreenCenter_atDistanceFromCam - upperScreenCenter_atDistanceFromCam).magnitude; + } + else + { + return 1.0f; + } + } + + public static float Get_horizExtentOfViewport_at_distanceFromCam(Camera camera, float distanceFromCam) + { + if (camera != null) + { + Vector3 leftScreenEnd_atDistanceFromCam = camera.ViewportToWorldPoint(new Vector3(0.0f, 0.5f, distanceFromCam)); + Vector3 rightScreenEnd_atDistanceFromCam = camera.ViewportToWorldPoint(new Vector3(1.0f, 0.5f, distanceFromCam)); + return (leftScreenEnd_atDistanceFromCam - rightScreenEnd_atDistanceFromCam).magnitude; + } + else + { + return 1.0f; + } + } + + public static float Get_diagonalExtentOfViewport_at_distanceFromCam(Camera camera, float distanceFromCam) + { + if (camera != null) + { + Vector3 lowLeftScreenCorner_atDistanceFromCam = camera.ViewportToWorldPoint(new Vector3(0.0f, 0.0f, distanceFromCam)); + Vector3 topRightScreenCorner_atDistanceFromCam = camera.ViewportToWorldPoint(new Vector3(1.0f, 1.0f, distanceFromCam)); + return (lowLeftScreenCorner_atDistanceFromCam - topRightScreenCorner_atDistanceFromCam).magnitude; + } + else + { + return 1.0f; + } + } + + public static float WorldSpaceExtent_to_viewportSpaceExtentRelToScreenHeight(Camera camera, Vector3 worldSpacePos_whereWorldSpaceExtentIsMounted, float worldSpaceExtentToConvert) + { + if (camera != null) + { + float half_worldSpaceExtent_asFloat = 0.5f * worldSpaceExtentToConvert; + Vector3 half_worldSpaceExtent_asVector3 = camera.transform.up * half_worldSpaceExtent_asFloat; + Vector3 upperEndOfExtent_inWorldSpace = worldSpacePos_whereWorldSpaceExtentIsMounted + half_worldSpaceExtent_asVector3; + Vector3 lowerEndOfExtent_inWorldSpace = worldSpacePos_whereWorldSpaceExtentIsMounted - half_worldSpaceExtent_asVector3; + Vector2 upperEndOfExtent_inViewportSpace0to1 = WorldPos_to_ViewportPos0to1(camera, upperEndOfExtent_inWorldSpace, false); + Vector2 lowerEndOfExtent_inViewportSpace0to1 = WorldPos_to_ViewportPos0to1(camera, lowerEndOfExtent_inWorldSpace, false); + + //-> the line is always vertical in screenspace, so we can discard the x-component: + return (upperEndOfExtent_inViewportSpace0to1.y - lowerEndOfExtent_inViewportSpace0to1.y); + } + else + { + return 0.0f; + } + } + + public static bool CheckIfViewportIsTooSmall(Camera camera) + { + //Unity behaves like this: + //-> The viewport rect can theoretically be set to sizes where it protrudes the screen. + //-> The inspector shows these rect component values as if the rect protrudes the screen + //-> If a script accesses the camera.rect component values then also the values are returned that protrude the screen + //BUT: + //-> Internally the viewport is clamped to the screen + //-> The actual rendering is done to an other viewport which has been shrinked so it doesn't protrude the screen anymore + //-> The conversion functions like "ViewportToWorldPoint" or "WorldToViewportPoint" work with the "shrinked" viewport rect. + + Rect viewportRect = camera.rect; + + if (viewportRect.x > 0.9975f) + { + Debug.LogError("Camera viewport rect too small (too far right): Draw operation not executed."); + return true; + } + + if (viewportRect.y > 0.9975f) + { + Debug.LogError("Camera viewport rect too small (too high): Draw operation not executed."); + return true; + } + + if (viewportRect.width < 0.0025f) + { + Debug.LogError("Camera viewport rect too small (too small width): Draw operation not executed."); + return true; + } + + if (viewportRect.height < 0.0025f) + { + Debug.LogError("Camera viewport rect too small (too small height): Draw operation not executed."); + return true; + } + + if ((viewportRect.x + viewportRect.width) < 0.0025f) + { + Debug.LogError("Camera viewport rect too small (too far left): Draw operation not executed."); + return true; + } + + if ((viewportRect.y + viewportRect.height) < 0.0025f) + { + Debug.LogError("Camera viewport rect too small (too low): Draw operation not executed."); + return true; + } + + return false; + } + + public static bool GetAutomaticCameraForDrawing(out Camera camera, string nameOfRequestingFunction, bool omitErrors = false) + { + //function returns whether such a "active enabled main camera" exists. + if (DrawScreenspace.defaultCameraForDrawing != null) + { + if (DrawScreenspace.defaultCameraForDrawing.gameObject.activeInHierarchy) + { + if (DrawScreenspace.defaultCameraForDrawing.enabled) + { + camera = DrawScreenspace.defaultCameraForDrawing; + return true; + } + else + { + return Search_theEnabledMainCameraOfTheScene(out camera, nameOfRequestingFunction, omitErrors); + } + } + else + { + return Search_theEnabledMainCameraOfTheScene(out camera, nameOfRequestingFunction, omitErrors); + } + } + else + { + return Search_theEnabledMainCameraOfTheScene(out camera, nameOfRequestingFunction, omitErrors); + } + } + + static Camera[] activeCamerasOfTheScene; + static bool obtainmentOf_sceneViewCam_hasFailed; + static bool obtainmentOf_gameViewCam_hasFailed; + static bool Search_theEnabledMainCameraOfTheScene(out Camera camera, string nameOfRequestingFunction, bool omitErrors) + { + obtainmentOf_sceneViewCam_hasFailed = false; + obtainmentOf_gameViewCam_hasFailed = false; + if (DrawScreenspace.defaultScreenspaceWindowForDrawing == DrawScreenspace.DefaultScreenspaceWindowForDrawing.sceneViewWindow) + { + return Search_theEnabledMainSceneViewCameraOfTheScene(out camera, nameOfRequestingFunction, omitErrors); + } + else + { + return Search_theEnabledMainGameViewCameraOfTheScene(out camera, nameOfRequestingFunction, omitErrors); + } + } + + static bool Search_theEnabledMainSceneViewCameraOfTheScene(out Camera camera, string nameOfRequestingFunction, bool omitErrors) + { +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView == null) + { + return FallbackToSearchingGameViewCam_orRejectDrawingWithLogNotification(out camera, nameOfRequestingFunction, omitErrors); + } + else + { + camera = UnityEditor.SceneView.lastActiveSceneView.camera; + return true; + } +#else + return FallbackToSearchingGameViewCam_orRejectDrawingWithLogNotification(out camera, nameOfRequestingFunction, omitErrors); +#endif + + } + + static bool FallbackToSearchingGameViewCam_orRejectDrawingWithLogNotification(out Camera camera, string nameOfRequestingFunction, bool omitErrors) + { + obtainmentOf_sceneViewCam_hasFailed = true; + if (obtainmentOf_gameViewCam_hasFailed) + { + return RejectDrawing_andNotifyUserThatThereIsNoCamera(out camera, nameOfRequestingFunction, omitErrors); + } + else + { + return Search_theEnabledMainGameViewCameraOfTheScene(out camera, nameOfRequestingFunction, omitErrors); + } + } + + static bool Search_theEnabledMainGameViewCameraOfTheScene(out Camera camera, string nameOfRequestingFunction, bool omitErrors) + { + Camera cameraMain_cached = Camera.main; //"Camera.main" is slow prior to Unity 2020.2 + if (cameraMain_cached != null) + { + camera = cameraMain_cached; + return true; + } + else + { + if (Camera.allCamerasCount > 0) + { + camera = Camera.allCameras[0]; + return true; + } + else + { + //"FindObjectsOfType()" doesn't return the camera if the gameObject (or any parent) is deactivated, but it does return the camera if only the camera component is disabled. + activeCamerasOfTheScene = UnityEngine.Object.FindObjectsOfType(); + if (activeCamerasOfTheScene == null) + { + return FallbackToSearchingSceneViewCam_orRejectDrawingWithLogNotification(out camera, nameOfRequestingFunction, omitErrors); + } + else + { + if (activeCamerasOfTheScene.Length == 0) + { + return FallbackToSearchingSceneViewCam_orRejectDrawingWithLogNotification(out camera, nameOfRequestingFunction, omitErrors); + } + else + { + for (int i = 0; i < activeCamerasOfTheScene.Length; i++) + { + if (activeCamerasOfTheScene[i] != null) + { + if (activeCamerasOfTheScene[i].gameObject.activeInHierarchy) + { + if (activeCamerasOfTheScene[i].enabled) + { + camera = activeCamerasOfTheScene[i]; + return true; + } + } + } + } + return FallbackToSearchingSceneViewCam_orRejectDrawingWithLogNotification(out camera, nameOfRequestingFunction, omitErrors); + } + } + } + } + } + + static bool FallbackToSearchingSceneViewCam_orRejectDrawingWithLogNotification(out Camera camera, string nameOfRequestingFunction, bool omitErrors) + { + obtainmentOf_gameViewCam_hasFailed = true; + if (obtainmentOf_sceneViewCam_hasFailed) + { + return RejectDrawing_andNotifyUserThatThereIsNoCamera(out camera, nameOfRequestingFunction, omitErrors); + } + else + { + return Search_theEnabledMainSceneViewCameraOfTheScene(out camera, nameOfRequestingFunction, omitErrors); + } + } + + static bool RejectDrawing_andNotifyUserThatThereIsNoCamera(out Camera camera, string nameOfRequestingFunction, bool omitErrors) + { + if (omitErrors == false) + { + if (nameOfRequestingFunction == null) + { + Debug.LogError("Draw XXL: Cannot draw because there is no active camera in the scene."); + } + else + { + Debug.LogError("Draw XXL: " + nameOfRequestingFunction + "() cannot draw because there is no active camera in the scene."); + } + } + camera = null; + return false; + } + + public static bool HasDefaultViewPortRect(Camera camera) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(camera.rect.x)) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(camera.rect.y)) + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(camera.rect.width, 1.0f)) + { + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(camera.rect.height, 1.0f)) + { + return true; + } + } + } + } + return false; + } + + public static float animationSpeedConversionFactor_viewportToWorldSpace = 0.25f; + static InternalDXXL_LineParamsFromCamViewportSpace lineParams = new InternalDXXL_LineParamsFromCamViewportSpace(); + public static InternalDXXL_LineParamsFromCamViewportSpace GetLineParamsFromCamViewportSpace(Camera camera, Vector2 start, Vector2 end, float width_relToViewportHeight, DrawBasics.LineStyle style, float stylePatternScaleFactor, float enlargeSmallTextToThisMinRelTextSize, float animationSpeed_viewportSpace, float endPlatesSize_relToViewportHeight) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return null; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_relToViewportHeight, "width_relToViewportHeight")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stylePatternScaleFactor, "stylePatternScaleFactor")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(enlargeSmallTextToThisMinRelTextSize, "enlargeSmallTextToThisMinRelTextSize")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(animationSpeed_viewportSpace, "animationSpeed_viewportSpace")) { return null; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + + //DO NOT fallback to "PointScreenSpace()" in case of "line with zero lenght", because "PointScreenSpace()" calls "LineScreenSpace()" again, which can create an endless loop. + + lineParams.startAnchor_worldSpace = ViewportSpacePos_to_WorldPosOnDrawPlane(camera, start, false); + lineParams.endAnchor_worldSpace = ViewportSpacePos_to_WorldPosOnDrawPlane(camera, end, false); + Vector2 middleV2 = 0.5f * (start + end); + Vector2 middleV2_clamped01 = new Vector2(Mathf.Clamp01(middleV2.x), Mathf.Clamp01(middleV2.y)); + + if (UtilitiesDXXL_Math.ApproximatelyZero(width_relToViewportHeight)) + { + lineParams.width_worldSpace = 0.0f; + } + else + { + lineParams.width_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, middleV2_clamped01, false, width_relToViewportHeight); + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(enlargeSmallTextToThisMinRelTextSize)) + { + lineParams.enlargeSmallTextToThisMinTextSize_worldSpace = 0.0f; + } + else + { + lineParams.enlargeSmallTextToThisMinTextSize_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, middleV2_clamped01, false, enlargeSmallTextToThisMinRelTextSize); + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(endPlatesSize_relToViewportHeight)) + { + lineParams.endPlatesSize_inAbsoluteWorldSpaceUnits = 0.0f; + } + else + { + lineParams.endPlatesSize_inAbsoluteWorldSpaceUnits = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, middleV2_clamped01, false, endPlatesSize_relToViewportHeight); + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(animationSpeed_viewportSpace)) + { + lineParams.animationSpeed_worldSpace = 0.0f; + } + else + { + float animationDirection = Mathf.Sign(animationSpeed_viewportSpace); + animationSpeed_viewportSpace = animationSpeedConversionFactor_viewportToWorldSpace * animationSpeed_viewportSpace; + lineParams.animationSpeed_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, middleV2_clamped01, false, animationSpeed_viewportSpace); + lineParams.animationSpeed_worldSpace = animationDirection * lineParams.animationSpeed_worldSpace; + } + + lineParams.lineStyleForcedTo2D = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(style); + lineParams.patternScaleFactor_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, middleV2_clamped01, false, stylePatternScaleFactor); + lineParams.patternScaleFactor_worldSpace = Mathf.Max(lineParams.patternScaleFactor_worldSpace, UtilitiesDXXL_LineStyles.minStylePatternScaleFactor); + lineParams.camPlane.Recreate(camera.transform.position, camera.transform.forward); + + return lineParams; + } + + public static void DrawShape(Camera camera, Vector2 centerPosition, DrawShapes.Shape2DType baseShape, Color colorForShape, Color colorForText, float width_relToViewportHeight, float height_relToViewportHeight, float zRotationDeg, float linesWidth_relToViewportHeight, string text, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool drawPointerIfOffscreen, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec, float relTextSizeScaling, string headerText, bool drawHullEdgeLines_forScreenEncasingShapes) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + if (CheckIfViewportIsTooSmall(camera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_relToViewportHeight, "width_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height_relToViewportHeight, "height_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zRotationDeg, "zRotationDeg")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth_relToViewportHeight, "linesWidth_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stylePatternScaleFactor, "stylePatternScaleFactor")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerPosition, "centerPosition")) { return; } + + linesWidth_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth_relToViewportHeight); + if (UtilitiesDXXL_Math.ApproximatelyZero(height_relToViewportHeight) && UtilitiesDXXL_Math.ApproximatelyZero(width_relToViewportHeight)) + { + PointFallback(camera, centerPosition, "[ ShapeScreenspace with extent of 0]
" + text, colorForShape, linesWidth_relToViewportHeight, durationInSec); + return; + } + + lineStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(lineStyle); + Vector3 centerPosition_worldSpace = ViewportSpacePos_to_WorldPosOnDrawPlane(camera, centerPosition, false); + float width_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, width_relToViewportHeight); + float height_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, height_relToViewportHeight); + float patternScaleFactor_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, stylePatternScaleFactor); + float linesWidth_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(linesWidth_relToViewportHeight) == false) + { + linesWidth_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, linesWidth_relToViewportHeight); + } + + Vector3 up_worldSpace_normalized = camera.transform.up; + if (UtilitiesDXXL_Math.ApproximatelyZero(zRotationDeg) == false) + { + Quaternion rotation = Quaternion.AngleAxis(zRotationDeg, camera.transform.forward); + up_worldSpace_normalized = rotation * camera.transform.up; + } + + int usedSlotsIn_verticesGlobal = DrawShapes.FlatShape(centerPosition_worldSpace, baseShape, width_worldSpace, height_worldSpace, colorForShape, camera.transform.forward, up_worldSpace_normalized, linesWidth_worldSpace, null, lineStyle, patternScaleFactor_worldSpace, true, DrawBasics.LineStyle.invisible, false, durationInSec, false); + if (usedSlotsIn_verticesGlobal <= 0) + { + UtilitiesDXXL_Log.PrintErrorCode("27-" + usedSlotsIn_verticesGlobal); + return; + } + + if (fillStyle != DrawBasics.LineStyle.invisible) + { + fillStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(fillStyle); + camPlane.Recreate(centerPosition_worldSpace, camera.transform.forward); + float distanceBetweenLines_viewportSpace = 0.01f; + float distanceBetweenLines_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, distanceBetweenLines_viewportSpace); + UtilitiesDXXL_Shapes.DrawShapeFilling(baseShape, fillStyle, usedSlotsIn_verticesGlobal, distanceBetweenLines_worldSpace, colorForShape, up_worldSpace_normalized, patternScaleFactor_worldSpace, camPlane, durationInSec, false); + } + + if (drawPointerIfOffscreen || (text != null && text != "") || (headerText != null && headerText != "")) + { + for (int i = 0; i < usedSlotsIn_verticesGlobal; i++) + { + UtilitiesDXXL_List.AddToAVector2List(ref vertices_inViewportSpace0to1, WorldPos_to_ViewportPos0to1(camera, UtilitiesDXXL_Shapes.verticesGlobal[i], false), i); + } + TagPointCollection(camera, text, headerText, usedSlotsIn_verticesGlobal, 0.3f * linesWidth_relToViewportHeight, colorForShape, colorForText, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, durationInSec, relTextSizeScaling, drawHullEdgeLines_forScreenEncasingShapes); + } + + } + + public static void Capsule(Camera camera, Vector2 posOfCircle1, Vector2 posOfCircle2, float radius_relToViewportHeight, Color color, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + if (CheckIfViewportIsTooSmall(camera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_relToViewportHeight, "radius_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth_relToViewportHeight, "linesWidth_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stylePatternScaleFactor, "stylePatternScaleFactor")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(posOfCircle1, "posOfCircle1")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(posOfCircle2, "posOfCircle2")) { return; } + + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(posOfCircle1, posOfCircle2) && UtilitiesDXXL_Math.ApproximatelyZero(radius_relToViewportHeight)) + { + PointFallback(camera, posOfCircle1, "[ CapsuleScreenspace with extent of 0]
" + text, color, linesWidth_relToViewportHeight, durationInSec); + return; + } + + Vector2 centerPosition = 0.5f * (posOfCircle1 + posOfCircle2); + Vector3 posOfCircle1_worldSpace = ViewportSpacePos_to_WorldPosOnDrawPlane(camera, posOfCircle1, false); + Vector3 posOfCircle2_worldSpace = ViewportSpacePos_to_WorldPosOnDrawPlane(camera, posOfCircle2, false); + float patternScaleFactor_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, stylePatternScaleFactor); + + float radius_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(radius_relToViewportHeight) == false) + { + radius_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, radius_relToViewportHeight); + } + + float lineWidth_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(linesWidth_relToViewportHeight) == false) + { + lineWidth_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, linesWidth_relToViewportHeight); + } + + lineStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(lineStyle); + fillStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(fillStyle); + float distanceBetweenFillLines_viewportSpace = 0.01f; + float distanceBetweenFillLines_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, distanceBetweenFillLines_viewportSpace); + int usedSlotsIn_verticesGlobal = UtilitiesDXXL_Shapes.FlatCapsule(posOfCircle1_worldSpace, posOfCircle2_worldSpace, radius_worldSpace, color, camera.transform.forward, lineWidth_worldSpace, null, lineStyle, patternScaleFactor_worldSpace, fillStyle, false, false, durationInSec, false, distanceBetweenFillLines_worldSpace, camera.transform.up); + DrawTextAtCapsule(camera, drawPointerIfOffscreen, text, usedSlotsIn_verticesGlobal, linesWidth_relToViewportHeight, color, addTextForOutsideDistance_toOffscreenPointer, durationInSec, true); + } + + public static void Capsule(Camera camera, Vector2 centerPosition, Vector2 size_relToViewportHeight, Color color, CapsuleDirection2D capsuleDirection, float zRotationDeg, float linesWidth_relToViewportHeight, string text, bool drawPointerIfOffscreen, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec, bool drawHullEdgeLines_forScreenEncasingShapes) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + if (CheckIfViewportIsTooSmall(camera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zRotationDeg, "zRotationDeg")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth_relToViewportHeight, "linesWidth_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stylePatternScaleFactor, "stylePatternScaleFactor")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerPosition, "centerPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(size_relToViewportHeight, "size_relToViewportHeight")) { return; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(size_relToViewportHeight)) + { + PointFallback(camera, centerPosition, "[ CapsuleScreenspace with extent of 0]
" + text, color, linesWidth_relToViewportHeight, durationInSec); + return; + } + + Vector3 centerPosition_worldSpace = ViewportSpacePos_to_WorldPosOnDrawPlane(camera, centerPosition, false); + float patternScaleFactor_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, stylePatternScaleFactor); + + float width_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(size_relToViewportHeight.x) == false) + { + width_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, size_relToViewportHeight.x); + } + + float height_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(size_relToViewportHeight.y) == false) + { + height_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, size_relToViewportHeight.y); + } + + float lineWidth_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(linesWidth_relToViewportHeight) == false) + { + lineWidth_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, linesWidth_relToViewportHeight); + } + + Vector3 upAlongVertInsideCapsulePlane_worldSpace = camera.transform.up; + if (UtilitiesDXXL_Math.ApproximatelyZero(zRotationDeg) == false) + { + Quaternion rotation = Quaternion.AngleAxis(zRotationDeg, camera.transform.forward); + upAlongVertInsideCapsulePlane_worldSpace = rotation * camera.transform.up; + } + + lineStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(lineStyle); + fillStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(fillStyle); + float distanceBetweenFillLines_viewportSpace = 0.01f; + float distanceBetweenFillLines_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, centerPosition, true, distanceBetweenFillLines_viewportSpace); + int usedSlotsIn_verticesGlobal = UtilitiesDXXL_Shapes.FlatCapsule(centerPosition_worldSpace, width_worldSpace, height_worldSpace, color, camera.transform.forward, upAlongVertInsideCapsulePlane_worldSpace, capsuleDirection, lineWidth_worldSpace, null, lineStyle, patternScaleFactor_worldSpace, fillStyle, false, false, durationInSec, false, distanceBetweenFillLines_worldSpace); + DrawTextAtCapsule(camera, drawPointerIfOffscreen, text, usedSlotsIn_verticesGlobal, linesWidth_relToViewportHeight, color, addTextForOutsideDistance_toOffscreenPointer, durationInSec, drawHullEdgeLines_forScreenEncasingShapes); + } + + static void DrawTextAtCapsule(Camera camera, bool drawPointerIfOffscreen, string text, int usedSlotsIn_verticesGlobal, float linesWidth_relToViewportHeight, Color color, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec, bool drawHullEdgeLines_forScreenEncasingShapes) + { + if (usedSlotsIn_verticesGlobal > 1) //-> preceding Draw.FlatCapsule-Call didn't return with abortDueToError + { + if (drawPointerIfOffscreen || (text != null && text != "")) + { + for (int i = 0; i < usedSlotsIn_verticesGlobal; i++) + { + UtilitiesDXXL_List.AddToAVector2List(ref vertices_inViewportSpace0to1, WorldPos_to_ViewportPos0to1(camera, UtilitiesDXXL_Shapes.verticesGlobal[i], false), i); + } + TagPointCollection(camera, text, null, usedSlotsIn_verticesGlobal, 0.3f * linesWidth_relToViewportHeight, color, color, drawPointerIfOffscreen, addTextForOutsideDistance_toOffscreenPointer, durationInSec, 1.0f, drawHullEdgeLines_forScreenEncasingShapes); + } + } + } + + public static void PointFallback(Camera camera, Vector2 position, string text = null, Color color = default(Color), float markingCrossLinesWidth_relToViewportHeight = 0.0f, float durationInSec = 0.0f) + { + DrawScreenspace.Point(camera, position, text, color, 0.1f, markingCrossLinesWidth_relToViewportHeight, 0.0f, false, true, true, true, durationInSec); + } + + static InternalDXXL_BoundsCamViewportSpace boundsViewportSpace = new InternalDXXL_BoundsCamViewportSpace(); + public static void TagPointCollection(Camera camera, string text, string headerText, int usedSlotsInVerticesViewportSpaceList, float linesWidth_relToViewportHeight, Color colorForLinesAndHeader, Color colorForText, bool drawPointerIfOffscreen, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec, float relTextSizeScaling, bool drawHullEdgeLines_forScreenEncasingShapes) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (usedSlotsInVerticesViewportSpaceList <= 0) + { + UtilitiesDXXL_Log.PrintErrorCode("30-" + usedSlotsInVerticesViewportSpaceList); + return; + } + + if (drawPointerIfOffscreen || (text != null && text != "") || (headerText != null && headerText != "")) + { + boundsViewportSpace.Recreate(vertices_inViewportSpace0to1[0], Vector2.zero); + for (int i = 1; i < usedSlotsInVerticesViewportSpaceList; i++) + { + boundsViewportSpace.Encapsulate(vertices_inViewportSpace0to1[i]); + } + + Vector2 taggedPos; + if (boundsViewportSpace.IsCompletelyInsideViewport()) + { + // Vector2 camCenterNearestBoundsCorner = boundsViewportSpace.GetNearestCorner(InternalDXXL_BoundsCamViewportSpace.viewportCenter); //-> makes the textPos flicker in common cases where symetrical verticesCenterPos is on a viewport0.5-axis + Vector2 camCenterNearestBoundsCorner = boundsViewportSpace.GetNearestCorner(new Vector2(0.51f, 0.51f)); //-> prevent textPos-flicker of common case where symetrical verticesCenterPos is on a viewport0.5-axis + taggedPos = UtilitiesDXXL_Math.GetNearestVertex(camCenterNearestBoundsCorner, vertices_inViewportSpace0to1, usedSlotsInVerticesViewportSpaceList); + } + else + { + if ((boundsViewportSpace.HasCornerInsideViewport() == false) && boundsViewportSpace.HasEdgePartInsideViewport()) + { + taggedPos = boundsViewportSpace.GetPosOnMostCenteredViewportCrossingEdge(0.55f); + if (drawHullEdgeLines_forScreenEncasingShapes) + { + boundsViewportSpace.DrawViewportCrossingEdges(camera, colorForLinesAndHeader, linesWidth_relToViewportHeight, durationInSec); + } + } + else + { + if (boundsViewportSpace.CompletelyEncapsulatesViewport()) + { + // taggedPos = InternalDXXL_BoundsCamViewportSpace.GetViewportCenterPlumbIntersectionWithViewportBorderShifted(boundsViewportSpace.center, -0.01f); //-> makes the textPos flicker in common cases where symetrical verticesCenterPos is on a viewport0.5-axis + taggedPos = InternalDXXL_BoundsCamViewportSpace.GetViewportCenterPlumbIntersectionWithViewportBorderShifted(boundsViewportSpace.center + new Vector2(0.01f, 0.01f), -0.01f);//-> prevent textPos-flicker of common case where symetrical verticesCenterPos is on a viewport0.5-axis + if (drawHullEdgeLines_forScreenEncasingShapes) + { + InternalDXXL_BoundsCamViewportSpace.DrawViewportBorder(camera, colorForLinesAndHeader, linesWidth_relToViewportHeight, 0.01f, durationInSec); + } + } + else + { + //"hasCornerInsideViewport" or "completelyOutsideViewport" + // taggedPos = DSU_Math.GetNearestVertex(InternalDXXL_BoundsCamViewportSpace.viewportCenter, vertices_inViewportSpace0to1, usedSlotsInVerticesViewportSpaceList); //-> makes the textPos flicker in common cases where symetrical verticesCenterPos is on a viewport0.5-axis + taggedPos = UtilitiesDXXL_Math.GetNearestVertex(new Vector2(0.51f, 0.51f), vertices_inViewportSpace0to1, usedSlotsInVerticesViewportSpaceList); //-> prevent textPos-flicker of common case where symetrical verticesCenterPos is on a viewport0.5-axis + } + } + } + + bool taggedPosIsOutsideOfViewport = InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportExclBorder(taggedPos); + bool forcePointerDueToOffscreen = (taggedPosIsOutsideOfViewport && drawPointerIfOffscreen); + if (forcePointerDueToOffscreen || (text != null && text != "") || (headerText != null && headerText != "")) + { + bool withPointer = taggedPosIsOutsideOfViewport; + PointTag(camera, taggedPos, text, headerText, colorForLinesAndHeader, colorForText, drawPointerIfOffscreen, linesWidth_relToViewportHeight, 0.2f, default(Vector2), relTextSizeScaling, !withPointer, addTextForOutsideDistance_toOffscreenPointer, durationInSec); + } + } + } + + public static void PointTag(Camera camera, Vector2 position, string text, string titleText, Color colorForLinesAndTitle, Color colorForText, bool drawPointerIfOffscreen, float linesWidth_relToViewportHeight, float size_asTextOffsetDistance_relToViewportHeight, Vector2 textOffsetDirection, float textSizeScaleFactor, bool skipConeDrawing, bool addTextForOutsideDistance_toOffscreenPointer, float durationInSec, Vector2 customTowardsPoint_ofDefaultTextOffsetDirection = default(Vector2)) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + if (CheckIfViewportIsTooSmall(camera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth_relToViewportHeight, "linesWidth_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size_asTextOffsetDistance_relToViewportHeight, "size_asTextOffsetDistance_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(textSizeScaleFactor, "textSizeScaleFactor")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textOffsetDirection, "textOffsetDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(customTowardsPoint_ofDefaultTextOffsetDirection, "customTowardsPoint_ofDefaultTextOffsetDirection")) { return; } + + //DO NOT fallback to "PointScreenSpace()" here, because "PointScreenSpace()" calls "PointTagScreenSpace()" again, which can create an endless loop. + + if (drawPointerIfOffscreen == false) + { + if (InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportWithPadding(position, 1.5f)) + { + return; + } + } + + colorForLinesAndTitle = UtilitiesDXXL_Colors.OverwriteDefaultColor(colorForLinesAndTitle); + colorForText = UtilitiesDXXL_Colors.OverwriteDefaultColor(colorForText); + Vector2 position_viewportSpace = position; + UtilitiesDXXL_Math.SkewedDirection quadrant = GetQuadrant(position_viewportSpace); + bool customTextOffsetDir; + Vector2 textOffsetDir_viewportSpace; + if (UtilitiesDXXL_Math.IsDefaultVector(textOffsetDirection)) + { + Vector2 towardsPoint_ofDefaultTextOffsetDir = UtilitiesDXXL_Math.OverwriteDefaultVectors(customTowardsPoint_ofDefaultTextOffsetDirection, InternalDXXL_BoundsCamViewportSpace.viewportCenter); + textOffsetDir_viewportSpace = towardsPoint_ofDefaultTextOffsetDir - position_viewportSpace; + if (UtilitiesDXXL_Math.ApproximatelyZero(textOffsetDir_viewportSpace)) + { + textOffsetDir_viewportSpace = new Vector2(0.5f, 1.0f); + } + customTextOffsetDir = false; + } + else + { + textOffsetDir_viewportSpace = textOffsetDirection; + customTextOffsetDir = true; + } + + linesWidth_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth_relToViewportHeight); + float lineWidth_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(linesWidth_relToViewportHeight) == false) + { + lineWidth_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, position_viewportSpace, true, linesWidth_relToViewportHeight); + } + + size_asTextOffsetDistance_relToViewportHeight = Mathf.Abs(size_asTextOffsetDistance_relToViewportHeight); + size_asTextOffsetDistance_relToViewportHeight = UtilitiesDXXL_Math.Max(size_asTextOffsetDistance_relToViewportHeight, 3.0f * linesWidth_relToViewportHeight, 0.035f); + float textOffsetDistance_worldSpace = VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, position_viewportSpace, true, size_asTextOffsetDistance_relToViewportHeight); + textSizeScaleFactor = Mathf.Abs(textSizeScaleFactor); + textSizeScaleFactor = Mathf.Max(textSizeScaleFactor, 0.01f); + + Vector3 postion_worldSpace = ViewportSpacePos_to_WorldPosOnDrawPlane(camera, position_viewportSpace, false); + Vector3 aPosTowardsTextStartPos_worldSpace = ViewportSpacePos_to_WorldPosOnDrawPlane(camera, position_viewportSpace + textOffsetDir_viewportSpace, false); + Vector3 textOffsetDir_worldSpace = aPosTowardsTextStartPos_worldSpace - postion_worldSpace; + Vector3 textOffsetDir_worldSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(textOffsetDir_worldSpace); + Vector3 pos_to_startOfUnderLine_worldSpace = textOffsetDir_worldSpace_normalized * textOffsetDistance_worldSpace; + + float coneHeight_worldSpace = 0.2f * textOffsetDistance_worldSpace; + coneHeight_worldSpace = Mathf.Max(coneHeight_worldSpace, 2.4f * lineWidth_worldSpace); + + if (drawPointerIfOffscreen) + { + if (InternalDXXL_BoundsCamViewportSpace.IsInsideViewportExclBorder(position_viewportSpace) == false) + { + skipConeDrawing = false; + if (addTextForOutsideDistance_toOffscreenPointer) + { + Vector2 projectionOntoScreenBorder = InternalDXXL_BoundsCamViewportSpace.ClampIntoViewport(position_viewportSpace); + float distance = (position_viewportSpace - projectionOntoScreenBorder).magnitude; + + if (text != null && text != "") + { + text = "[distance = " + distance.ToString("F2") + "]
" + text; + } + else + { + text = "[distance = " + distance.ToString("F2") + "]"; + } + } + } + + float maxOutsideScreen0to1 = customTextOffsetDir ? (-0.1f * coneHeight_worldSpace) : 0.3f * coneHeight_worldSpace; + postion_worldSpace = ViewportSpacePos_to_WorldPosOnDrawPlane_customClamp(camera, position_viewportSpace, -maxOutsideScreen0to1, 1.0f + maxOutsideScreen0to1, -maxOutsideScreen0to1, 1.0f + maxOutsideScreen0to1); + } + + Vector3 startOfTextUnderline_worldSpace = postion_worldSpace + pos_to_startOfUnderLine_worldSpace; + Vector2 startOfTextUnderline_viewportSpace = WorldPos_to_ViewportPos0to1(camera, startOfTextUnderline_worldSpace, false); + + if (skipConeDrawing) + { + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, position_viewportSpace, startOfTextUnderline_viewportSpace, colorForLinesAndTitle, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + else + { + float offsetDistance_forStartAnchorOfLineToText_worldSpace = (3.0f * lineWidth_worldSpace); + offsetDistance_forStartAnchorOfLineToText_worldSpace = Mathf.Min(offsetDistance_forStartAnchorOfLineToText_worldSpace, coneHeight_worldSpace); + Vector3 offsettedStartAnchor_ofLineToText_worldSpace = postion_worldSpace + textOffsetDir_worldSpace_normalized * offsetDistance_forStartAnchorOfLineToText_worldSpace; + Vector2 offsettedStartAnchor_ofLineToText_viewportSpace = WorldPos_to_ViewportPos0to1(camera, offsettedStartAnchor_ofLineToText_worldSpace, false); + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, offsettedStartAnchor_ofLineToText_viewportSpace, startOfTextUnderline_viewportSpace, colorForLinesAndTitle, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + } + + float underlineLength_viewportSpace = 0.2f * size_asTextOffsetDistance_relToViewportHeight; + float textSize_relToViewportHeight = UtilitiesDXXL_DrawBasics.pointTagsTextSize_relToOffset * textSizeScaleFactor * size_asTextOffsetDistance_relToViewportHeight; + Vector2 textPosition_viewportSpace = startOfTextUnderline_viewportSpace + Vector2.up * (0.3f * textSize_relToViewportHeight + 0.5f * linesWidth_relToViewportHeight); + textSize_relToViewportHeight = Mathf.Max(textSize_relToViewportHeight, DrawScreenspace.minTextSize_relToViewportHeight); + if (text != null && text != "") + { + DrawText.TextAnchorDXXL textAnchor = GetTextAnchor(quadrant); + UtilitiesDXXL_Text.WriteScreenspace(camera, text, textPosition_viewportSpace, colorForText, textSize_relToViewportHeight, 0.0f, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, false, durationInSec, false); + float lengthOfLongestLine_inText_viewportSpace = DrawText.parsedTextSpecs.widthOfLongestLine; + underlineLength_viewportSpace = Mathf.Max(underlineLength_viewportSpace, lengthOfLongestLine_inText_viewportSpace); + } + + if (titleText != null && titleText != "") + { + //-> no strokeWidth-markup: trading execution time and code readability for GC.Alloc()-prevention: + // Color titleTextColor = DSU_Colors.Get_color_darkenedFromGivenColor(colorForLinesAndTitle, 1.3f); + DrawText.TextAnchorDXXL titleTextAnchor = GetTitleTextAnchor(quadrant); + Vector2 offsetForDoubledPrint_viewportSpace = camera.transform.right * textSize_relToViewportHeight * 0.11f; + Vector2 offsetForTripledPrint_viewportSpace = camera.transform.right * textSize_relToViewportHeight * 0.055f + camera.transform.up * textSize_relToViewportHeight * 0.08f; + UtilitiesDXXL_Text.WriteScreenspace(camera, titleText, textPosition_viewportSpace, colorForLinesAndTitle, textSize_relToViewportHeight, 0.0f, titleTextAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, false, durationInSec, false); + float lengthOfLongestLine_inTitleText_viewportSpace = DrawText.parsedTextSpecs.widthOfLongestLine; + UtilitiesDXXL_Text.WriteScreenspace(camera, titleText, textPosition_viewportSpace + offsetForDoubledPrint_viewportSpace, colorForLinesAndTitle, textSize_relToViewportHeight, 0.0f, titleTextAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, false, durationInSec, false); + UtilitiesDXXL_Text.WriteScreenspace(camera, titleText, textPosition_viewportSpace + offsetForTripledPrint_viewportSpace, colorForLinesAndTitle, textSize_relToViewportHeight, 0.0f, titleTextAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, false, durationInSec, false); + underlineLength_viewportSpace = Mathf.Max(underlineLength_viewportSpace, lengthOfLongestLine_inTitleText_viewportSpace); + } + + Vector2 textDir_viewportSpace_normalized = (quadrant == UtilitiesDXXL_Math.SkewedDirection.upLeft || quadrant == UtilitiesDXXL_Math.SkewedDirection.downLeft) ? Vector2.right : Vector2.left; + Line_fadeableAnimSpeed_screenspace.InternalDraw(camera, startOfTextUnderline_viewportSpace, startOfTextUnderline_viewportSpace + textDir_viewportSpace_normalized * underlineLength_viewportSpace, colorForLinesAndTitle, linesWidth_relToViewportHeight, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, 0.0f, 0.0f, 0.0f, durationInSec); + + if (skipConeDrawing == false) + { + float coneAngleDeg = 25.0f; + Vector3 upVector_ofConeBaseRect = camera.transform.forward; + DrawShapes.ConeFilled(postion_worldSpace, coneHeight_worldSpace, pos_to_startOfUnderLine_worldSpace, upVector_ofConeBaseRect, 0.0f, coneAngleDeg, colorForLinesAndTitle, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, false); + } + } + + static UtilitiesDXXL_Math.SkewedDirection GetQuadrant(Vector2 position_viewportSpace) + { + //float viewportCenter_1D = 0.5f; //-> makes the textPos flicker in common cases where the taggedPosition is on a viewport0.5-axis + float viewportCenter_1D = 0.505f; //-> prevent textPos-flicker of common case where the taggedPosition is on a viewport0.5-axis + + if (position_viewportSpace.x <= viewportCenter_1D) + { + if (position_viewportSpace.y < viewportCenter_1D) + { + return UtilitiesDXXL_Math.SkewedDirection.downLeft; + } + else + { + return UtilitiesDXXL_Math.SkewedDirection.upLeft; + } + } + else + { + if (position_viewportSpace.y < viewportCenter_1D) + { + return UtilitiesDXXL_Math.SkewedDirection.downRight; + } + else + { + return UtilitiesDXXL_Math.SkewedDirection.upRight; + } + } + } + + static DrawText.TextAnchorDXXL GetTextAnchor(UtilitiesDXXL_Math.SkewedDirection quadrant) + { + switch (quadrant) + { + case UtilitiesDXXL_Math.SkewedDirection.downLeft: + return DrawText.TextAnchorDXXL.LowerLeft; + + case UtilitiesDXXL_Math.SkewedDirection.upLeft: + return DrawText.TextAnchorDXXL.UpperLeft; + + case UtilitiesDXXL_Math.SkewedDirection.downRight: + return DrawText.TextAnchorDXXL.LowerRight; + + case UtilitiesDXXL_Math.SkewedDirection.upRight: + return DrawText.TextAnchorDXXL.UpperRight; + + default: + return DrawText.TextAnchorDXXL.UpperLeft; + } + } + + static DrawText.TextAnchorDXXL GetTitleTextAnchor(UtilitiesDXXL_Math.SkewedDirection quadrant) + { + switch (quadrant) + { + case UtilitiesDXXL_Math.SkewedDirection.downLeft: + return DrawText.TextAnchorDXXL.UpperLeft; + + case UtilitiesDXXL_Math.SkewedDirection.upLeft: + return DrawText.TextAnchorDXXL.LowerLeft; + + case UtilitiesDXXL_Math.SkewedDirection.downRight: + return DrawText.TextAnchorDXXL.UpperRight; + + case UtilitiesDXXL_Math.SkewedDirection.upRight: + return DrawText.TextAnchorDXXL.LowerRight; + + default: + return DrawText.TextAnchorDXXL.LowerLeft; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Screenspace.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Screenspace.cs.meta new file mode 100644 index 0000000..da0e57e --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Screenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0a8e58b7509c18247bc1e3dc5e1c9f0b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Shapes.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Shapes.cs new file mode 100644 index 0000000..2c5df70 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Shapes.cs @@ -0,0 +1,2533 @@ +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + public class UtilitiesDXXL_Shapes + { + public static List verticesGlobal = new List(); + public static List verticesLocal = new List(); + static List precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward = new List(); + static float distanceOfUnscaledFillLines_asFractionOfShapeSize = 0.075f; + static InternalDXXL_Plane polygonPlane = new InternalDXXL_Plane(); + + public static int DrawFlatPolygon(float angleDeg_ofFirstCorner_from12oClock, int corners, Vector3 centerPosition, float hullRadius, Vector3 normal, Vector3 up_insidePolyPlane, Color color, float lineWidth, string text, float durationInSec, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool hiddenByNearerObjects, bool textBlockAboveLine, bool skipDraw) + { + //function returns "usedSlotsIn_verticesGlobal"; + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(angleDeg_ofFirstCorner_from12oClock, "angleDeg_ofFirstCorner_from12oClock")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(hullRadius, "hullRadius")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth, "lineWidth")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stylePatternScaleFactor, "stylePatternScaleFactor")) { return 0; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerPosition, "centerPosition")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal, "normal")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insidePolyPlane, "up_insidePolyPlane")) { return 0; } + + lineWidth = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth); + + if (corners < 3) + { + Debug.LogError("Cannot draw a polygon with only " + corners + " corners."); + return 0; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(hullRadius)) + { + //DO NOT fallback via "PointFallback-2D-()" here, because the 2D-version may draw a "Circle()", which forwards to here, which can create an endless loop. + UtilitiesDXXL_DrawBasics.PointFallback(centerPosition, "[ Polygon with radius of 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, centerPosition, 0); + return 1; + } + + UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetNormalAndUpInsidePlane(out Vector3 normal_final_notGuaranteedNormalized, out Vector3 up_insidePolyPlane_normalized, normal, up_insidePolyPlane, centerPosition); + polygonPlane.Recreate(centerPosition, normal_final_notGuaranteedNormalized); + + Vector3 vector_fromPolyCenter_toPointOnCircleThatMarksUpInsidePolyPlane = up_insidePolyPlane_normalized * hullRadius; + float angleDeg_betweenPolyCorners = 360.0f / corners; + + Vector3 posOfFirstCorner = Vector3.zero; + Vector3 posOfCurrCorner = Vector3.zero; + Vector3 posOfPrevCorner; + + bool requestedAmountOfCorners_hasPrecalcedPoints = TryFillPrecalcedUnitCirclePointsList(corners); + Quaternion rotationOfPrecalcedPoints = default(Quaternion); //-> will get filled afterwards in each case where it is used + if (requestedAmountOfCorners_hasPrecalcedPoints) + { + Vector3 forwardOfRotationOfPrecalcedPoints; + if (UtilitiesDXXL_Math.ApproximatelyZero(angleDeg_ofFirstCorner_from12oClock) == false) + { + Quaternion rotation_fromUpInsidePolyPlane_toUpTowardsFirstVertex = Quaternion.AngleAxis(angleDeg_ofFirstCorner_from12oClock, normal_final_notGuaranteedNormalized); + forwardOfRotationOfPrecalcedPoints = rotation_fromUpInsidePolyPlane_toUpTowardsFirstVertex * up_insidePolyPlane_normalized; + } + else + { + forwardOfRotationOfPrecalcedPoints = up_insidePolyPlane_normalized; + } + + rotationOfPrecalcedPoints = Quaternion.LookRotation(forwardOfRotationOfPrecalcedPoints, normal_final_notGuaranteedNormalized); + } + + int usedSlotsIn_verticesGlobal = 0; + for (int i = 0; i < corners; i++) + { + Vector3 vector_fromPolyCenter_toCurrCorner; + if (requestedAmountOfCorners_hasPrecalcedPoints) + { + vector_fromPolyCenter_toCurrCorner = rotationOfPrecalcedPoints * precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward[i]; + vector_fromPolyCenter_toCurrCorner = hullRadius * vector_fromPolyCenter_toCurrCorner; + } + else + { + Quaternion rotation_fromFirstCorner_toCurrCorner = Quaternion.AngleAxis(angleDeg_betweenPolyCorners * i + angleDeg_ofFirstCorner_from12oClock, normal_final_notGuaranteedNormalized); + vector_fromPolyCenter_toCurrCorner = rotation_fromFirstCorner_toCurrCorner * vector_fromPolyCenter_toPointOnCircleThatMarksUpInsidePolyPlane; + } + + if (i == 0) + { + posOfCurrCorner = centerPosition + vector_fromPolyCenter_toCurrCorner; + posOfFirstCorner = posOfCurrCorner; + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, posOfFirstCorner, usedSlotsIn_verticesGlobal); + } + else + { + posOfPrevCorner = posOfCurrCorner; + posOfCurrCorner = centerPosition + vector_fromPolyCenter_toCurrCorner; + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, posOfCurrCorner, usedSlotsIn_verticesGlobal); + + if (skipDraw == false) + { + UtilitiesDXXL_DrawBasics.Line(posOfPrevCorner, posOfCurrCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + if (filledWithSpokes) + { + UtilitiesDXXL_DrawBasics.Line(centerPosition, posOfCurrCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + + } + } + + if (skipDraw == false) + { + //close gap from last to first corner: + UtilitiesDXXL_DrawBasics.Line(posOfCurrCorner, posOfFirstCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + if (filledWithSpokes) + { + UtilitiesDXXL_DrawBasics.Line(centerPosition, posOfFirstCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + + if (fillStyle != DrawBasics.LineStyle.invisible) + { + float absHullRadius = Mathf.Abs(hullRadius); + // float distanceBetweenLines = 0.04f / DrawShapes.ShapeFillDensity; + float absHullDiameter = 2.0f * absHullRadius; + float distanceBetweenLines = (distanceOfUnscaledFillLines_asFractionOfShapeSize * absHullDiameter) / DrawShapes.ShapeFillDensity; + distanceBetweenLines = Mathf.Min(distanceBetweenLines, 0.15f * absHullRadius); + distanceBetweenLines = Mathf.Max(distanceBetweenLines, 0.005f * absHullRadius); + int usedSlotsInFillEdgesList = RecalcFillingOfPolygon(usedSlotsIn_verticesGlobal, up_insidePolyPlane_normalized, distanceBetweenLines); + for (int i = 0; i < usedSlotsInFillEdgesList; i++) + { + UtilitiesDXXL_DrawBasics.Line(fillEdges[i].start, fillEdges[i].end, color, 0.0f, null, fillStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + + if (text != null && text != "") + { + float virtualScalePerDim = 0.75f * hullRadius; + Copy_globalVertices_to_localVertices(centerPosition, usedSlotsIn_verticesGlobal); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centerPosition, usedSlotsIn_verticesGlobal, lineWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + return usedSlotsIn_verticesGlobal; + } + + public static int Triangle(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insideTrianglePlane, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(hullRadius, "hullRadius")) { return 0; } + return DrawFlatPolygon(0.0f, 3, centerPosition, Mathf.Abs(hullRadius), normal, up_insideTrianglePlane, color, lineWidth, text, durationInSec, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, hiddenByNearerObjects, textBlockAboveLine, skipDraw); + } + + public static int Square(Vector3 centerPosition, float sideLength, Color color, Vector3 normal, Vector3 up_insideSquarePlane, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(sideLength, "sideLength")) { return 0; } + return DrawFlatPolygon(45.0f, 4, centerPosition, Mathf.Abs(0.5f * sideLength * UtilitiesDXXL_Math.sqrtOf2_precalced), normal, up_insideSquarePlane, color, lineWidth, text, durationInSec, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, hiddenByNearerObjects, textBlockAboveLine, skipDraw); + } + + public static int Pentagon(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insidePentagonPlane, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(hullRadius, "hullRadius")) { return 0; } + return DrawFlatPolygon(0.0f, 5, centerPosition, Mathf.Abs(hullRadius), normal, up_insidePentagonPlane, color, lineWidth, text, durationInSec, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, hiddenByNearerObjects, textBlockAboveLine, skipDraw); + } + + public static int Hexagon(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insideHexagonPlane, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(hullRadius, "hullRadius")) { return 0; } + return DrawFlatPolygon(30.0f, 6, centerPosition, Mathf.Abs(hullRadius), normal, up_insideHexagonPlane, color, lineWidth, text, durationInSec, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, hiddenByNearerObjects, textBlockAboveLine, skipDraw); + } + + public static int Septagon(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insideSeptagonPlane, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(hullRadius, "hullRadius")) { return 0; } + return DrawFlatPolygon(0.0f, 7, centerPosition, Mathf.Abs(hullRadius), normal, up_insideSeptagonPlane, color, lineWidth, text, durationInSec, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, hiddenByNearerObjects, textBlockAboveLine, skipDraw); + } + + public static int Octagon(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insideOctagonPlane, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(hullRadius, "hullRadius")) { return 0; } + return DrawFlatPolygon(67.5f, 8, centerPosition, Mathf.Abs(hullRadius), normal, up_insideOctagonPlane, color, lineWidth, text, durationInSec, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, hiddenByNearerObjects, textBlockAboveLine, skipDraw); + } + + public static int Decagon(Vector3 centerPosition, float hullRadius, Color color, Vector3 normal, Vector3 up_insideDecagonPlane, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(hullRadius, "hullRadius")) { return 0; } + return DrawFlatPolygon(0.0f, 10, centerPosition, Mathf.Abs(hullRadius), normal, up_insideDecagonPlane, color, lineWidth, text, durationInSec, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, hiddenByNearerObjects, textBlockAboveLine, skipDraw); + } + + public static int Circle(Vector3 centerPosition, float radius, Color color, Vector3 normal, Vector3 up_insideCirclePlane, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return 0; } + return DrawFlatPolygon(0.0f, 32, centerPosition, Mathf.Abs(radius), normal, up_insideCirclePlane, color, lineWidth, text, durationInSec, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, hiddenByNearerObjects, textBlockAboveLine, skipDraw); + } + + public static int Ellipse(Vector3 centerPosition, float radiusSideward, float radiusUpward, Color color, Vector3 normal, Vector3 up_insideEllipsePlane, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radiusUpward, "radiusUpward")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radiusSideward, "radiusSideward")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth, "lineWidth")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stylePatternScaleFactor, "stylePatternScaleFactor")) { return 0; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerPosition, "centerPosition")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal, "normal")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideEllipsePlane, "up_insideEllipsePlane")) { return 0; } + + lineWidth = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth); + UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetNormalAndUpInsidePlane(out Vector3 normal_final_notGuaranteedNormalized, out Vector3 up_insideEllipsePlane_normalized, normal, up_insideEllipsePlane, centerPosition); + float absRadiusForward = Mathf.Abs(radiusUpward); + float absRadiusSideward = Mathf.Abs(radiusSideward); + if (UtilitiesDXXL_Math.ApproximatelyZero(absRadiusForward) && UtilitiesDXXL_Math.ApproximatelyZero(absRadiusSideward)) + { + UtilitiesDXXL_DrawBasics.PointFallback(centerPosition, "[ Ellipse with radius of 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, centerPosition, 0); + return 1; + } + + int usedSlotsIn_verticesGlobal = DrawFlatPolygon(0.0f, 32, Vector3.zero, 0.5f, Vector3.forward, Vector3.up, color, lineWidth, null, durationInSec, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, hiddenByNearerObjects, textBlockAboveLine, true); + UtilitiesDXXL_List.CopyContentOfVectorLists(ref verticesLocal, ref verticesGlobal, usedSlotsIn_verticesGlobal); //-> fixing mixup from global and local, after "DrawFlatPolygon" was (virtually) drawn at origin, but filled the "verticesGlobal"-list + + ScaleY(ref verticesLocal, 2.0f * absRadiusForward, usedSlotsIn_verticesGlobal); + ScaleX(ref verticesLocal, 2.0f * absRadiusSideward, usedSlotsIn_verticesGlobal); + Quaternion rotation = Quaternion.LookRotation(normal_final_notGuaranteedNormalized, up_insideEllipsePlane_normalized); + RotateVertices(ref verticesLocal, rotation, usedSlotsIn_verticesGlobal); + Copy_localVertices_to_globalVertices(centerPosition, usedSlotsIn_verticesGlobal); + + if (skipDraw == false) + { + polygonPlane.Recreate(centerPosition, normal_final_notGuaranteedNormalized); + for (int i = 0; i < usedSlotsIn_verticesGlobal; i++) + { + UtilitiesDXXL_DrawBasics.Line(verticesGlobal[i], verticesGlobal[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, usedSlotsIn_verticesGlobal)], color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + if (filledWithSpokes) + { + UtilitiesDXXL_DrawBasics.Line(centerPosition, verticesGlobal[i], color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + + if (fillStyle != DrawBasics.LineStyle.invisible) + { + //float distanceBetweenLines = 0.04f / DrawShapes.ShapeFillDensity; + float absDiameterForward = 2.0f * absRadiusForward; + float distanceBetweenLines = (distanceOfUnscaledFillLines_asFractionOfShapeSize * absDiameterForward) / DrawShapes.ShapeFillDensity; + distanceBetweenLines = Mathf.Min(distanceBetweenLines, 0.15f * absRadiusForward); + distanceBetweenLines = Mathf.Max(distanceBetweenLines, 0.005f * absRadiusForward); + int usedSlotsInFillEdgesList = RecalcFillingOfPolygon(usedSlotsIn_verticesGlobal, up_insideEllipsePlane_normalized, distanceBetweenLines); + for (int i = 0; i < usedSlotsInFillEdgesList; i++) + { + UtilitiesDXXL_DrawBasics.Line(fillEdges[i].start, fillEdges[i].end, color, 0.0f, null, fillStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + + if (text != null && text != "") + { + float virtualScalePerDim = 0.75f * Mathf.Max(absRadiusForward, absRadiusSideward); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centerPosition, usedSlotsIn_verticesGlobal, lineWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + return usedSlotsIn_verticesGlobal; + } + + public static int Star(Vector3 centerPosition, float outerRadius, Color color, int corners, float innerRadiusFactor, Vector3 normal, Vector3 up_insideStarPlane, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(outerRadius, "outerRadius")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(innerRadiusFactor, "innerRadiusFactor")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth, "lineWidth")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(stylePatternScaleFactor, "stylePatternScaleFactor")) { return 0; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerPosition, "centerPosition")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal, "normal")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideStarPlane, "up_insideStarPlane")) { return 0; } + + lineWidth = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth); + + if (corners < 3) + { + Debug.LogError("Cannot draw a star with only " + corners + " corners."); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, centerPosition, 0); + return 1; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(outerRadius)) + { + UtilitiesDXXL_DrawBasics.PointFallback(centerPosition, "[ Star with radius of 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, centerPosition, 0); + return 1; + } + + UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetNormalAndUpInsidePlane(out Vector3 normal_final_notGuaranteedNormalized, out Vector3 up_insideStarPlane_normalized, normal, up_insideStarPlane, centerPosition); + if (skipDraw == false) { polygonPlane.Recreate(centerPosition, normal_final_notGuaranteedNormalized); } + + float angleDeg_betweenOuterCorners = 360.0f / corners; + float angleDeg_betweenOuterAndInnerCorners = 0.5f * angleDeg_betweenOuterCorners; + float scaleFactor_fromOuterRadius_toOuterPolyHullAtInnerCornersPos = Mathf.Cos(Mathf.Deg2Rad * angleDeg_betweenOuterAndInnerCorners); + Vector3 vector_fromPolyCenter_toFirstOuterCorner = up_insideStarPlane_normalized * outerRadius; + float scaleFactor_fromOuterRadius_toInnerRadius = scaleFactor_fromOuterRadius_toOuterPolyHullAtInnerCornersPos * innerRadiusFactor; + float innerRadius = scaleFactor_fromOuterRadius_toInnerRadius * outerRadius; + Vector3 vector_fromPolyCenter_toFirstOuterCorner_shortenedToInnerRadiusLength = vector_fromPolyCenter_toFirstOuterCorner * scaleFactor_fromOuterRadius_toInnerRadius; + + bool requestedAmountOfCorners_hasPrecalcedPoints = TryFillPrecalcedUnitCirclePointsList(corners); + Quaternion rotationOfPrecalcedOuterPoints = default(Quaternion); //-> will get filled afterwards in each case where it is used + Quaternion rotationOfPrecalcedInnerPoints = default(Quaternion); //-> will get filled afterwards in each case where it is used + if (requestedAmountOfCorners_hasPrecalcedPoints) + { + Quaternion rotation_fromOuterPoints_toInnerPoints = Quaternion.AngleAxis(angleDeg_betweenOuterAndInnerCorners, normal_final_notGuaranteedNormalized); + rotationOfPrecalcedOuterPoints = Quaternion.LookRotation(up_insideStarPlane, normal_final_notGuaranteedNormalized); + rotationOfPrecalcedInnerPoints = Quaternion.LookRotation(rotation_fromOuterPoints_toInnerPoints * up_insideStarPlane, normal_final_notGuaranteedNormalized); + } + + Vector3 posOfFirstOuterCorner = Vector3.zero; + Vector3 posOfCurrOuterCorner = Vector3.zero; + Vector3 posOfCurrInnerCorner = Vector3.zero; + Vector3 posOfPrevInnerCorner; + + int usedSlotsIn_verticesGlobal = 0; + for (int i = 0; i < corners; i++) + { + Vector3 vector_fromPolyCenter_toCurrOuterCorner; + Vector3 vector_fromPolyCenter_toCurrInnerCorner; + if (requestedAmountOfCorners_hasPrecalcedPoints) + { + vector_fromPolyCenter_toCurrOuterCorner = rotationOfPrecalcedOuterPoints * precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward[i]; + vector_fromPolyCenter_toCurrOuterCorner = outerRadius * vector_fromPolyCenter_toCurrOuterCorner; + vector_fromPolyCenter_toCurrInnerCorner = rotationOfPrecalcedInnerPoints * precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward[i]; + vector_fromPolyCenter_toCurrInnerCorner = innerRadius * vector_fromPolyCenter_toCurrInnerCorner; + } + else + { + Quaternion rotation_fromFirstOuterCorner_toCurrOuterCorner = Quaternion.AngleAxis(angleDeg_betweenOuterCorners * i, normal_final_notGuaranteedNormalized); + Quaternion rotation_fromFirstOuterCorner_toCurrInnerCorner = Quaternion.AngleAxis(angleDeg_betweenOuterCorners * i + 0.5f * angleDeg_betweenOuterCorners, normal_final_notGuaranteedNormalized); + vector_fromPolyCenter_toCurrOuterCorner = rotation_fromFirstOuterCorner_toCurrOuterCorner * vector_fromPolyCenter_toFirstOuterCorner; + vector_fromPolyCenter_toCurrInnerCorner = rotation_fromFirstOuterCorner_toCurrInnerCorner * vector_fromPolyCenter_toFirstOuterCorner_shortenedToInnerRadiusLength; + } + + if (i == 0) + { + posOfCurrOuterCorner = centerPosition + vector_fromPolyCenter_toCurrOuterCorner; + posOfFirstOuterCorner = posOfCurrOuterCorner; + + posOfCurrInnerCorner = centerPosition + vector_fromPolyCenter_toCurrInnerCorner; + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, posOfCurrInnerCorner, usedSlotsIn_verticesGlobal); + + if (skipDraw == false) + { + UtilitiesDXXL_DrawBasics.Line(posOfCurrOuterCorner, posOfCurrInnerCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + if (filledWithSpokes) + { + UtilitiesDXXL_DrawBasics.Line(centerPosition, posOfCurrInnerCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + } + else + { + posOfCurrOuterCorner = centerPosition + vector_fromPolyCenter_toCurrOuterCorner; + posOfPrevInnerCorner = posOfCurrInnerCorner; + posOfCurrInnerCorner = centerPosition + vector_fromPolyCenter_toCurrInnerCorner; + + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, posOfCurrOuterCorner, usedSlotsIn_verticesGlobal); + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, posOfCurrInnerCorner, usedSlotsIn_verticesGlobal); + + if (skipDraw == false) + { + UtilitiesDXXL_DrawBasics.Line(posOfPrevInnerCorner, posOfCurrOuterCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(posOfCurrOuterCorner, posOfCurrInnerCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + + if (filledWithSpokes) + { + UtilitiesDXXL_DrawBasics.Line(centerPosition, posOfCurrOuterCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(centerPosition, posOfCurrInnerCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + } + } + + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, posOfFirstOuterCorner, usedSlotsIn_verticesGlobal); + + if (skipDraw == false) + { + //close gap from last to first corner: + UtilitiesDXXL_DrawBasics.Line(posOfCurrInnerCorner, posOfFirstOuterCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + if (filledWithSpokes) + { + UtilitiesDXXL_DrawBasics.Line(centerPosition, posOfFirstOuterCorner, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + + //"fillStyle" not supported: GetFillingOfPolygon is not fit for concave shapes like stars + + if (text != null && text != "") + { + float virtualScalePerDim = 0.75f * outerRadius; + Copy_globalVertices_to_localVertices(centerPosition, usedSlotsIn_verticesGlobal); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centerPosition, usedSlotsIn_verticesGlobal, lineWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + return usedSlotsIn_verticesGlobal; + } + + static InternalDXXL_Plane plane_perpToCapsuleDir = new InternalDXXL_Plane(); + public static int FlatCapsule(Vector3 posOfCircle1, Vector3 posOfCircle2, float radius, Color color, Vector3 normal, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, float unscaled_distanceBetweenFillLines = 0.0f, Vector3 upInsidePlane_fallbackForCircleCase = default(Vector3)) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return 0; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(posOfCircle1, "posOfCircle1")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(posOfCircle2, "posOfCircle2")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal, "normal")) { return 0; } + + Vector3 cirle1_to_circle2 = posOfCircle2 - posOfCircle1; + Vector3 centerPosition = 0.5f * (posOfCircle1 + posOfCircle2); + float distance_betweenCircleCenters = cirle1_to_circle2.magnitude; + if (distance_betweenCircleCenters > 0.0001f) + { + //"normal" has to be defined here (as not-default-vector + perpToUp) because otherwise the later "UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetNormalAndUpInsidePlane" would force "upInsideCapsulePlane=cirle1_to_circle2" so it is perp to "normal", but in this case here has the peculiarity that "upInsideCapsulePlane" is the relevant dir, and "normal" should be forced to align perp to it. + if (UtilitiesDXXL_Math.IsDefaultVector(normal)) + { + UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetNormalAndUpInsidePlane(out normal, out Vector3 upAlongVert_insideCapsulePlane_normalized, default(Vector3), cirle1_to_circle2, centerPosition); + } + else + { + plane_perpToCapsuleDir.Recreate(posOfCircle1, cirle1_to_circle2); + normal = ForceVectorPerpToOtherVector(normal, plane_perpToCapsuleDir); + } + } + + float width = 2.0f * radius; + float height = 2.0f * radius + distance_betweenCircleCenters; + return FlatCapsule(centerPosition, width, height, color, normal, cirle1_to_circle2, CapsuleDirection2D.Vertical, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects, unscaled_distanceBetweenFillLines, upInsidePlane_fallbackForCircleCase); + } + + public static int FlatCapsule(Vector3 centerPosition, float width, float height, Color color, Vector3 normal, Vector3 upAlongVert_insideCapsulePlane, CapsuleDirection2D direction, float lineWidth, string text, DrawBasics.LineStyle outlineStyle, float stylePatternScaleFactor, DrawBasics.LineStyle fillStyle, bool filledWithSpokes, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, float unscaled_distanceBetweenFillLines = 0.0f, Vector3 upInsidePlane_fallbackForCircleCase = default(Vector3)) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height, "height")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth, "lineWidth")) { return 0; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerPosition, "centerPosition")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal, "normal")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(upAlongVert_insideCapsulePlane, "upAlongVert_insideCapsulePlane")) { return 0; } + + lineWidth = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth); + + if (UtilitiesDXXL_Math.ApproximatelyZero(width) && UtilitiesDXXL_Math.ApproximatelyZero(height)) + { + UtilitiesDXXL_DrawBasics.PointFallback(centerPosition, "[ FlatCapsule with size of 0]
" + text, color, lineWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, centerPosition, 0); + return 1; + } + + float absWidth = UtilitiesDXXL_Math.AbsNonZeroValue(width); + float absHeight = UtilitiesDXXL_Math.AbsNonZeroValue(height); + + UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetNormalAndUpInsidePlane(out Vector3 normal_final_notGuaranteedNormalized, out Vector3 upAlongVert_insideCapsulePlane_normalized, normal, upAlongVert_insideCapsulePlane, centerPosition); + polygonPlane.Recreate(centerPosition, normal_final_notGuaranteedNormalized); + + float absBiggerSizeComponent; + float absSmallerSizeComponent; + float absRadius; + bool isCircle = false; + if (direction == CapsuleDirection2D.Vertical) + { + if (absHeight <= absWidth) + { + isCircle = true; + absHeight = Mathf.Max(absHeight, absWidth); + } + absRadius = 0.5f * absWidth; + absBiggerSizeComponent = absHeight; + absSmallerSizeComponent = absWidth; + } + else + { + if (absWidth <= absHeight) + { + isCircle = true; + absWidth = Mathf.Max(absHeight, absWidth); + } + absRadius = 0.5f * absHeight; + absBiggerSizeComponent = absWidth; + absSmallerSizeComponent = absHeight; + } + + if (isCircle) + { + Vector3 up_insideCirclePlane; + if (UtilitiesDXXL_Math.IsDefaultVector(upInsidePlane_fallbackForCircleCase)) + { + up_insideCirclePlane = (direction == CapsuleDirection2D.Vertical) ? upAlongVert_insideCapsulePlane_normalized : Vector3.Cross(upAlongVert_insideCapsulePlane_normalized, normal_final_notGuaranteedNormalized); + } + else + { + up_insideCirclePlane = upInsidePlane_fallbackForCircleCase; //<-used by screenspace-version where the camera might be skewed + } + return DrawShapes.Circle(centerPosition, absRadius, color, normal_final_notGuaranteedNormalized, up_insideCirclePlane, lineWidth, text, outlineStyle, stylePatternScaleFactor, fillStyle, filledWithSpokes, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + else + { + int cornersPerHalfCircle = 17; + int usedSlotsIn_verticesLocal = 2 * cornersPerHalfCircle; + float halfAbsHeight = 0.5f * absHeight; + float halfAbsWidth = 0.5f * absWidth; + Vector3 centerOfSphere1_local_unrotated; + Vector3 centerOfSphere2_local_unrotated; + + if (direction == CapsuleDirection2D.Vertical) + { + Vector3 upperSphereCenter_local_unrotated = Vector3.up * (halfAbsHeight - absRadius); + Vector3 lowerSphereCenter_local_unrotated = Vector3.down * (halfAbsHeight - absRadius); + centerOfSphere1_local_unrotated = lowerSphereCenter_local_unrotated; + centerOfSphere2_local_unrotated = upperSphereCenter_local_unrotated; + for (int i = 0; i < cornersPerHalfCircle; i++) + { + int curr_i_inPrecalcedPointsArray = UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(8 - i, 32); + Vector3 vector_fromUpperSphereCenter_toCurrCorner = halfAbsWidth * _32precalcedUnitCirclePoints_aroundOrigin_insideZPlane_startingAtUpward_clockwiseWhenLookingAlongZForward[curr_i_inPrecalcedPointsArray]; + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, upperSphereCenter_local_unrotated + vector_fromUpperSphereCenter_toCurrCorner, i); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, lowerSphereCenter_local_unrotated - vector_fromUpperSphereCenter_toCurrCorner, i + cornersPerHalfCircle); + } + } + else + { + Vector3 rightSphereCenter_local_unrotated = Vector3.right * (halfAbsWidth - absRadius); + Vector3 leftSphereCenter_local_unrotated = Vector3.left * (halfAbsWidth - absRadius); + centerOfSphere1_local_unrotated = leftSphereCenter_local_unrotated; + centerOfSphere2_local_unrotated = rightSphereCenter_local_unrotated; + for (int i = 0; i < cornersPerHalfCircle; i++) + { + int curr_i_inPrecalcedPointsArray = 16 - i; + Vector3 vector_fromRightSphereCenter_toCurrCorner = halfAbsHeight * _32precalcedUnitCirclePoints_aroundOrigin_insideZPlane_startingAtUpward_clockwiseWhenLookingAlongZForward[curr_i_inPrecalcedPointsArray]; + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, rightSphereCenter_local_unrotated + vector_fromRightSphereCenter_toCurrCorner, i); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, leftSphereCenter_local_unrotated - vector_fromRightSphereCenter_toCurrCorner, i + cornersPerHalfCircle); + } + } + + Quaternion rotation = Quaternion.LookRotation(normal_final_notGuaranteedNormalized, upAlongVert_insideCapsulePlane_normalized); + RotateVertices(ref verticesLocal, rotation, usedSlotsIn_verticesLocal); + Copy_localVertices_to_globalVertices(centerPosition, usedSlotsIn_verticesLocal); + int usedSlotsIn_verticesGlobal = usedSlotsIn_verticesLocal; + + for (int i = 0; i < usedSlotsIn_verticesGlobal; i++) + { + UtilitiesDXXL_DrawBasics.Line(verticesGlobal[i], verticesGlobal[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, usedSlotsIn_verticesGlobal)], color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + if (filledWithSpokes) + { + UtilitiesDXXL_DrawBasics.Line(centerPosition, verticesGlobal[i], color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + + if (filledWithSpokes) + { + //additional struts at straight part: + Vector3 strutStartAnchors_at0 = verticesGlobal[0]; + Vector3 strutStartAnchors_0to1 = verticesGlobal[usedSlotsIn_verticesGlobal - 1] - verticesGlobal[0]; + Vector3 strutEndAnchors_at0 = verticesGlobal[cornersPerHalfCircle]; + Vector3 strutEndAnchors_0to1 = verticesGlobal[cornersPerHalfCircle - 1] - verticesGlobal[cornersPerHalfCircle]; + + float ratio_biggerToSmallerDim = (Mathf.Max(0.02f, absBiggerSizeComponent) / Mathf.Max(0.01f, absSmallerSizeComponent)); + int numberOfStrutsAtStraightPart = Mathf.FloorToInt(1.3f * ratio_biggerToSmallerDim * ratio_biggerToSmallerDim); + numberOfStrutsAtStraightPart = Mathf.Min(numberOfStrutsAtStraightPart, 30); + for (int i = 0; i < numberOfStrutsAtStraightPart; i++) + { + float progress_0to1 = (float)(i + 1) / (float)(numberOfStrutsAtStraightPart + 1); + UtilitiesDXXL_DrawBasics.Line(strutStartAnchors_at0 + progress_0to1 * strutStartAnchors_0to1, strutEndAnchors_at0 + progress_0to1 * strutEndAnchors_0to1, color, lineWidth, null, outlineStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + + float absAverageCapsuleSize = 0.5f * (absSmallerSizeComponent + absBiggerSizeComponent); + DrawCapsuleFilling(unscaled_distanceBetweenFillLines, fillStyle, usedSlotsIn_verticesGlobal, centerOfSphere1_local_unrotated, centerOfSphere2_local_unrotated, color, rotation, stylePatternScaleFactor, absAverageCapsuleSize, durationInSec, hiddenByNearerObjects); + + if (text != null && text != "") + { + float virtualScalePerDim = 0.75f * absBiggerSizeComponent; + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centerPosition, usedSlotsIn_verticesLocal, lineWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + return usedSlotsIn_verticesGlobal; + } + } + + static void DrawCapsuleFilling(float unscaled_distanceBetweenFillLines, DrawBasics.LineStyle fillStyle, int usedSlotsIn_verticesGlobal, Vector3 centerOfSphere1_local_unrotated, Vector3 centerOfSphere2_local_unrotated, Color color, Quaternion rotation, float stylePatternScaleFactor, float absAverageCapsuleSize, float durationInSec, bool hiddenByNearerObjects) + { + if (fillStyle != DrawBasics.LineStyle.invisible) + { + float distanceBetweenLines; + if (UtilitiesDXXL_Math.ApproximatelyZero(unscaled_distanceBetweenFillLines)) + { + distanceBetweenLines = (distanceOfUnscaledFillLines_asFractionOfShapeSize * absAverageCapsuleSize) / DrawShapes.ShapeFillDensity; + } + else + { + //used by Screenspace-Version, where fillLineDistances is dependent on screenHeight rather than capsuleSize: + distanceBetweenLines = unscaled_distanceBetweenFillLines / DrawShapes.ShapeFillDensity; + } + + distanceBetweenLines = Mathf.Min(distanceBetweenLines, 0.15f * absAverageCapsuleSize); + distanceBetweenLines = Mathf.Max(distanceBetweenLines, 0.005f * absAverageCapsuleSize); + Vector3 centerOfSphere1_local_rotated = rotation * centerOfSphere1_local_unrotated; + Vector3 centerOfSphere2_local_rotated = rotation * centerOfSphere2_local_unrotated; + Vector3 up_insideCapsulePlane = centerOfSphere2_local_rotated - centerOfSphere1_local_rotated; + Vector3 up_insideCapsulePlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(up_insideCapsulePlane); + int usedSlotsInFillEdgesList = RecalcFillingOfPolygon(usedSlotsIn_verticesGlobal, up_insideCapsulePlane_normalized, distanceBetweenLines); + for (int i = 0; i < usedSlotsInFillEdgesList; i++) + { + UtilitiesDXXL_DrawBasics.Line(fillEdges[i].start, fillEdges[i].end, color, 0.0f, null, fillStyle, stylePatternScaleFactor, 0.0f, null, polygonPlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + } + + static InternalDXXL_Plane plane = new InternalDXXL_Plane(); + public static float finalWidth_ofLastDrawnPlane; + public static float finalLength_ofLastDrawnPlane; + public static void Plane(Vector3 planeMountingPoint, Vector3 positionOnPlaneToIncorporate, Vector3 normal, Color color, float width, float length, Vector3 forward_insidePlane, float linesWidth, string text, float subSegments_signFlipsInterpretation, bool pointer_as_textAttachStyle, float anchorVisualizationSize, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(length, "length")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(subSegments_signFlipsInterpretation, "subSegments_signFlipsInterpretation")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(anchorVisualizationSize, "anchorVisualizationSize")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(planeMountingPoint, "planeMountingPoint")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(positionOnPlaneToIncorporate, "positionOnPlaneToIncorporate")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal, "normal")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward_insidePlane, "forward")) { return; } + + if (subSegments_signFlipsInterpretation < 0.0f) + { + //-> drawing the plane a second time, but only the outline square, since the inner struts don't necessarily coincide with the outline + string text_ofBoundarySquarePlane = null; + float subSegments_signFlipsInterpretation_ofBoundarySquarePlane = 1.0f;//-> this is also important to prevent endless recursive drawing + float anchorVisualizationSize_ofBoundarySquarePlane = 0.0f; + Plane(planeMountingPoint, positionOnPlaneToIncorporate, normal, color, width, length, forward_insidePlane, linesWidth, text_ofBoundarySquarePlane, subSegments_signFlipsInterpretation_ofBoundarySquarePlane, pointer_as_textAttachStyle, anchorVisualizationSize_ofBoundarySquarePlane, lineStyle, stylePatternScaleFactor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + width = UtilitiesDXXL_Math.AbsNonZeroValue(width); + length = UtilitiesDXXL_Math.AbsNonZeroValue(length); + + Vector3 centralPositionOfTheDrawnPlaneArea = planeMountingPoint; + if (UtilitiesDXXL_Math.IsDefaultVector(positionOnPlaneToIncorporate) == false) + { + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(planeMountingPoint, positionOnPlaneToIncorporate) == false) + { + Vector3 fromMountingPointToIncorporatedPoint = positionOnPlaneToIncorporate - planeMountingPoint; + centralPositionOfTheDrawnPlaneArea = centralPositionOfTheDrawnPlaneArea + 0.5f * fromMountingPointToIncorporatedPoint; + float distance_fromMountingPointToIncorporatedPoint_alongForwardInsidePlaneVector; + float distance_fromMountingPointToIncorporatedPoint_alongToSideInsidePlaneVector; + if (UtilitiesDXXL_Math.IsDefaultVector(forward_insidePlane)) + { + forward_insidePlane = fromMountingPointToIncorporatedPoint; + distance_fromMountingPointToIncorporatedPoint_alongForwardInsidePlaneVector = fromMountingPointToIncorporatedPoint.magnitude; + distance_fromMountingPointToIncorporatedPoint_alongToSideInsidePlaneVector = 0.0f; + } + else + { + Vector3 fromMountingPointToIncorporatedPoint_alongForwardInsidePlaneVector = Vector3.Project(fromMountingPointToIncorporatedPoint, forward_insidePlane); + Vector3 fromMountingPointToIncorporatedPoint_perpToForwardInsidePlaneVector = fromMountingPointToIncorporatedPoint - fromMountingPointToIncorporatedPoint_alongForwardInsidePlaneVector; + distance_fromMountingPointToIncorporatedPoint_alongForwardInsidePlaneVector = fromMountingPointToIncorporatedPoint_alongForwardInsidePlaneVector.magnitude; + distance_fromMountingPointToIncorporatedPoint_alongToSideInsidePlaneVector = fromMountingPointToIncorporatedPoint_perpToForwardInsidePlaneVector.magnitude; + } + + width = width + distance_fromMountingPointToIncorporatedPoint_alongToSideInsidePlaneVector; + length = length + distance_fromMountingPointToIncorporatedPoint_alongForwardInsidePlaneVector; + } + } + + finalWidth_ofLastDrawnPlane = width; + finalLength_ofLastDrawnPlane = length; + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + if (UtilitiesDXXL_Math.ApproximatelyZero(width) && UtilitiesDXXL_Math.ApproximatelyZero(length)) + { + UtilitiesDXXL_DrawBasics.PointFallback(planeMountingPoint, "[ Plane with extent of 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref normal, ref forward_insidePlane, true); + normal = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(normal); + plane.Recreate(planeMountingPoint, normal); + forward_insidePlane = ForceVectorPerpToOtherVector(forward_insidePlane, plane); + + int usedSlotsIn_verticesLoal; + if (subSegments_signFlipsInterpretation < 0.0f) + { + usedSlotsIn_verticesLoal = DrawStruts_caseFixedWorldSpaceSegmentSize(centralPositionOfTheDrawnPlaneArea, planeMountingPoint, normal, color, width, length, forward_insidePlane, ref linesWidth, subSegments_signFlipsInterpretation, lineStyle, stylePatternScaleFactor, durationInSec, hiddenByNearerObjects); + } + else + { + usedSlotsIn_verticesLoal = DrawStruts_caseFixedNumberOfSegments(centralPositionOfTheDrawnPlaneArea, normal, color, width, length, forward_insidePlane, ref linesWidth, subSegments_signFlipsInterpretation, lineStyle, stylePatternScaleFactor, durationInSec, hiddenByNearerObjects); + } + + TryDrawPlaneAnchorVisualization(planeMountingPoint, normal, color, anchorVisualizationSize, durationInSec, hiddenByNearerObjects); + TryDrawPlanesText(usedSlotsIn_verticesLoal, centralPositionOfTheDrawnPlaneArea, normal, color, width, length, forward_insidePlane, linesWidth, text, pointer_as_textAttachStyle, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + public const float min_fixedWorldSpaceDistanceOfStrutSegments = 0.001f; + static int DrawStruts_caseFixedWorldSpaceSegmentSize(Vector3 centralPositionOfTheDrawnPlaneArea, Vector3 planeMountingPoint, Vector3 normal, Color color, float width, float length, Vector3 forward_insidePlane, ref float linesWidth, float subSegments_signFlipsInterpretation, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, float durationInSec, bool hiddenByNearerObjects) + { + //-> the outer boundary square has already been drawn + //-> unrotated local space: the unrotated plane lies horizontal in the y plane, while looking form top down onto it + //-> "forward_insidePlane" means "forwardAlongPositiveZAxis" + //-> "centralPositionOfTheDrawnPlaneArea" is the zero origin of this pre-rotation space + + Quaternion rotation = Quaternion.LookRotation(forward_insidePlane, normal); + Vector3 centralDrawPos_to_planeMountingPoint_inGlobalSpace = planeMountingPoint - centralPositionOfTheDrawnPlaneArea; + Vector3 planeMountingPoint_inUnrotatedLocalSpace = Quaternion.Inverse(rotation) * centralDrawPos_to_planeMountingPoint_inGlobalSpace; + + float halfWidth = 0.5f * width; + float halfLength = 0.5f * length; + + int strutsForBothDims = 0; + int i_nextVertexToFillIn = 0; + float absDistanceBetweenStruts = Mathf.Max(min_fixedWorldSpaceDistanceOfStrutSegments, (-subSegments_signFlipsInterpretation)); + int maxStrutsFromAnchorToEdge_perSide = 10000; + + //Further struts when walking along positive zDir: + for (int i = 0; i < maxStrutsFromAnchorToEdge_perSide; i++) //-> starting with "i = 0" -> this positive direction cares for the line through the mountingPoint + { + float currentDistanceFromMountingPoint = absDistanceBetweenStruts * i; + float currentZPos_inUnrotatedLocalSpace = planeMountingPoint_inUnrotatedLocalSpace.z + currentDistanceFromMountingPoint; + + if (currentZPos_inUnrotatedLocalSpace > halfLength) + { + break; + } + else + { + i_nextVertexToFillIn = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(-halfWidth, 0.0f, currentZPos_inUnrotatedLocalSpace), i_nextVertexToFillIn); + i_nextVertexToFillIn = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(+halfWidth, 0.0f, currentZPos_inUnrotatedLocalSpace), i_nextVertexToFillIn); + strutsForBothDims++; + } + } + + //Further struts when walking along negative zDir: + for (int i = 1; i < maxStrutsFromAnchorToEdge_perSide; i++) //-> starting with "i = 1" -> the positive direction above already cared for the line through the mountingPoint + { + float currentDistanceFromMountingPoint = (-absDistanceBetweenStruts) * i; + float currentZPos_inUnrotatedLocalSpace = planeMountingPoint_inUnrotatedLocalSpace.z + currentDistanceFromMountingPoint; + + if (currentZPos_inUnrotatedLocalSpace < (-halfLength)) + { + break; + } + else + { + i_nextVertexToFillIn = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(-halfWidth, 0.0f, currentZPos_inUnrotatedLocalSpace), i_nextVertexToFillIn); + i_nextVertexToFillIn = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(+halfWidth, 0.0f, currentZPos_inUnrotatedLocalSpace), i_nextVertexToFillIn); + strutsForBothDims++; + } + } + + //Further struts when walking along positive xDir: + for (int i = 0; i < maxStrutsFromAnchorToEdge_perSide; i++) //-> starting with "i = 0" -> this positive direction cares for the line through the mountingPoint + { + float currentDistanceFromMountingPoint = absDistanceBetweenStruts * i; + float currentXPos_inUnrotatedLocalSpace = planeMountingPoint_inUnrotatedLocalSpace.x + currentDistanceFromMountingPoint; + + if (currentXPos_inUnrotatedLocalSpace > halfWidth) + { + break; + } + else + { + i_nextVertexToFillIn = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(currentXPos_inUnrotatedLocalSpace, 0.0f, -halfLength), i_nextVertexToFillIn); + i_nextVertexToFillIn = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(currentXPos_inUnrotatedLocalSpace, 0.0f, +halfLength), i_nextVertexToFillIn); + strutsForBothDims++; + } + } + + //Further struts when walking along negative xDir: + for (int i = 1; i < maxStrutsFromAnchorToEdge_perSide; i++) //-> starting with "i = 1" -> the positive direction above already cared for the line through the mountingPoint + { + float currentDistanceFromMountingPoint = (-absDistanceBetweenStruts) * i; + float currentXPos_inUnrotatedLocalSpace = planeMountingPoint_inUnrotatedLocalSpace.x + currentDistanceFromMountingPoint; + + if (currentXPos_inUnrotatedLocalSpace < (-halfWidth)) + { + break; + } + else + { + i_nextVertexToFillIn = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(currentXPos_inUnrotatedLocalSpace, 0.0f, -halfLength), i_nextVertexToFillIn); + i_nextVertexToFillIn = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(currentXPos_inUnrotatedLocalSpace, 0.0f, +halfLength), i_nextVertexToFillIn); + strutsForBothDims++; + } + } + + RotateVertices(ref verticesLocal, rotation, i_nextVertexToFillIn); + linesWidth = Mathf.Min(linesWidth, 0.9f * absDistanceBetweenStruts); + + for (int i_vertex = 0; i_vertex < i_nextVertexToFillIn; i_vertex++) + { + UtilitiesDXXL_DrawBasics.Line(centralPositionOfTheDrawnPlaneArea + verticesLocal[i_vertex], centralPositionOfTheDrawnPlaneArea + verticesLocal[i_vertex + 1], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, plane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + i_vertex++; + } + + return i_nextVertexToFillIn; + } + + static int DrawStruts_caseFixedNumberOfSegments(Vector3 centralPositionOfTheDrawnPlaneArea, Vector3 normal, Color color, float width, float length, Vector3 forward_insidePlane, ref float linesWidth, float subSegments_signFlipsInterpretation, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, float durationInSec, bool hiddenByNearerObjects) + { + int subSegments = Mathf.Max((int)(subSegments_signFlipsInterpretation), 1); + int strutsPerDim = subSegments + 1; + int usedSlotsIn_verticesLoal = strutsPerDim * 4; + + float subSegmentLength_alongWidth = width / subSegments; + float subSegmentLength_alongLength = length / subSegments; + + float halfWidth = 0.5f * width; + float halfLength = 0.5f * length; + + //-> the unrotated plane lies horizontal in the y plane. + //-> the vector names fit a view direction that looks from top down onto this horizontal plane, while "up" means "forwardAlongPositiveZAxis" + //-> "centralPositionOfTheDrawnPlaneArea" is the zero origin of the pre-rotation space + Vector3 lowLeftCorner_local_unrotated = Vector3.left * halfWidth + Vector3.back * halfLength; + Vector3 topLeftCorner_local_unrotated = Vector3.left * halfWidth + Vector3.forward * halfLength; + Vector3 lowRightCorner_local_unrotated = Vector3.right * halfWidth + Vector3.back * halfLength; + + //4 sides: starting with lowest, then counterclockwise, each ascending along axisPositive + for (int i_strut = 0; i_strut < strutsPerDim; i_strut++) + { + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, lowLeftCorner_local_unrotated + Vector3.right * subSegmentLength_alongWidth * i_strut, i_strut); + } + + for (int i_strut = 0; i_strut < strutsPerDim; i_strut++) + { + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, lowRightCorner_local_unrotated + Vector3.forward * subSegmentLength_alongLength * i_strut, strutsPerDim + i_strut); + } + + for (int i_strut = 0; i_strut < strutsPerDim; i_strut++) + { + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, topLeftCorner_local_unrotated + Vector3.right * subSegmentLength_alongWidth * i_strut, 2 * strutsPerDim + i_strut); + } + + for (int i_strut = 0; i_strut < strutsPerDim; i_strut++) + { + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, lowLeftCorner_local_unrotated + Vector3.forward * subSegmentLength_alongLength * i_strut, 3 * strutsPerDim + i_strut); + } + + Quaternion rotation = Quaternion.LookRotation(forward_insidePlane, normal); + RotateVertices(ref verticesLocal, rotation, usedSlotsIn_verticesLoal); + linesWidth = UtilitiesDXXL_Math.Min(linesWidth, 0.9f * subSegmentLength_alongWidth, 0.9f * subSegmentLength_alongLength); + + for (int i_vertex = 0; i_vertex < strutsPerDim; i_vertex++) + { + UtilitiesDXXL_DrawBasics.Line(centralPositionOfTheDrawnPlaneArea + verticesLocal[i_vertex], centralPositionOfTheDrawnPlaneArea + verticesLocal[i_vertex + 2 * strutsPerDim], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, plane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(centralPositionOfTheDrawnPlaneArea + verticesLocal[i_vertex + 1 * strutsPerDim], centralPositionOfTheDrawnPlaneArea + verticesLocal[i_vertex + 3 * strutsPerDim], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, plane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + + return usedSlotsIn_verticesLoal; + } + + static void TryDrawPlaneAnchorVisualization(Vector3 planeMountingPoint, Vector3 normal, Color color, float anchorVisualizationSize, float durationInSec, bool hiddenByNearerObjects) + { + if (anchorVisualizationSize > 0.0f) + { + Color colorForNormal = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color, 0.33f); + Vector3 normal_normalized = normal.normalized; + float lengthOfDrawnNormal = anchorVisualizationSize; + Vector3 drawnNormal = normal_normalized * lengthOfDrawnNormal; + Line_fadeableAnimSpeed.InternalDraw(planeMountingPoint, planeMountingPoint + drawnNormal, colorForNormal, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + float radius = 0.5f * anchorVisualizationSize; + DrawShapes.Circle(planeMountingPoint, radius, color, normal_normalized, default(Vector3), 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + } + } + + static void TryDrawPlanesText(int usedSlotsIn_verticesLoal, Vector3 centralPositionOfTheDrawnPlaneArea, Vector3 normal, Color color, float width, float length, Vector3 forward_insidePlane, float linesWidth, string text, bool pointer_as_textAttachStyle, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (text != null && text != "") + { + if (pointer_as_textAttachStyle) + { + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centralPositionOfTheDrawnPlaneArea, usedSlotsIn_verticesLoal, 0.4f * linesWidth, Mathf.Max(width, length), color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + else + { + Vector3 textUp = Vector3.Cross(forward_insidePlane, normal); + float textSize = 0.05f * width; + float halfLength = 0.5f * length; + float autoLineBreakWidth = 1.001f * halfLength; //-> the "1.001f"-factor prevents lineBreak-flicker + UtilitiesDXXL_Text.WriteFramed(text, centralPositionOfTheDrawnPlaneArea, color, textSize, forward_insidePlane, textUp, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, true, durationInSec, hiddenByNearerObjects); + } + } + } + + public static Vector3 GetPlaneNormalFromTransformEnum(Transform planeTransform, DrawShapes.PlaneNormalFromTransform normalAsEnum_toConvert) + { + switch (normalAsEnum_toConvert) + { + case DrawShapes.PlaneNormalFromTransform.right: + return planeTransform.right; + case DrawShapes.PlaneNormalFromTransform.up: + return planeTransform.up; + case DrawShapes.PlaneNormalFromTransform.forward: + return planeTransform.forward; + case DrawShapes.PlaneNormalFromTransform.left: + return (-planeTransform.right); + case DrawShapes.PlaneNormalFromTransform.down: + return (-planeTransform.up); + case DrawShapes.PlaneNormalFromTransform.back: + return (-planeTransform.forward); + default: + return planeTransform.up; + } + } + + public static Vector3 Get_forwardInsidePlane_FromPlameTransformEnum(Transform planeTransform, DrawShapes.PlaneNormalFromTransform normalAsEnum_toConvert) + { + switch (normalAsEnum_toConvert) + { + case DrawShapes.PlaneNormalFromTransform.right: + return planeTransform.up; + case DrawShapes.PlaneNormalFromTransform.up: + return planeTransform.forward; + case DrawShapes.PlaneNormalFromTransform.forward: + return planeTransform.up; + case DrawShapes.PlaneNormalFromTransform.left: + return planeTransform.up; + case DrawShapes.PlaneNormalFromTransform.down: + return planeTransform.forward; + case DrawShapes.PlaneNormalFromTransform.back: + return planeTransform.up; + default: + return planeTransform.up; + } + } + + public static float Get_width_FromPlameTransformEnum(Transform planeTransform, DrawShapes.PlaneNormalFromTransform normalAsEnum_toConvert) + { + switch (normalAsEnum_toConvert) + { + case DrawShapes.PlaneNormalFromTransform.right: + return planeTransform.lossyScale.z; + case DrawShapes.PlaneNormalFromTransform.up: + return planeTransform.lossyScale.x; + case DrawShapes.PlaneNormalFromTransform.forward: + return planeTransform.lossyScale.x; + case DrawShapes.PlaneNormalFromTransform.left: + return planeTransform.lossyScale.z; + case DrawShapes.PlaneNormalFromTransform.down: + return planeTransform.lossyScale.x; + case DrawShapes.PlaneNormalFromTransform.back: + return planeTransform.lossyScale.x; + default: + return planeTransform.lossyScale.x; + } + } + + public static float Get_length_FromPlameTransformEnum(Transform planeTransform, DrawShapes.PlaneNormalFromTransform normalAsEnum_toConvert) + { + switch (normalAsEnum_toConvert) + { + case DrawShapes.PlaneNormalFromTransform.right: + return planeTransform.lossyScale.y; + case DrawShapes.PlaneNormalFromTransform.up: + return planeTransform.lossyScale.z; + case DrawShapes.PlaneNormalFromTransform.forward: + return planeTransform.lossyScale.y; + case DrawShapes.PlaneNormalFromTransform.left: + return planeTransform.lossyScale.y; + case DrawShapes.PlaneNormalFromTransform.down: + return planeTransform.lossyScale.z; + case DrawShapes.PlaneNormalFromTransform.back: + return planeTransform.lossyScale.y; + default: + return planeTransform.lossyScale.z; + } + } + + public static void Rhombus(Vector3 startCornerPosition, Vector3 firstEdge, Vector3 secondEdge, Color color, float linesWidth, string text, int subSegments, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(startCornerPosition, "startCornerPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(firstEdge, "firstEdge")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(secondEdge, "secondEdge")) { return; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(firstEdge) && UtilitiesDXXL_Math.ApproximatelyZero(secondEdge)) + { + UtilitiesDXXL_DrawBasics.PointFallback(startCornerPosition, "[ Rhombus with extent of 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + + Vector3 normal = Vector3.Cross(firstEdge, secondEdge); + Vector3 normal_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(normal); + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(normal_normalized) < 0.0001f) + { + plane.Recreate(startCornerPosition, Vector3.forward); + } + else + { + plane.Recreate(startCornerPosition, normal_normalized); + } + + Vector3 tenthOfVector1 = firstEdge / (float)subSegments; + Vector3 tenthOfVector2 = secondEdge / (float)subSegments; + for (int i = 0; i <= subSegments; i++) + { + Vector3 areaLine_startPos = startCornerPosition + tenthOfVector1 * (float)i; + Vector3 areaLine_endPos = areaLine_startPos + secondEdge; + UtilitiesDXXL_DrawBasics.Line(areaLine_startPos, areaLine_endPos, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, plane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + + areaLine_startPos = startCornerPosition + tenthOfVector2 * (float)i; + areaLine_endPos = areaLine_startPos + firstEdge; + UtilitiesDXXL_DrawBasics.Line(areaLine_startPos, areaLine_endPos, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, plane, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + + if (text != null && text != "") + { + float textSize; + Vector3 textDir; + Vector3 textUp; + if (UtilitiesDXXL_Math.ApproximatelyZero(firstEdge)) + { + textDir = secondEdge; + textUp = default; + textSize = 0.05f * secondEdge.magnitude; + } + else + { + textDir = firstEdge; + if (UtilitiesDXXL_Math.Check_ifTwoVectorsAreApproxParallel_butCanHeadToDifferntDirs_DXXL(firstEdge, secondEdge)) + { + textUp = default; + } + else + { + textUp = -secondEdge; + } + textSize = 0.05f * firstEdge.magnitude; + } + textSize = Mathf.Max(textSize, 0.01f); + UtilitiesDXXL_Text.WriteFramed(text, startCornerPosition, color, textSize, textDir, textUp, DrawText.TextAnchorDXXL.LowerLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects); + } + + } + + static InternalDXXL_Edge[] cubesEdgesLocal = new InternalDXXL_Edge[12] { new InternalDXXL_Edge(), new InternalDXXL_Edge(), new InternalDXXL_Edge(), new InternalDXXL_Edge(), new InternalDXXL_Edge(), new InternalDXXL_Edge(), new InternalDXXL_Edge(), new InternalDXXL_Edge(), new InternalDXXL_Edge(), new InternalDXXL_Edge(), new InternalDXXL_Edge(), new InternalDXXL_Edge() }; + public static int Cube(Vector3 position, Vector3 scale, Color colorForCube, Color colorForText, Vector3 up, Vector3 forward, float linesWidth, string text, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipDraw, string headerText) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(scale, "scale")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up, "up")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward, "forward")) { return 0; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + + if (UtilitiesDXXL_Math.ApproximatelyZero(scale)) + { + UtilitiesDXXL_DrawBasics.PointFallback(position, "[ Cube with scale of 0]
" + text, colorForCube, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, position, 0); + return 1; + } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up, ref forward, true); + basePlane.Recreate(position, up); + forward = ForceVectorPerpToOtherVector(forward, basePlane); + + int usedSlotsIn_verticesLocal = 8; + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(-0.5f * scale.x, -0.5f * scale.y, -0.5f * scale.z), 0); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(-0.5f * scale.x, 0.5f * scale.y, -0.5f * scale.z), 1); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(0.5f * scale.x, -0.5f * scale.y, -0.5f * scale.z), 2); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(0.5f * scale.x, 0.5f * scale.y, -0.5f * scale.z), 3); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(-0.5f * scale.x, -0.5f * scale.y, 0.5f * scale.z), 4); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(-0.5f * scale.x, 0.5f * scale.y, 0.5f * scale.z), 5); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(0.5f * scale.x, -0.5f * scale.y, 0.5f * scale.z), 6); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(0.5f * scale.x, 0.5f * scale.y, 0.5f * scale.z), 7); + + Quaternion rotation = Quaternion.LookRotation(forward, up); + RotateVertices(ref verticesLocal, rotation, usedSlotsIn_verticesLocal); + Copy_localVertices_to_globalVertices(position, usedSlotsIn_verticesLocal); + + if (skipDraw) { return usedSlotsIn_verticesLocal; } + + cubesEdgesLocal[0].Recreate(verticesLocal[0], verticesLocal[1]); + cubesEdgesLocal[1].Recreate(verticesLocal[0], verticesLocal[2]); + cubesEdgesLocal[2].Recreate(verticesLocal[1], verticesLocal[3]); + cubesEdgesLocal[3].Recreate(verticesLocal[2], verticesLocal[3]); + cubesEdgesLocal[4].Recreate(verticesLocal[4], verticesLocal[5]); + cubesEdgesLocal[5].Recreate(verticesLocal[4], verticesLocal[6]); + cubesEdgesLocal[6].Recreate(verticesLocal[5], verticesLocal[7]); + cubesEdgesLocal[7].Recreate(verticesLocal[6], verticesLocal[7]); + cubesEdgesLocal[8].Recreate(verticesLocal[0], verticesLocal[4]); + cubesEdgesLocal[9].Recreate(verticesLocal[1], verticesLocal[5]); + cubesEdgesLocal[10].Recreate(verticesLocal[2], verticesLocal[6]); + cubesEdgesLocal[11].Recreate(verticesLocal[3], verticesLocal[7]); + + if (UtilitiesDXXL_Math.ApproximatelyZero(linesWidth) == false) + { + float biggestDim = UtilitiesDXXL_Math.GetBiggestAbsComponent(scale); + float maxLinesWidth = biggestDim * 0.1f; + linesWidth = Mathf.Min(linesWidth, maxLinesWidth); + } + + for (int i = 0; i < cubesEdgesLocal.Length; i++) + { + Line_fadeableAnimSpeed.InternalDraw(position + cubesEdgesLocal[i].start, position + cubesEdgesLocal[i].end, colorForCube, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, headerText, position, usedSlotsIn_verticesLocal, 0.4f * linesWidth, scale, colorForCube, colorForText, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + return usedSlotsIn_verticesLocal; + } + + public static void CubeFilled(Vector3 position, Vector3 scale, Color color, Vector3 up, Vector3 forward, float linesWidth, int segmentsPerSide, string text, DrawBasics.LineStyle lineStyle, Color colorOfEdges, float linesWidthOfEdgesCube, float stylePatternScaleFactor, bool useEdgesColorAsTextColor_ifAvailable, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + //The color of the edges can still be different from the color of the fill lines, even if "colorOfEdges" is "default(Color)" (=don't draw edges separately). + //-> This happens for "color" with alpha lower than 1, because the fillLines are drawn as planes, and the edges are drawn twice, because they are part of to planes. + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidthOfEdgesCube, "linesWidthOfEdgesCube")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(scale, "scale")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up, "up")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward, "forward")) { return; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + bool drawFrameCube = !UtilitiesDXXL_Colors.IsDefaultColor(colorOfEdges); + + if (UtilitiesDXXL_Math.ApproximatelyZero(scale)) + { + Color textColor = color; + if (drawFrameCube && useEdgesColorAsTextColor_ifAvailable) { textColor = colorOfEdges; } + UtilitiesDXXL_DrawBasics.PointFallback(position, "[ CubeFilled with scale of 0]
" + text, textColor, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, position, 0); + return; + } + + segmentsPerSide = Mathf.Max(segmentsPerSide, 1); + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up, ref forward, true); + Vector3 up_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(up); + basePlane.Recreate(position, up_normalized); + forward = ForceVectorPerpToOtherVector(forward, basePlane); + Vector3 forward_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(forward); + Vector3 right = Vector3.Cross(up_normalized, forward_normalized); + Vector3 right_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(right); + + Vector3 absScale = UtilitiesDXXL_Math.Abs(scale); + Vector3 halfAbsScale = 0.5f * absScale; + if (absScale.y > 0.001 || absScale.z > 0.001) + { + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(right_normalized) > 0.1f) + { + Vector3 x_negativeEnd_worldSpace = position - right_normalized * halfAbsScale.x; + Vector3 x_positiveEnd_worldSpace = position + right_normalized * halfAbsScale.x; + Plane(x_negativeEnd_worldSpace, default(Vector3), right_normalized, color, scale.z, scale.y, up_normalized, linesWidth, null, segmentsPerSide, false, 0.0f, lineStyle, stylePatternScaleFactor, false, durationInSec, hiddenByNearerObjects); + Plane(x_positiveEnd_worldSpace, default(Vector3), right_normalized, color, scale.z, scale.y, up_normalized, linesWidth, null, segmentsPerSide, false, 0.0f, lineStyle, stylePatternScaleFactor, false, durationInSec, hiddenByNearerObjects); + } + } + + if (absScale.x > 0.001 || absScale.z > 0.001) + { + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(up_normalized) > 0.1f) + { + Vector3 y_negativeEnd_worldSpace = position - up_normalized * halfAbsScale.y; + Vector3 y_positiveEnd_worldSpace = position + up_normalized * halfAbsScale.y; + Plane(y_negativeEnd_worldSpace, default(Vector3), up_normalized, color, scale.x, scale.z, forward_normalized, linesWidth, null, segmentsPerSide, false, 0.0f, lineStyle, stylePatternScaleFactor, false, durationInSec, hiddenByNearerObjects); + Plane(y_positiveEnd_worldSpace, default(Vector3), up_normalized, color, scale.x, scale.z, forward_normalized, linesWidth, null, segmentsPerSide, false, 0.0f, lineStyle, stylePatternScaleFactor, false, durationInSec, hiddenByNearerObjects); + } + } + + if (absScale.x > 0.001 || absScale.y > 0.001) + { + if (UtilitiesDXXL_Math.GetBiggestAbsComponent(forward_normalized) > 0.1f) + { + Vector3 z_negativeEnd_worldSpace = position - forward_normalized * halfAbsScale.z; + Vector3 z_positiveEnd_worldSpace = position + forward_normalized * halfAbsScale.z; + Plane(z_negativeEnd_worldSpace, default(Vector3), forward_normalized, color, scale.x, scale.y, up_normalized, linesWidth, null, segmentsPerSide, false, 0.0f, lineStyle, stylePatternScaleFactor, false, durationInSec, hiddenByNearerObjects); + Plane(z_positiveEnd_worldSpace, default(Vector3), forward_normalized, color, scale.x, scale.y, up_normalized, linesWidth, null, segmentsPerSide, false, 0.0f, lineStyle, stylePatternScaleFactor, false, durationInSec, hiddenByNearerObjects); + } + } + + if (drawFrameCube) + { + DrawShapes.Cube(position, scale, colorOfEdges, up_normalized, forward_normalized, linesWidthOfEdgesCube, null, DrawBasics.LineStyle.solid, 1.0f, false, durationInSec, hiddenByNearerObjects); + } + + if (text != null && text != "") + { + int usedSlotsIn_verticesLocal = 8; + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(-0.5f * scale.x, -0.5f * scale.y, -0.5f * scale.z), 0); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(-0.5f * scale.x, 0.5f * scale.y, -0.5f * scale.z), 1); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(0.5f * scale.x, -0.5f * scale.y, -0.5f * scale.z), 2); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(0.5f * scale.x, 0.5f * scale.y, -0.5f * scale.z), 3); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(-0.5f * scale.x, -0.5f * scale.y, 0.5f * scale.z), 4); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(-0.5f * scale.x, 0.5f * scale.y, 0.5f * scale.z), 5); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(0.5f * scale.x, -0.5f * scale.y, 0.5f * scale.z), 6); + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, new Vector3(0.5f * scale.x, 0.5f * scale.y, 0.5f * scale.z), 7); + + Quaternion rotation = Quaternion.LookRotation(forward_normalized, up_normalized); + RotateVertices(ref verticesLocal, rotation, usedSlotsIn_verticesLocal); + Copy_localVertices_to_globalVertices(position, usedSlotsIn_verticesLocal); + + Color textColor = color; + if (drawFrameCube && useEdgesColorAsTextColor_ifAvailable) { textColor = colorOfEdges; } + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, position, usedSlotsIn_verticesLocal, 0.4f * linesWidth, scale, textColor, textColor, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + static InternalDXXL_Plane spheresPlaneForLineOrienation = new InternalDXXL_Plane(); + static int pointsPerSphereCircle = 64; + static int half_pointsPerSphereCircle = 32; + static float angleDeg_betweenSpheresCirclePoints = 360.0f / (float)pointsPerSphereCircle; + static Vector3[] pointsOnSpheresMainCircle = new Vector3[pointsPerSphereCircle]; + static Vector3[] pointsOn_currStrutCircle = new Vector3[pointsPerSphereCircle]; + static List vectors_fromCenter_toStrutAnchorsUnrotated_normalized = new List(); + static List strutAnchors = new List(); //-> this is filled by "Sphere()" and "Ellipsoid()", but not used by them. A caller can use it afterwards in conjunction with the returned "usedSlotsIn_strutAnchorList". E.g. "Capsule()" does it this way. + + public static int Sphere(Vector3 position, float radius, Color color, Vector3 up, Vector3 forward, float linesWidth, string text, int struts, bool onlyUpperHalf, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipMainRing) + { + //function returns "usedSlotsIn_strutAnchorList"; + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return 0; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up, "up")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward, "forward")) { return 0; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + + if (UtilitiesDXXL_Math.ApproximatelyZero(radius)) + { + //DO NOT fallback to "Point()" here, because "Point()" may draw a "Sphere()" again, which can create an endless loop. + //PointFallback(); + //Debug.Log("'Sphere' (at " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(position) + ") is not drawn, because radius is 0."); + UtilitiesDXXL_List.AddToAVectorList(ref strutAnchors, position, 0); + return 1; + } + + if (struts <= 0) + { + Debug.Log("'struts' (" + struts + ") must be bigger than 0 and is now automatically set to 2."); + struts = 2; + } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up, ref forward, true); + spheresPlaneForLineOrienation.Recreate(position, up); + forward = ForceVectorPerpToOtherVector(forward, spheresPlaneForLineOrienation); + Quaternion sphereOrientation = Quaternion.LookRotation(forward, up); + int usedSlotsIn_verticesGlobal = 0; + int indexIncrements_forCurrentQualitiesSphereCircle = GetIndexIncrements_forCurrentQualitiesSphereCircle(); + + if (skipMainRing == false) + { + int i_endOfPrecedingSubLine = 0; + for (int i = 0; i < pointsPerSphereCircle;) + { + pointsOnSpheresMainCircle[i] = radius * _64precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i]; + pointsOnSpheresMainCircle[i] = sphereOrientation * pointsOnSpheresMainCircle[i]; + pointsOnSpheresMainCircle[i] = position + pointsOnSpheresMainCircle[i]; + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, pointsOnSpheresMainCircle[i], usedSlotsIn_verticesGlobal); + + //skip first point (the gap will be closed with the last point): + if (i > 0) + { + UtilitiesDXXL_DrawBasics.Line(pointsOnSpheresMainCircle[i], pointsOnSpheresMainCircle[i_endOfPrecedingSubLine], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, spheresPlaneForLineOrienation, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + i_endOfPrecedingSubLine = i; + + //close gap that was skipped by the first point: + if (i == (pointsPerSphereCircle - indexIncrements_forCurrentQualitiesSphereCircle)) + { + UtilitiesDXXL_DrawBasics.Line(pointsOnSpheresMainCircle[i], pointsOnSpheresMainCircle[0], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, spheresPlaneForLineOrienation, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + + i += indexIncrements_forCurrentQualitiesSphereCircle; + } + } + + float angleDeg_betweenStrutAnchorsPoints = 180.0f / (float)struts; + for (int i = 0; i < struts; i++) + { + Quaternion currRotation_aroundUp = Quaternion.AngleAxis(angleDeg_betweenStrutAnchorsPoints * i, Vector3.up); + UtilitiesDXXL_List.AddToAVectorList(ref vectors_fromCenter_toStrutAnchorsUnrotated_normalized, currRotation_aroundUp * Vector3.forward, i); + } + + int usedSlotsIn_strutAnchorList = 0; + int pointsPerStrutCircle = onlyUpperHalf ? half_pointsPerSphereCircle : pointsPerSphereCircle; + for (int i_strut = 0; i_strut < struts; i_strut++) + { + Vector3 perpToUnrotatedStrutPlane = -Vector3.Cross(Vector3.up, vectors_fromCenter_toStrutAnchorsUnrotated_normalized[i_strut]); + + if (UtilitiesDXXL_Math.ApproximatelyZero(perpToUnrotatedStrutPlane)) { break; } + + Quaternion rotationOfStrutRelToEquatorCircle = Quaternion.LookRotation(vectors_fromCenter_toStrutAnchorsUnrotated_normalized[i_strut], perpToUnrotatedStrutPlane); + Quaternion overallRotationOfStrutCircle = sphereOrientation * rotationOfStrutRelToEquatorCircle; + + Vector3 perpToRotatedStrutPlane = sphereOrientation * perpToUnrotatedStrutPlane; + spheresPlaneForLineOrienation.Recreate(position, perpToRotatedStrutPlane); + + int i_endOfPrecedingSubLine = 0; + for (int i_posOnStrut = 0; i_posOnStrut < pointsPerStrutCircle;) + { + pointsOn_currStrutCircle[i_posOnStrut] = overallRotationOfStrutCircle * _64precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i_posOnStrut]; + pointsOn_currStrutCircle[i_posOnStrut] = radius * pointsOn_currStrutCircle[i_posOnStrut]; + pointsOn_currStrutCircle[i_posOnStrut] = position + pointsOn_currStrutCircle[i_posOnStrut]; + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, pointsOn_currStrutCircle[i_posOnStrut], usedSlotsIn_verticesGlobal); + + if (i_posOnStrut == 0) + { + usedSlotsIn_strutAnchorList = UtilitiesDXXL_List.AddToAVectorList(ref strutAnchors, pointsOn_currStrutCircle[i_posOnStrut], usedSlotsIn_strutAnchorList); + Vector3 oppositeStrutAnchor = position - (pointsOn_currStrutCircle[i_posOnStrut] - position); + usedSlotsIn_strutAnchorList = UtilitiesDXXL_List.AddToAVectorList(ref strutAnchors, oppositeStrutAnchor, usedSlotsIn_strutAnchorList); + } + + //skip first point (the gap will be closed with the last point): + if (i_posOnStrut > 0) + { + UtilitiesDXXL_DrawBasics.Line(pointsOn_currStrutCircle[i_posOnStrut], pointsOn_currStrutCircle[i_endOfPrecedingSubLine], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, spheresPlaneForLineOrienation, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + i_endOfPrecedingSubLine = i_posOnStrut; + + //close gap that was skipped by the first point: + if (i_posOnStrut == (pointsPerStrutCircle - indexIncrements_forCurrentQualitiesSphereCircle)) + { + Vector3 endPoint_local_unrotated = onlyUpperHalf ? (-vectors_fromCenter_toStrutAnchorsUnrotated_normalized[i_strut]) : vectors_fromCenter_toStrutAnchorsUnrotated_normalized[i_strut]; //-> it would also work by accessing "i=32" or "i=0" of "_64precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward" + endPoint_local_unrotated = radius * endPoint_local_unrotated; + Vector3 endPoint_local_rotated = sphereOrientation * endPoint_local_unrotated; + Vector3 endPoint_global = position + endPoint_local_rotated; + UtilitiesDXXL_DrawBasics.Line(pointsOn_currStrutCircle[i_posOnStrut], endPoint_global, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, spheresPlaneForLineOrienation, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + + i_posOnStrut += indexIncrements_forCurrentQualitiesSphereCircle; + } + } + + if (text != null && text != "") + { + float virtualScalePerDim = 2.0f * radius; + Copy_globalVertices_to_localVertices(position, usedSlotsIn_verticesGlobal); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, position, usedSlotsIn_verticesGlobal, linesWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + return usedSlotsIn_strutAnchorList; + } + + public static int Ellipsoid(Vector3 position, Vector3 radius, Color color, Vector3 up, Vector3 forward, float linesWidth, string text, int struts, bool onlyUpperHalf, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects, bool skipMainRing) + { + //function returns "usedSlotsIn_strutAnchorList"; + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(radius, "radius")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up, "up")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward, "forward")) { return 0; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + + if (UtilitiesDXXL_Math.ApproximatelyZero(radius)) + { + UtilitiesDXXL_DrawBasics.PointFallback(position, "[ Ellipsoid with extent of 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_List.AddToAVectorList(ref strutAnchors, position, 0); + return 1; + } + + if (struts <= 0) + { + Debug.Log("'struts' (" + struts + ") must be bigger than 0 and is now automatically set to 2."); + struts = 2; + } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up, ref forward, true); + spheresPlaneForLineOrienation.Recreate(position, up); + forward = ForceVectorPerpToOtherVector(forward, spheresPlaneForLineOrienation); + Quaternion sphereOrientation = Quaternion.LookRotation(forward, up); + bool x_and_z_areZero_but_y_isNot = UtilitiesDXXL_Math.ApproximatelyZero(radius.x) && UtilitiesDXXL_Math.ApproximatelyZero(radius.z); + int usedSlotsIn_verticesGlobal = 0; + int indexIncrements_forCurrentQualitiesSphereCircle = GetIndexIncrements_forCurrentQualitiesSphereCircle(); + + if (x_and_z_areZero_but_y_isNot) + { + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, position, usedSlotsIn_verticesGlobal); + } + else + { + if (skipMainRing == false) + { + int i_endOfPrecedingSubLine = 0; + for (int i = 0; i < pointsPerSphereCircle;) + { + Vector3 currPointLocal_onMainCircle_withoutSphereRotationApplied_onUnitCircle = _64precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i]; + Vector3 currPointLocal_onMainCircle_withoutSphereRotationApplied_onWarpedCircle = new Vector3(currPointLocal_onMainCircle_withoutSphereRotationApplied_onUnitCircle.x * radius.x, currPointLocal_onMainCircle_withoutSphereRotationApplied_onUnitCircle.y, currPointLocal_onMainCircle_withoutSphereRotationApplied_onUnitCircle.z * radius.z); + Vector3 currPointLocal_onMainCircle_withSphereRotationApplied_onWarpedCircle = sphereOrientation * currPointLocal_onMainCircle_withoutSphereRotationApplied_onWarpedCircle; + pointsOnSpheresMainCircle[i] = position + currPointLocal_onMainCircle_withSphereRotationApplied_onWarpedCircle; + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, pointsOnSpheresMainCircle[i], usedSlotsIn_verticesGlobal); + + //skip first point (the gap will be closed with the last point): + if (i > 0) + { + UtilitiesDXXL_DrawBasics.Line(pointsOnSpheresMainCircle[i], pointsOnSpheresMainCircle[i_endOfPrecedingSubLine], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, spheresPlaneForLineOrienation, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + i_endOfPrecedingSubLine = i; + + //close gap that was skipped by the first point: + if (i == (pointsPerSphereCircle - indexIncrements_forCurrentQualitiesSphereCircle)) + { + UtilitiesDXXL_DrawBasics.Line(pointsOnSpheresMainCircle[i], pointsOnSpheresMainCircle[0], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, spheresPlaneForLineOrienation, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + + i += indexIncrements_forCurrentQualitiesSphereCircle; + } + } + } + + float angleDeg_betweenStrutAnchorsPoints = 180.0f / (float)struts; + for (int i = 0; i < struts; i++) + { + Quaternion currRotation_aroundUp = Quaternion.AngleAxis(angleDeg_betweenStrutAnchorsPoints * i, Vector3.up); + UtilitiesDXXL_List.AddToAVectorList(ref vectors_fromCenter_toStrutAnchorsUnrotated_normalized, currRotation_aroundUp * Vector3.forward, i); + } + + int usedSlotsIn_strutAnchorList = 0; + int pointsPerStrutCircle = onlyUpperHalf ? half_pointsPerSphereCircle : pointsPerSphereCircle; + for (int i_strut = 0; i_strut < struts; i_strut++) + { + Vector3 perpToUnrotatedUnwarpedStrutPlane = -Vector3.Cross(Vector3.up, vectors_fromCenter_toStrutAnchorsUnrotated_normalized[i_strut]); + Vector3 perpToUnrotatedWarpedStrutPlane; + if (UtilitiesDXXL_Math.ApproximatelyZero(radius.x) || UtilitiesDXXL_Math.ApproximatelyZero(radius.z)) + { + perpToUnrotatedWarpedStrutPlane = perpToUnrotatedUnwarpedStrutPlane; + } + else + { + perpToUnrotatedWarpedStrutPlane = new Vector3(perpToUnrotatedUnwarpedStrutPlane.x * radius.z, 0.0f, perpToUnrotatedUnwarpedStrutPlane.z * radius.x); + } + Vector3 perpToRotatedWarpedStrut = sphereOrientation * perpToUnrotatedWarpedStrutPlane; + spheresPlaneForLineOrienation.Recreate(position, perpToRotatedWarpedStrut); + + int i_endOfPrecedingSubLine = 0; + for (int i_posOnStrut = 0; i_posOnStrut < pointsPerStrutCircle;) + { + //-> the repeated use of "Quaternion.AngleAxis" could probably be refactored to using something like "_64precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward" (see "Sphere()") to save performance + Quaternion rotation_forCurrPoint = Quaternion.AngleAxis(angleDeg_betweenSpheresCirclePoints * i_posOnStrut, perpToUnrotatedUnwarpedStrutPlane); + Vector3 currPointLocal_ofCurrStrut_withoutSphereRotationApplied_onUnitCircle = rotation_forCurrPoint * vectors_fromCenter_toStrutAnchorsUnrotated_normalized[i_strut]; + Vector3 currPointLocal_ofCurrStrut_withoutSphereRotationApplied_onWarpedCircle = new Vector3(currPointLocal_ofCurrStrut_withoutSphereRotationApplied_onUnitCircle.x * radius.x, currPointLocal_ofCurrStrut_withoutSphereRotationApplied_onUnitCircle.y * radius.y, currPointLocal_ofCurrStrut_withoutSphereRotationApplied_onUnitCircle.z * radius.z); + Vector3 currPointLocal_ofCurrStrut_withSphereRotationApplied_onWarpedCircle = sphereOrientation * currPointLocal_ofCurrStrut_withoutSphereRotationApplied_onWarpedCircle; + pointsOn_currStrutCircle[i_posOnStrut] = position + currPointLocal_ofCurrStrut_withSphereRotationApplied_onWarpedCircle; + usedSlotsIn_verticesGlobal = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, pointsOn_currStrutCircle[i_posOnStrut], usedSlotsIn_verticesGlobal); + + //currently not used by 'Ellipsoid', but keeps consistency with 'Sphere': + if (i_posOnStrut == 0) + { + usedSlotsIn_strutAnchorList = UtilitiesDXXL_List.AddToAVectorList(ref strutAnchors, pointsOn_currStrutCircle[i_posOnStrut], usedSlotsIn_strutAnchorList); + Vector3 oppositeStrutAnchor = position - (pointsOn_currStrutCircle[i_posOnStrut] - position); + usedSlotsIn_strutAnchorList = UtilitiesDXXL_List.AddToAVectorList(ref strutAnchors, oppositeStrutAnchor, usedSlotsIn_strutAnchorList); + } + + //skip first point (the gap will be closed with the last point): + if (i_posOnStrut > 0) + { + UtilitiesDXXL_DrawBasics.Line(pointsOn_currStrutCircle[i_posOnStrut], pointsOn_currStrutCircle[i_endOfPrecedingSubLine], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, spheresPlaneForLineOrienation, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + i_endOfPrecedingSubLine = i_posOnStrut; + + //close gap that was skipped by the first point: + if (i_posOnStrut == (pointsPerStrutCircle - indexIncrements_forCurrentQualitiesSphereCircle)) + { + //-> "Quaternion.AngleAxis" is used here only for the case of "onlyUpperHalf". In the other case the rotation is always 360° and therefore redundant. It could probably refactored to eliminate the "Quaternion.AngleAxis" all over to save performance. + Quaternion rotation_forEndPoint = Quaternion.AngleAxis(angleDeg_betweenSpheresCirclePoints * (i_posOnStrut + indexIncrements_forCurrentQualitiesSphereCircle), perpToUnrotatedUnwarpedStrutPlane); + Vector3 endPointLocal_ofCurrStrut_withoutSphereRotationApplied_onUnitCircle = rotation_forEndPoint * vectors_fromCenter_toStrutAnchorsUnrotated_normalized[i_strut]; + Vector3 endPointLocal_ofCurrStrut_withoutSphereRotationApplied_onWarpedCircle = new Vector3(endPointLocal_ofCurrStrut_withoutSphereRotationApplied_onUnitCircle.x * radius.x, endPointLocal_ofCurrStrut_withoutSphereRotationApplied_onUnitCircle.y * radius.y, endPointLocal_ofCurrStrut_withoutSphereRotationApplied_onUnitCircle.z * radius.z); + Vector3 endPointLocal_ofCurrStrut_withSphereRotationApplied_onWarpedCircle = sphereOrientation * endPointLocal_ofCurrStrut_withoutSphereRotationApplied_onWarpedCircle; + Vector3 endPointGlobal_ofCurrStrut_withSphereRotationApplied_onWarpedCircle = position + endPointLocal_ofCurrStrut_withSphereRotationApplied_onWarpedCircle; + UtilitiesDXXL_DrawBasics.Line(pointsOn_currStrutCircle[i_posOnStrut], endPointGlobal_ofCurrStrut_withSphereRotationApplied_onWarpedCircle, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, spheresPlaneForLineOrienation, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + + i_posOnStrut += indexIncrements_forCurrentQualitiesSphereCircle; + } + } + + if (text != null && text != "") + { + float virtualScalePerDim = 2.0f * UtilitiesDXXL_Math.GetBiggestAbsComponent(radius); + Copy_globalVertices_to_localVertices(position, usedSlotsIn_verticesGlobal); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, position, usedSlotsIn_verticesGlobal, linesWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + return usedSlotsIn_strutAnchorList; + } + + static int GetIndexIncrements_forCurrentQualitiesSphereCircle() + { + if (DrawShapes.LinesPerSphereCircle == 64) + { + return 1; + } + else + { + if (DrawShapes.LinesPerSphereCircle == 32) + { + return 2; + } + else + { + if (DrawShapes.LinesPerSphereCircle == 16) + { + return 4; + } + else + { + //this is (DrawShapes.LinesPerSphereCircle == 8) + return 8; + } + } + } + } + + static InternalDXXL_Plane strutPlane = new InternalDXXL_Plane(); + static List verticesGlobal_ofCapsule = new List(); + public static void Capsule(Vector3 position, Color color, float radius, float heightInclBothCaps, Vector3 up, Vector3 forward_insideCrosssectionPlane, float linesWidth, string text, int struts, bool onlyUpperHalfSphere, DrawBasics.LineStyle style, float stylePatternScaleFactor, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(heightInclBothCaps, "heightInclBothCaps")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up, "up")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(forward_insideCrosssectionPlane, "forward_insideCrosssectionPlane")) { return; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref up, ref forward_insideCrosssectionPlane, true); + Vector3 upNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(up); + basePlane.Recreate(position, up); + forward_insideCrosssectionPlane = ForceVectorPerpToOtherVector(forward_insideCrosssectionPlane, basePlane); + + if (UtilitiesDXXL_Math.ApproximatelyZero(heightInclBothCaps)) + { + UtilitiesDXXL_DrawBasics.PointFallback(position, "[ Capsule with extent of 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(radius)) + { + Vector3 upperSpherePos = position + 0.5f * heightInclBothCaps * upNormalized; + Vector3 lowerSpherePos = position - 0.5f * heightInclBothCaps * upNormalized; + Line_fadeableAnimSpeed.InternalDraw(lowerSpherePos, upperSpherePos, color, linesWidth, text, style, stylePatternScaleFactor, 0.0f, null, default, false, 0.0f, 0.0f, 0.005f, durationInSec, hiddenByNearerObjects, false, false); + return; + } + + int usedSlotsIn_verticesGlobalOfCapsule = 0; + float heightOfCyl = heightInclBothCaps - Mathf.Sign(heightInclBothCaps) * 2.0f * radius; + if (onlyUpperHalfSphere == false) + { + int numberOfStrutAnchors_lowerSphere = Sphere(position - 0.5f * heightOfCyl * upNormalized, radius, color, (Mathf.Sign(heightInclBothCaps)) * (-upNormalized), forward_insideCrosssectionPlane, linesWidth, null, struts, true, style, stylePatternScaleFactor, false, durationInSec, hiddenByNearerObjects, false); + usedSlotsIn_verticesGlobalOfCapsule = UtilitiesDXXL_List.AddRangeToAVectorList(ref verticesGlobal_ofCapsule, strutAnchors, usedSlotsIn_verticesGlobalOfCapsule, numberOfStrutAnchors_lowerSphere); + } + int numberOfStrutAnchors_upperSphere = Sphere(position + 0.5f * heightOfCyl * upNormalized, radius, color, (Mathf.Sign(heightInclBothCaps)) * upNormalized, forward_insideCrosssectionPlane, linesWidth, null, struts, true, style, stylePatternScaleFactor, false, durationInSec, hiddenByNearerObjects, false); + usedSlotsIn_verticesGlobalOfCapsule = UtilitiesDXXL_List.AddRangeToAVectorList(ref verticesGlobal_ofCapsule, strutAnchors, usedSlotsIn_verticesGlobalOfCapsule, numberOfStrutAnchors_upperSphere); + + for (int i = 0; i < numberOfStrutAnchors_upperSphere; i++) + { + Vector3 strutAnchor_onLowerSide = strutAnchors[i] - heightOfCyl * upNormalized; + Vector3 strutPlaneNormal = Vector3.Cross(upNormalized, strutAnchors[i] - (position + 0.5f * heightOfCyl * upNormalized)); + + if (UtilitiesDXXL_Math.ApproximatelyZero(strutPlaneNormal)) { break; } + + strutPlane.Recreate(position, strutPlaneNormal); + UtilitiesDXXL_DrawBasics.Line(strutAnchors[i], strutAnchor_onLowerSide, color, linesWidth, null, style, stylePatternScaleFactor, 0.0f, null, strutPlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + if (onlyUpperHalfSphere) + { + int numberOfCircleVertices = DrawShapes.Circle(position - 0.5f * heightOfCyl * upNormalized, radius, color, upNormalized, forward_insideCrosssectionPlane, linesWidth, null, style, stylePatternScaleFactor, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); + usedSlotsIn_verticesGlobalOfCapsule = UtilitiesDXXL_List.AddRangeToAVectorList(ref verticesGlobal_ofCapsule, verticesGlobal, usedSlotsIn_verticesGlobalOfCapsule, numberOfCircleVertices); + } + } + + if (text != null && text != "") + { + float virtualScalePerDim = Mathf.Abs(heightInclBothCaps); + usedSlotsIn_verticesGlobalOfCapsule = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal_ofCapsule, position + (0.5f * heightOfCyl * upNormalized) + upNormalized * radius, usedSlotsIn_verticesGlobalOfCapsule); + if (onlyUpperHalfSphere == false) + { + usedSlotsIn_verticesGlobalOfCapsule = UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal_ofCapsule, position - (0.5f * heightOfCyl * upNormalized) - upNormalized * radius, usedSlotsIn_verticesGlobalOfCapsule); + } + Copy_customGlobalVertices_to_localVertices(ref verticesGlobal_ofCapsule, position, usedSlotsIn_verticesGlobalOfCapsule); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, position, usedSlotsIn_verticesGlobalOfCapsule, linesWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + static int default_cornersOnFlatPyramidBaseCircle = 16; + static int cornersOnFlatPyramidBaseCircle = default_cornersOnFlatPyramidBaseCircle; + static InternalDXXL_Plane basePlane = new InternalDXXL_Plane(); + static InternalDXXL_Plane localVertPlane = new InternalDXXL_Plane(); + static List verticesLocal_ofPyramid = new List(); //"Pyramid" cannot use the classwide "verticesLocal"-list, because it gets called from "Vector", which again gets called from "Line(lineStyle = arrows)". So any draw function that executes multiple successive "Line(lineStyle = arrows)"-calls (for example "Plane()") would get their used "verticesLocal"-List overwritten by the PyramidCone of the Arrows after this first "Line()"-call, resulting in undefined behaviour for the succeeding "Line()"-calls. + public static void Pyramid(Vector3 center_ofBasePlane, float height, float width_ofBase, float length_ofBase, Color color, Vector3 normal_ofBaseTowardsApex, Vector3 up_insideBasePlane, DrawShapes.Shape2DType baseShape, float linesWidth, string text, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height, "height")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_ofBase, "width_ofBase")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(length_ofBase, "length_ofBase")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(center_ofBasePlane, "center_ofBasePlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal_ofBaseTowardsApex, "normal_ofBaseTowardsApex")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideBasePlane, "up_insideBasePlane")) { return; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + + if (UtilitiesDXXL_Math.ApproximatelyZero(height) && UtilitiesDXXL_Math.ApproximatelyZero(length_ofBase) && UtilitiesDXXL_Math.ApproximatelyZero(width_ofBase)) + { + //DO NOT fallback to "Point()" here, because "Point()" calls "Pyramid()" again, which can create an endless loop. + // PointFallback(); + //Debug.Log("'Pyramid' (at " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(center_ofBasePlane) + ") is not drawn, because height, length_ofBase and width_ofBase is 0."); + return; + } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref normal_ofBaseTowardsApex, ref up_insideBasePlane, true); + basePlane.Recreate(center_ofBasePlane, normal_ofBaseTowardsApex); + up_insideBasePlane = ForceVectorPerpToOtherVector(up_insideBasePlane, basePlane); + + + int usedSlotsIn_verticesLocal_ofPyramid; + if (baseShape == DrawShapes.Shape2DType.circle) + { + //special case: preventing "GetUnitSquared2DShapeAnchorsInsideYPlane" from overwriting "verticesGlobal" because: See declaration of "verticesLocal_ofPyramid" + usedSlotsIn_verticesLocal_ofPyramid = FillVerticesLocalOfPyramid_withBaseHalfUnitCircle_unrotated(length_ofBase, width_ofBase); + } + else + { + int usedSlotsIn_verticesGlobal = GetUnitSquared2DShapeAnchorsInsideYPlane(baseShape); + UtilitiesDXXL_List.CopyContentOfVectorLists(ref verticesLocal_ofPyramid, ref verticesGlobal, usedSlotsIn_verticesGlobal); //-> fixing mixup from global and local, after "GetUnitSquared2DShapeAnchorsInsideYPlane" was (virtually) drawn at origin, but filled the "verticesGlobal"-list + usedSlotsIn_verticesLocal_ofPyramid = usedSlotsIn_verticesGlobal; + } + + ScaleZ(ref verticesLocal_ofPyramid, length_ofBase, usedSlotsIn_verticesLocal_ofPyramid); + ScaleX(ref verticesLocal_ofPyramid, width_ofBase, usedSlotsIn_verticesLocal_ofPyramid); + Quaternion rotation = Quaternion.LookRotation(up_insideBasePlane, normal_ofBaseTowardsApex); + RotateVertices(ref verticesLocal_ofPyramid, rotation, usedSlotsIn_verticesLocal_ofPyramid); + + //line on pyramid-base: + if (baseShape == DrawShapes.Shape2DType.circle && (UtilitiesDXXL_Math.ApproximatelyZero(length_ofBase) || UtilitiesDXXL_Math.ApproximatelyZero(width_ofBase))) + { + UtilitiesDXXL_DrawBasics.Line(center_ofBasePlane + verticesLocal_ofPyramid[0], center_ofBasePlane + verticesLocal_ofPyramid[cornersOnFlatPyramidBaseCircle - 1], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, basePlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + else + { + for (int i = 0; i < usedSlotsIn_verticesLocal_ofPyramid; i++) + { + UtilitiesDXXL_DrawBasics.Line(center_ofBasePlane + verticesLocal_ofPyramid[i], center_ofBasePlane + verticesLocal_ofPyramid[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, usedSlotsIn_verticesLocal_ofPyramid)], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, basePlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + + //line to pyramid-peak: + Vector3 pyramidPeakLocal = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(normal_ofBaseTowardsApex) * height; + for (int i = 0; i < usedSlotsIn_verticesLocal_ofPyramid; i++) + { + if (baseShape != DrawShapes.Shape2DType.circle4struts || CircleI_marksQuarter(i)) + { + localVertPlane.Recreate(center_ofBasePlane, center_ofBasePlane + verticesLocal_ofPyramid[i], center_ofBasePlane + normal_ofBaseTowardsApex, true); + if (UtilitiesDXXL_Math.ApproximatelyZero(localVertPlane.normalDir)) { continue; } + UtilitiesDXXL_DrawBasics.Line(center_ofBasePlane + verticesLocal_ofPyramid[i], center_ofBasePlane + pyramidPeakLocal, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, localVertPlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + + usedSlotsIn_verticesLocal_ofPyramid = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal_ofPyramid, pyramidPeakLocal, usedSlotsIn_verticesLocal_ofPyramid); + + if (text != null && text != "") + { + UtilitiesDXXL_List.CopyContentOfVectorLists(ref verticesLocal, ref verticesLocal_ofPyramid, usedSlotsIn_verticesLocal_ofPyramid); //since "Vector()->Cone()->Pyramid()" doesn't specify "text", this line doesn't cause problems as described at the "verticesLocal_ofPyramid"-declaration + float virtualScalePerDim = 0.35f * UtilitiesDXXL_Math.Max(Mathf.Abs(height), Mathf.Abs(length_ofBase), Mathf.Abs(width_ofBase)); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, center_ofBasePlane, usedSlotsIn_verticesLocal_ofPyramid, linesWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + static int FillVerticesLocalOfPyramid_withBaseHalfUnitCircle_unrotated(float baseLength, float baseWidth) + { + float hullDiameter = 1.0f; + float hullRadius = 0.5f; //-> a real "unit circle" would have a radius of 1. Therefor the returend circle is called "HalfUnitCircle" in the function name + + if (UtilitiesDXXL_Math.ApproximatelyZero(baseLength)) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(baseWidth)) + { + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal_ofPyramid, Vector3.zero, 0); + return 1; + } + else + { + cornersOnFlatPyramidBaseCircle = UtilitiesDXXL_DrawBasics.useMoreStrutsForFlatPyramidArrow ? 32 : default_cornersOnFlatPyramidBaseCircle; + float distancePerCorner = hullDiameter / (cornersOnFlatPyramidBaseCircle - 1); + int usedSlotsIn_verticesLocal_ofPyramid = 0; + for (int i = 0; i < cornersOnFlatPyramidBaseCircle; i++) + { + Vector3 posOfCurrCorner = new Vector3((-hullRadius) + distancePerCorner * i, 0.0f, 0.0f); + usedSlotsIn_verticesLocal_ofPyramid = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal_ofPyramid, posOfCurrCorner, usedSlotsIn_verticesLocal_ofPyramid); + } + return usedSlotsIn_verticesLocal_ofPyramid; + } + } + else + { + if (UtilitiesDXXL_Math.ApproximatelyZero(baseWidth)) + { + cornersOnFlatPyramidBaseCircle = UtilitiesDXXL_DrawBasics.useMoreStrutsForFlatPyramidArrow ? 32 : default_cornersOnFlatPyramidBaseCircle; + float distancePerCorner = hullDiameter / (cornersOnFlatPyramidBaseCircle - 1); + int usedSlotsIn_verticesLocal_ofPyramid = 0; + for (int i = 0; i < cornersOnFlatPyramidBaseCircle; i++) + { + Vector3 posOfCurrCorner = new Vector3(0.0f, 0.0f, (-hullRadius) + distancePerCorner * i); + usedSlotsIn_verticesLocal_ofPyramid = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal_ofPyramid, posOfCurrCorner, usedSlotsIn_verticesLocal_ofPyramid); + } + return usedSlotsIn_verticesLocal_ofPyramid; + } + else + { + int corners = 32; + int usedSlotsIn_verticesLocal_ofPyramid = 0; + for (int i = 0; i < corners; i++) + { + usedSlotsIn_verticesLocal_ofPyramid = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal_ofPyramid, hullRadius * _32precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i], usedSlotsIn_verticesLocal_ofPyramid); + } + return usedSlotsIn_verticesLocal_ofPyramid; + } + } + } + + public static void Bipyramid(Vector3 center_ofBasePlane, float heightUp, float heightDown, float width_ofBase, float length_ofBase, Color color, Vector3 normal_ofBaseTowardsUpperApex, Vector3 up_insideBasePlane, DrawShapes.Shape2DType baseShape, float linesWidth, string text, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(heightUp, "heightUp")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(heightDown, "heightDown")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(length_ofBase, "length_ofBase")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_ofBase, "width_ofBase")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(center_ofBasePlane, "center_ofBasePlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal_ofBaseTowardsUpperApex, "normal_ofBaseTowardsUpperApex")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideBasePlane, "up_insideBasePlane")) { return; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + + if (UtilitiesDXXL_Math.ApproximatelyZero(heightUp) && UtilitiesDXXL_Math.ApproximatelyZero(heightDown) && UtilitiesDXXL_Math.ApproximatelyZero(length_ofBase) && UtilitiesDXXL_Math.ApproximatelyZero(width_ofBase)) + { + UtilitiesDXXL_DrawBasics.PointFallback(center_ofBasePlane, "[ Bipyramid with extent of 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + + if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(heightUp, heightDown)) + { + UtilitiesDXXL_DrawBasics.PointFallback(center_ofBasePlane, "[ Bipyramid with coinciding pyramids. Both heights = " + heightUp + "]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref normal_ofBaseTowardsUpperApex, ref up_insideBasePlane, true); + Vector3 upNormalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(normal_ofBaseTowardsUpperApex); + basePlane.Recreate(center_ofBasePlane, upNormalized); + up_insideBasePlane = ForceVectorPerpToOtherVector(up_insideBasePlane, basePlane); + + int usedSlotsIn_verticesGlobal = GetUnitSquared2DShapeAnchorsInsideYPlane(baseShape); + UtilitiesDXXL_List.CopyContentOfVectorLists(ref verticesLocal, ref verticesGlobal, usedSlotsIn_verticesGlobal); //-> fixing mixup from global and local, after "GetUnitSquared2DShapeAnchorsInsideYPlane" was (virtually) drawn at origin, but filled the "verticesGlobal"-list + int usedSlotsIn_verticesLocal = usedSlotsIn_verticesGlobal; + + ScaleZ(ref verticesLocal, length_ofBase, usedSlotsIn_verticesLocal); + ScaleX(ref verticesLocal, width_ofBase, usedSlotsIn_verticesLocal); + Quaternion rotation = Quaternion.LookRotation(up_insideBasePlane, normal_ofBaseTowardsUpperApex); + RotateVertices(ref verticesLocal, rotation, usedSlotsIn_verticesLocal); + + Vector3 pyramidPeakUpsideLocal = upNormalized * heightUp; + Vector3 pyramidPeakDownsideLocal = upNormalized * heightDown; + for (int i = 0; i < usedSlotsIn_verticesLocal; i++) + { + UtilitiesDXXL_DrawBasics.Line(center_ofBasePlane + verticesLocal[i], center_ofBasePlane + verticesLocal[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, usedSlotsIn_verticesLocal)], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, basePlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + if (baseShape != DrawShapes.Shape2DType.circle4struts || CircleI_marksQuarter(i)) + { + localVertPlane.Recreate(center_ofBasePlane, center_ofBasePlane + verticesLocal[i], center_ofBasePlane + normal_ofBaseTowardsUpperApex, true); + if (UtilitiesDXXL_Math.ApproximatelyZero(localVertPlane.normalDir)) { continue; } + UtilitiesDXXL_DrawBasics.Line(center_ofBasePlane + verticesLocal[i], center_ofBasePlane + pyramidPeakUpsideLocal, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, localVertPlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(center_ofBasePlane + verticesLocal[i], center_ofBasePlane + pyramidPeakDownsideLocal, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, localVertPlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + usedSlotsIn_verticesLocal = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, pyramidPeakUpsideLocal, usedSlotsIn_verticesLocal); + usedSlotsIn_verticesLocal = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, pyramidPeakDownsideLocal, usedSlotsIn_verticesLocal); + + if (text != null && text != "") + { + float virtualScalePerDim = 0.35f * UtilitiesDXXL_Math.Max(Mathf.Abs(heightUp) + Mathf.Abs(heightDown), Mathf.Abs(length_ofBase), Mathf.Abs(width_ofBase)); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, center_ofBasePlane, usedSlotsIn_verticesLocal, linesWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + } + + static List verticesLocal_aroundNonExtrudedCenter = new List(); + public static void Cylinder(Vector3 centerPos, float height, float width_ofBase, float length_ofBase, Color color, Vector3 extrusionDirection, Vector3 up_insideCrossSectionPlane, DrawShapes.Shape2DType baseShape, float linesWidth, string text, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height, "height")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_ofBase, "width_ofBase")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(length_ofBase, "length_ofBase")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerPos, "centerPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(extrusionDirection, "extrusionDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideCrossSectionPlane, "up_insideCrossSectionPlane")) { return; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + + if (UtilitiesDXXL_Math.ApproximatelyZero(height) && UtilitiesDXXL_Math.ApproximatelyZero(length_ofBase) && UtilitiesDXXL_Math.ApproximatelyZero(width_ofBase)) + { + UtilitiesDXXL_DrawBasics.PointFallback(centerPos, "[ Cylinder with extent of 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + + UtilitiesDXXL_DrawBasics.OverwriteDefaultVectorsWithStandardIdentity(ref extrusionDirection, ref up_insideCrossSectionPlane, true); + basePlane.Recreate(centerPos, extrusionDirection); + up_insideCrossSectionPlane = ForceVectorPerpToOtherVector(up_insideCrossSectionPlane, basePlane); + + int usedSlotsIn_verticesGlobal = GetUnitSquared2DShapeAnchorsInsideYPlane(baseShape); + UtilitiesDXXL_List.CopyContentOfVectorLists(ref verticesLocal_aroundNonExtrudedCenter, ref verticesGlobal, usedSlotsIn_verticesGlobal); //-> fixing mixup from global and local, after "GetUnitSquared2DShapeAnchorsInsideYPlane" was (virtually) drawn at origin, but filled the "verticesGlobal"-list + int usedSlotsIn_verticesLocalAroundNonExtrudedCenter = usedSlotsIn_verticesGlobal; + + ScaleZ(ref verticesLocal_aroundNonExtrudedCenter, length_ofBase, usedSlotsIn_verticesLocalAroundNonExtrudedCenter); + ScaleX(ref verticesLocal_aroundNonExtrudedCenter, width_ofBase, usedSlotsIn_verticesLocalAroundNonExtrudedCenter); + Quaternion rotation = Quaternion.LookRotation(up_insideCrossSectionPlane, extrusionDirection); + RotateVertices(ref verticesLocal_aroundNonExtrudedCenter, rotation, usedSlotsIn_verticesLocalAroundNonExtrudedCenter); + + int usedSlotsIn_verticesLocal = 0; + Vector3 up_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(extrusionDirection); + Vector3 centerToUpperPlaneCenter = up_normalized * 0.5f * height; + + for (int i = 0; i < usedSlotsIn_verticesLocalAroundNonExtrudedCenter; i++) + { + Vector3 currVertex_onUpperPlane_local = centerToUpperPlaneCenter + verticesLocal_aroundNonExtrudedCenter[i]; + Vector3 currVertex_onLowerPlane_local = (-centerToUpperPlaneCenter) + verticesLocal_aroundNonExtrudedCenter[i]; + Vector3 prevVertex_onUpperPlane_local = centerToUpperPlaneCenter + verticesLocal_aroundNonExtrudedCenter[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i - 1, usedSlotsIn_verticesLocalAroundNonExtrudedCenter)]; + Vector3 prevVertex_onLowerPlane_local = (-centerToUpperPlaneCenter) + verticesLocal_aroundNonExtrudedCenter[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i - 1, usedSlotsIn_verticesLocalAroundNonExtrudedCenter)]; + + UtilitiesDXXL_DrawBasics.Line(centerPos + currVertex_onUpperPlane_local, centerPos + prevVertex_onUpperPlane_local, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, basePlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(centerPos + currVertex_onLowerPlane_local, centerPos + prevVertex_onLowerPlane_local, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, basePlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + + if (baseShape != DrawShapes.Shape2DType.circle4struts || CircleI_marksQuarter(i)) + { + localVertPlane.Recreate(centerPos, centerPos + verticesLocal_aroundNonExtrudedCenter[i], centerPos + up_normalized, true); + if (UtilitiesDXXL_Math.ApproximatelyZero(localVertPlane.normalDir)) { continue; } + UtilitiesDXXL_DrawBasics.Line(centerPos + currVertex_onUpperPlane_local, centerPos + currVertex_onLowerPlane_local, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, localVertPlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + + usedSlotsIn_verticesLocal = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, currVertex_onUpperPlane_local, usedSlotsIn_verticesLocal); + usedSlotsIn_verticesLocal = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, currVertex_onLowerPlane_local, usedSlotsIn_verticesLocal); + } + + if (text != null && text != "") + { + float virtualScalePerDim = 0.35f * UtilitiesDXXL_Math.Max(Mathf.Abs(height), Mathf.Abs(length_ofBase), Mathf.Abs(width_ofBase)); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centerPos, usedSlotsIn_verticesLocal, linesWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + } + + static List frustumsBigPlaneAnchorPoints_local = new List(); + static List frustumsSmallPlaneAnchorPoints_local = new List(); + public static void Frustum(Vector3 center_ofBigClipPlane, Vector3 center_ofSmallClipPlane, float width_ofBigClipPlane, float height_ofBigClipPlane, float width_ofSmallClipPlane, float height_ofSmallClipPlane, Color color, Vector3 up_insideClippedPlanes, Vector3 fallback_for_normalOfClipPlanesTowardsApex, DrawShapes.Shape2DType clipPlanesShape, float linesWidth, string text, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_ofBigClipPlane, "width_ofBigClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height_ofBigClipPlane, "height_ofBigClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width_ofSmallClipPlane, "width_ofSmallClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height_ofSmallClipPlane, "height_ofSmallClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(center_ofBigClipPlane, "center_ofBigClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(center_ofSmallClipPlane, "center_ofSmallClipPlane")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideClippedPlanes, "up_insideClippedPlanes")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(fallback_for_normalOfClipPlanesTowardsApex, "fallback_for_normalOfClipPlanesTowardsApex")) { return; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + up_insideClippedPlanes = UtilitiesDXXL_Math.OverwriteDefaultVectors(up_insideClippedPlanes, Vector3.forward); + Vector3 bigPlaneCenter_to_smallPlaneCenter = center_ofSmallClipPlane - center_ofBigClipPlane; + + if (UtilitiesDXXL_Math.ApproximatelyZero(bigPlaneCenter_to_smallPlaneCenter) && UtilitiesDXXL_Math.ApproximatelyZero(height_ofBigClipPlane) && UtilitiesDXXL_Math.ApproximatelyZero(width_ofBigClipPlane) && UtilitiesDXXL_Math.ApproximatelyZero(height_ofSmallClipPlane) && UtilitiesDXXL_Math.ApproximatelyZero(width_ofSmallClipPlane)) + { + UtilitiesDXXL_DrawBasics.PointFallback(center_ofBigClipPlane, "[ Frustum with extent of 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + return; + } + + Vector3 up = bigPlaneCenter_to_smallPlaneCenter; + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(center_ofBigClipPlane, center_ofSmallClipPlane)) + { + fallback_for_normalOfClipPlanesTowardsApex = UtilitiesDXXL_Math.OverwriteDefaultVectors(fallback_for_normalOfClipPlanesTowardsApex, Vector3.up); + up = fallback_for_normalOfClipPlanesTowardsApex; + } + //forward = OverwriteParallelVectorsWithPerpVector(forward, up); + basePlane.Recreate(center_ofBigClipPlane, up); + up_insideClippedPlanes = ForceVectorPerpToOtherVector(up_insideClippedPlanes, basePlane); + + int usedSlotsIn_verticesGlobal = GetUnitSquared2DShapeAnchorsInsideYPlane(clipPlanesShape); + UtilitiesDXXL_List.CopyContentOfVectorLists(ref frustumsBigPlaneAnchorPoints_local, ref verticesGlobal, usedSlotsIn_verticesGlobal); //-> fixing mixup from global and local, after "GetUnitSquared2DShapeAnchorsInsideYPlane" was (virtually) drawn at origin, but filled the "verticesGlobal"-list + UtilitiesDXXL_List.CopyContentOfVectorLists(ref frustumsSmallPlaneAnchorPoints_local, ref verticesGlobal, usedSlotsIn_verticesGlobal); //-> fixing mixup from global and local, after "GetUnitSquared2DShapeAnchorsInsideYPlane" was (virtually) drawn at origin, but filled the "verticesGlobal"-list + int usedSlotsIn_frustumsPlaneAnchorLists = usedSlotsIn_verticesGlobal; + + Quaternion rotation = Quaternion.LookRotation(up_insideClippedPlanes, up); + ScaleZ(ref frustumsBigPlaneAnchorPoints_local, height_ofBigClipPlane, usedSlotsIn_frustumsPlaneAnchorLists); + ScaleX(ref frustumsBigPlaneAnchorPoints_local, width_ofBigClipPlane, usedSlotsIn_frustumsPlaneAnchorLists); + RotateVertices(ref frustumsBigPlaneAnchorPoints_local, rotation, usedSlotsIn_frustumsPlaneAnchorLists); + ScaleZ(ref frustumsSmallPlaneAnchorPoints_local, height_ofSmallClipPlane, usedSlotsIn_frustumsPlaneAnchorLists); + ScaleX(ref frustumsSmallPlaneAnchorPoints_local, width_ofSmallClipPlane, usedSlotsIn_frustumsPlaneAnchorLists); + RotateVertices(ref frustumsSmallPlaneAnchorPoints_local, rotation, usedSlotsIn_frustumsPlaneAnchorLists); + + int usedSlotsIn_verticesLocal = 0; + for (int i = 0; i < usedSlotsIn_frustumsPlaneAnchorLists; i++) + { + Vector3 currVertex_onBigPlane_localToBigPlaneCenter = frustumsBigPlaneAnchorPoints_local[i]; + Vector3 prevVertex_onBigPlane_localToBigPlaneCenter = frustumsBigPlaneAnchorPoints_local[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i - 1, usedSlotsIn_frustumsPlaneAnchorLists)]; + Vector3 currVertex_onSmallPlane_localToBigPlaneCenter = bigPlaneCenter_to_smallPlaneCenter + frustumsSmallPlaneAnchorPoints_local[i]; + Vector3 prevVertex_onSmallPlane_localToBigPlaneCenter = bigPlaneCenter_to_smallPlaneCenter + frustumsSmallPlaneAnchorPoints_local[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i - 1, usedSlotsIn_frustumsPlaneAnchorLists)]; + + //Drawing clip plane outlines: + UtilitiesDXXL_DrawBasics.Line(center_ofBigClipPlane + currVertex_onBigPlane_localToBigPlaneCenter, center_ofBigClipPlane + prevVertex_onBigPlane_localToBigPlaneCenter, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, basePlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(center_ofBigClipPlane + currVertex_onSmallPlane_localToBigPlaneCenter, center_ofBigClipPlane + prevVertex_onSmallPlane_localToBigPlaneCenter, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, basePlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + + //Drawing connection struts between clip planes: + if (clipPlanesShape != DrawShapes.Shape2DType.circle4struts || CircleI_marksQuarter(i)) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(currVertex_onBigPlane_localToBigPlaneCenter) || UtilitiesDXXL_Math.ApproximatelyZero(up)) + { + UtilitiesDXXL_DrawBasics.Line(center_ofBigClipPlane + currVertex_onBigPlane_localToBigPlaneCenter, center_ofBigClipPlane + currVertex_onSmallPlane_localToBigPlaneCenter, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, null, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + else + { + localVertPlane.Recreate(center_ofBigClipPlane, center_ofBigClipPlane + currVertex_onBigPlane_localToBigPlaneCenter, center_ofBigClipPlane + up, true); + if (UtilitiesDXXL_Math.ApproximatelyZero(localVertPlane.normalDir) == false) + { + UtilitiesDXXL_DrawBasics.Line(center_ofBigClipPlane + currVertex_onBigPlane_localToBigPlaneCenter, center_ofBigClipPlane + currVertex_onSmallPlane_localToBigPlaneCenter, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, localVertPlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + else + { + UtilitiesDXXL_DrawBasics.Line(center_ofBigClipPlane + currVertex_onBigPlane_localToBigPlaneCenter, center_ofBigClipPlane + currVertex_onSmallPlane_localToBigPlaneCenter, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, null, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + } + + usedSlotsIn_verticesLocal = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, currVertex_onBigPlane_localToBigPlaneCenter, usedSlotsIn_verticesLocal); + usedSlotsIn_verticesLocal = UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, currVertex_onSmallPlane_localToBigPlaneCenter, usedSlotsIn_verticesLocal); + } + + if (text != null && text != "") + { + float height = bigPlaneCenter_to_smallPlaneCenter.magnitude; + float virtualScalePerDim = 0.35f * UtilitiesDXXL_Math.Max(Mathf.Abs(height), Mathf.Abs(height_ofBigClipPlane), Mathf.Abs(width_ofBigClipPlane), Mathf.Abs(height_ofSmallClipPlane), Mathf.Abs(width_ofSmallClipPlane)); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, center_ofBigClipPlane, usedSlotsIn_verticesLocal, linesWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + } + + static InternalDXXL_Plane shapePlane = new InternalDXXL_Plane(); + public static int FlatShape(Vector3 centerPosition, float width, float height, Color color, Vector3 normal, Vector3 up_insideShapePlane, DrawShapes.Shape2DType outlineShape, float linesWidth, string text, DrawBasics.LineStyle lineStyle, float stylePatternScaleFactor, bool flattenRoundLines_intoShapePlane, DrawBasics.LineStyle fillStyle, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + //function returns "usedSlotsIn_verticesGlobal"; + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(height, "height")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(width, "width")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(linesWidth, "linesWidth")) { return 0; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(centerPosition, "centerPosition")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(up_insideShapePlane, "up_insideShapePlane")) { return 0; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(normal, "normal")) { return 0; } + + linesWidth = UtilitiesDXXL_Math.AbsNonZeroValue(linesWidth); + + if (UtilitiesDXXL_Math.ApproximatelyZero(height) && UtilitiesDXXL_Math.ApproximatelyZero(width)) + { + //DO NOT fallback via "PointFallback-2D-()" here, because the 2D-version may draw a "Decagon()", which forwards to here, which can create an endless loop. + UtilitiesDXXL_DrawBasics.PointFallback(centerPosition, "[ FlatShape with extent of 0]
" + text, color, linesWidth, durationInSec, hiddenByNearerObjects); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, centerPosition, 0); + return 1; + } + + UtilitiesDXXL_FlatShapesNormaAndUpCalculation.GetNormalAndUpInsidePlane(out Vector3 normal_final_notGuaranteedNormalized, out Vector3 up_insideShapePlane_normalized, normal, up_insideShapePlane, centerPosition); + shapePlane.Recreate(centerPosition, normal_final_notGuaranteedNormalized); + + int usedSlotsIn_verticesGlobal = GetUnitSquared2DShapeAnchorsInsideYPlane(outlineShape); + UtilitiesDXXL_List.CopyContentOfVectorLists(ref verticesLocal, ref verticesGlobal, usedSlotsIn_verticesGlobal); //-> fixing mixup from global and local, after "GetUnitSquared2DShapeAnchorsInsideYPlane" was (virtually) drawn at origin, but filled the "verticesGlobal"-list + int usedSlotsIn_verticesLocal = usedSlotsIn_verticesGlobal; + + ScaleZ(ref verticesLocal, height, usedSlotsIn_verticesLocal); + ScaleX(ref verticesLocal, width, usedSlotsIn_verticesLocal); + Quaternion rotation = Quaternion.LookRotation(up_insideShapePlane_normalized, normal_final_notGuaranteedNormalized); + RotateVertices(ref verticesLocal, rotation, usedSlotsIn_verticesLocal); + Copy_localVertices_to_globalVertices(centerPosition, usedSlotsIn_verticesLocal); + + if (outlineShape == DrawShapes.Shape2DType.square && (UtilitiesDXXL_Math.ApproximatelyZero(linesWidth) == false)) + { + //correcting the dents on square corners: + Vector3 right_insideShapePlane = Vector3.Cross(normal_final_notGuaranteedNormalized, up_insideShapePlane_normalized); + Vector3 right_insideShapePlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(right_insideShapePlane); + float halfLineWidth = 0.5f * linesWidth; + Vector3 cornerDent_correctionVector_inUpDir = up_insideShapePlane_normalized * halfLineWidth; + Vector3 cornerDent_correctionVector_inRightDir = right_insideShapePlane_normalized * halfLineWidth; + UtilitiesDXXL_DrawBasics.Line(verticesGlobal[0] - cornerDent_correctionVector_inRightDir, centerPosition + verticesLocal[1] + cornerDent_correctionVector_inRightDir, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, shapePlane, flattenRoundLines_intoShapePlane, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(verticesGlobal[1] - cornerDent_correctionVector_inUpDir, centerPosition + verticesLocal[2] + cornerDent_correctionVector_inUpDir, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, shapePlane, flattenRoundLines_intoShapePlane, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(verticesGlobal[2] + cornerDent_correctionVector_inRightDir, centerPosition + verticesLocal[3] - cornerDent_correctionVector_inRightDir, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, shapePlane, flattenRoundLines_intoShapePlane, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(verticesGlobal[3] + cornerDent_correctionVector_inUpDir, centerPosition + verticesLocal[0] - cornerDent_correctionVector_inUpDir, color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, shapePlane, flattenRoundLines_intoShapePlane, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + else + { + for (int i = 0; i < usedSlotsIn_verticesLocal; i++) + { + UtilitiesDXXL_DrawBasics.Line(verticesGlobal[i], centerPosition + verticesLocal[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, usedSlotsIn_verticesLocal)], color, linesWidth, null, lineStyle, stylePatternScaleFactor, 0.0f, null, shapePlane, flattenRoundLines_intoShapePlane, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + + float absHeight = Mathf.Abs(height); + DrawShapeFilling(outlineShape, fillStyle, usedSlotsIn_verticesGlobal, distanceOfUnscaledFillLines_asFractionOfShapeSize * absHeight, color, up_insideShapePlane_normalized, stylePatternScaleFactor, shapePlane, durationInSec, hiddenByNearerObjects); + + if (text != null && text != "") + { + float virtualScalePerDim = 0.35f * Mathf.Max(Mathf.Abs(height), Mathf.Abs(width)); + UtilitiesDXXL_TextTagForPointCollection.TagPointCollection(text, null, centerPosition, usedSlotsIn_verticesLocal, linesWidth, virtualScalePerDim, color, color, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + return usedSlotsIn_verticesGlobal; + } + + static int GetUnitSquared2DShapeAnchorsInsideYPlane(DrawShapes.Shape2DType baseShape) + { + //function returns "usedSlotsIn_verticesGlobal" and has filled "verticesGlobal" around origin with the requested shape + + switch (baseShape) + { + case DrawShapes.Shape2DType.triangle: + return Triangle(Vector3.zero, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.square: + //return Square(Vector3.zero, 1.0f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, new Vector3(-0.5f, 0.0f, -0.5f), 0); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, new Vector3(0.5f, 0.0f, -0.5f), 1); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, new Vector3(0.5f, 0.0f, 0.5f), 2); + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, new Vector3(-0.5f, 0.0f, 0.5f), 3); + return 4; + + case DrawShapes.Shape2DType.pentagon: + return Pentagon(Vector3.zero, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.hexagon: + return Hexagon(Vector3.zero, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.septagon: + return Septagon(Vector3.zero, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.octagon: + return Octagon(Vector3.zero, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.decagon: + return Decagon(Vector3.zero, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.circle: + return Circle(Vector3.zero, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.circle4struts: + return Circle(Vector3.zero, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.star3: + return Star(Vector3.zero, 0.5f, default, 3, 0.5f, Vector3.up, Vector3.forward, default, null, default, 1.0f, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.star4: + return Star(Vector3.zero, 0.5f, default, 4, 0.5f, Vector3.up, Vector3.forward, default, null, default, 1.0f, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.star5: + return Star(Vector3.zero, 0.5f, default, 5, 0.5f, Vector3.up, Vector3.forward, default, null, default, 1.0f, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.star6: + return Star(Vector3.zero, 0.5f, default, 6, 0.5f, Vector3.up, Vector3.forward, default, null, default, 1.0f, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.star8: + return Star(Vector3.zero, 0.5f, default, 8, 0.5f, Vector3.up, Vector3.forward, default, null, default, 1.0f, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.star10: + return Star(Vector3.zero, 0.5f, default, 10, 0.5f, Vector3.up, Vector3.forward, default, null, default, 1.0f, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.star16: + return Star(Vector3.zero, 0.5f, default, 16, 0.5f, Vector3.up, Vector3.forward, default, null, default, 1.0f, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.star32: + return Star(Vector3.zero, 0.5f, default, 32, 0.5f, Vector3.up, Vector3.forward, default, null, default, 1.0f, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.star64: + return Star(Vector3.zero, 0.5f, default, 64, 0.5f, Vector3.up, Vector3.forward, default, null, default, 1.0f, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.ellipse05: + return Ellipse(Vector3.zero, 0.5f * 0.5f, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.ellipse025: + return Ellipse(Vector3.zero, 0.5f * 0.25f, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + case DrawShapes.Shape2DType.ellipse0125: + return Ellipse(Vector3.zero, 0.5f * 0.125f, 0.5f, default, Vector3.up, Vector3.forward, default, null, default, 1.0f, default, false, false, 0.0f, true, true); + + default: + Debug.LogError("BaseShape " + baseShape + " not yet implemented."); + return 0; + } + } + + static bool CircleI_marksQuarter(int i) + { + if (i == 0 || i == 8 || i == 16 || i == 24) + { + return true; + } + else + { + return false; + } + } + + public static List fillEdges = new List(); + static List edges = new List(); + static List parallelFillLines = new List(); + static int RecalcFillingOfPolygon(int usedSlotsInVerticesGlobalList, Vector3 up_insidePolyPlane_normalized, float distanceBetweenLines) + { + //returns "usedSlotsInFillEdgesList" + + //this function can only handle convex polygons. Concave polygons not implemented yet. + //verticesGlobal have to lie in the same plane. + + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return 0; } + + int usedSlotsInFillEdgesList = 0; + if (usedSlotsInVerticesGlobalList == 0) { return 0; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(up_insidePolyPlane_normalized)) + { + Debug.LogError("'up_insidePolyPlane_normalized' is not allowed to be zero."); + return 0; + } + + int usedSlots_inEdgesList = 0; + Vector3 lowestVertex = verticesGlobal[0]; + Vector3 highestVertex = verticesGlobal[0]; + for (int i = 0; i < usedSlotsInVerticesGlobalList; i++) + { + Vector3 vertexToLowest = lowestVertex - verticesGlobal[i]; + if (UtilitiesDXXL_Math.Check_ifVectorsPointInSameDirection_perpCountsAsPointingInSameDir(vertexToLowest, up_insidePolyPlane_normalized)) + { + lowestVertex = verticesGlobal[i]; + } + + Vector3 vertexToHighest = highestVertex - verticesGlobal[i]; + if (UtilitiesDXXL_Math.Check_ifVectorsPointAwayFromEachOther_perpCountsAsPointingAwayFromEachOther(vertexToHighest, up_insidePolyPlane_normalized)) + { + highestVertex = verticesGlobal[i]; + } + + Vector3 edgeStart = verticesGlobal[i]; + Vector3 edgeEnd = verticesGlobal[UtilitiesDXXL_Math.LoopOvershootingIndexIntoCollectionSize(i + 1, usedSlotsInVerticesGlobalList)]; + if (UtilitiesDXXL_Math.CheckIf_twoVectorsAreApproximatelyEqual(edgeStart, edgeEnd) == false) + { + usedSlots_inEdgesList = AddToAEdgeList(ref edges, edgeStart, edgeEnd, true, usedSlots_inEdgesList); + } + } + + Vector3 lowestToHighestVertex = highestVertex - lowestVertex; + Vector3 lowestToHighestVertex_parallelToUp = Vector3.Project(lowestToHighestVertex, up_insidePolyPlane_normalized); + float distance_fromlowestToHighestVertex_alongUp = lowestToHighestVertex_parallelToUp.magnitude; + distanceBetweenLines = UtilitiesDXXL_Math.Max(distanceBetweenLines, 0.001f, 0.0005f * distance_fromlowestToHighestVertex_alongUp); + float currDistanceFromLowestVertex = 0.499f * distanceBetweenLines; + + int usedSlotsIn_polyFillLinesList = 0; + int loopIterationCounter = 0; + while (currDistanceFromLowestVertex < distance_fromlowestToHighestVertex_alongUp) + { + Vector3 planeAnchorPos = lowestVertex + up_insidePolyPlane_normalized * currDistanceFromLowestVertex; + usedSlotsIn_polyFillLinesList = AddToAPolyFillLinesList(ref parallelFillLines, planeAnchorPos, up_insidePolyPlane_normalized, usedSlotsIn_polyFillLinesList); + currDistanceFromLowestVertex = currDistanceFromLowestVertex + distanceBetweenLines; + + loopIterationCounter++; + if (loopIterationCounter > 100000) + { + Debug.LogError("Too many while loop iterations. Forced quit to prevent freeze. distanceBetweenLines: " + distanceBetweenLines + " distance_fromlowestToHighestVertex_alongUp: " + distance_fromlowestToHighestVertex_alongUp); + break; + } + } + + for (int i_fillLine = 0; i_fillLine < usedSlotsIn_polyFillLinesList; i_fillLine++) + { + for (int i_edge = 0; i_edge < usedSlots_inEdgesList; i_edge++) + { + parallelFillLines[i_fillLine].IntersectWithEdge(edges[i_edge]); + } + parallelFillLines[i_fillLine].RemoveDuplicateIntersections(); + } + + for (int i_fillLine = 0; i_fillLine < usedSlotsIn_polyFillLinesList; i_fillLine++) + { + if (parallelFillLines[i_fillLine].usedSlotsInFillLineAnchorsList >= 2) + { + usedSlotsInFillEdgesList = AddToAEdgeList(ref fillEdges, parallelFillLines[i_fillLine].fillLineAnchors[0], parallelFillLines[i_fillLine].fillLineAnchors[1], false, usedSlotsInFillEdgesList); + } + } + + return usedSlotsInFillEdgesList; + } + + static int AddToAPolyFillLinesList(ref List targetList, Vector3 posOfPerpPlane, Vector3 normalOfPerpPlane, int i_ofSlotWhereToAdd) + { + //function returns "i_nextFreeSlot" + if (i_ofSlotWhereToAdd < targetList.Count) + { + targetList[i_ofSlotWhereToAdd].plane_perpToPolygon.Recreate(posOfPerpPlane, normalOfPerpPlane); + targetList[i_ofSlotWhereToAdd].usedSlotsInFillLineAnchorsList = 0; + } + else + { + InternalDXXL_PolyFillLine newPolyFillLine = new InternalDXXL_PolyFillLine(posOfPerpPlane, normalOfPerpPlane); + targetList.Add(newPolyFillLine); + } + i_ofSlotWhereToAdd++; + return i_ofSlotWhereToAdd; + } + + static int AddToAEdgeList(ref List targetList, Vector3 start, Vector3 end, bool calcLine, int i_ofSlotWhereToAdd) + { + //function returns "i_nextFreeSlot" + if (i_ofSlotWhereToAdd < targetList.Count) + { + targetList[i_ofSlotWhereToAdd].start = start; + targetList[i_ofSlotWhereToAdd].end = end; + if (calcLine) + { + targetList[i_ofSlotWhereToAdd].CalcLine(); + } + } + else + { + InternalDXXL_Edge newEdge = new InternalDXXL_Edge(); + newEdge.start = start; + newEdge.end = end; + if (calcLine) + { + newEdge.CalcLine(); + } + targetList.Add(newEdge); + } + i_ofSlotWhereToAdd++; + return i_ofSlotWhereToAdd; + } + + public static void DrawShapeFilling(DrawShapes.Shape2DType baseShape, DrawBasics.LineStyle fillStyle, int usedSlotsIn_verticesGlobal, float distanceBetweenLines, Color color, Vector3 up_normalized, float stylePatternScaleFactor, InternalDXXL_Plane shapePlane, float durationInSec, bool hiddenByNearerObjects) + { + if (fillStyle != DrawBasics.LineStyle.invisible) + { + if (Shape2DisConvex(baseShape)) + { + float scaledDistanceBetweenLines = distanceBetweenLines / DrawShapes.ShapeFillDensity; + int usedSlotsInFillEdgesList = RecalcFillingOfPolygon(usedSlotsIn_verticesGlobal, up_normalized, scaledDistanceBetweenLines); + for (int i = 0; i < usedSlotsInFillEdgesList; i++) + { + UtilitiesDXXL_DrawBasics.Line(fillEdges[i].start, fillEdges[i].end, color, 0.0f, null, fillStyle, stylePatternScaleFactor, 0.0f, null, shapePlane, false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + } + else + { + Debug.Log("Fillstyle '" + fillStyle + "' is only supported for convex shapes, so not for '" + baseShape + "'."); + } + } + } + + static Vector3[] _64precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward = new Vector3[] { new Vector3(0f, 0f, 1f), new Vector3(0.09801714f, 0f, 0.9951847f), new Vector3(0.1950903f, 0f, 0.9807853f), new Vector3(0.2902847f, 0f, 0.9569404f), new Vector3(0.3826834f, 0f, 0.9238795f), new Vector3(0.4713968f, 0f, 0.8819212f), new Vector3(0.5555702f, 0f, 0.8314697f), new Vector3(0.6343933f, 0f, 0.7730104f), new Vector3(0.7071068f, 0f, 0.7071067f), new Vector3(0.7730104f, 0f, 0.6343933f), new Vector3(0.8314696f, 0f, 0.5555702f), new Vector3(0.8819213f, 0f, 0.4713967f), new Vector3(0.9238795f, 0f, 0.3826834f), new Vector3(0.9569404f, 0f, 0.2902846f), new Vector3(0.9807853f, 0f, 0.1950902f), new Vector3(0.9951848f, 0f, 0.0980171f), new Vector3(1.0f, 0f, 0f), new Vector3(0.9951847f, 0f, -0.09801733f), new Vector3(0.9807853f, 0f, -0.1950903f), new Vector3(0.9569404f, 0f, -0.2902846f), new Vector3(0.9238795f, 0f, -0.3826835f), new Vector3(0.8819212f, 0f, -0.4713969f), new Vector3(0.8314695f, 0f, -0.5555704f), new Vector3(0.7730105f, 0f, -0.6343933f), new Vector3(0.7071068f, 0f, -0.7071067f), new Vector3(0.6343932f, 0f, -0.7730104f), new Vector3(0.5555702f, 0f, -0.8314697f), new Vector3(0.4713966f, 0f, -0.8819213f), new Vector3(0.3826833f, 0f, -0.9238796f), new Vector3(0.2902847f, 0f, -0.9569403f), new Vector3(0.1950903f, 0f, -0.9807853f), new Vector3(0.09801709f, 0f, -0.9951847f), new Vector3(0f, 0f, -1f), new Vector3(-0.09801727f, 0f, -0.9951847f), new Vector3(-0.1950905f, 0f, -0.9807853f), new Vector3(-0.2902849f, 0f, -0.9569403f), new Vector3(-0.3826834f, 0f, -0.9238794f), new Vector3(-0.4713968f, 0f, -0.8819213f), new Vector3(-0.5555703f, 0f, -0.8314694f), new Vector3(-0.6343934f, 0f, -0.7730104f), new Vector3(-0.7071069f, 0f, -0.7071067f), new Vector3(-0.7730104f, 0f, -0.6343933f), new Vector3(-0.8314698f, 0f, -0.5555701f), new Vector3(-0.8819213f, 0f, -0.4713967f), new Vector3(-0.9238797f, 0f, -0.3826832f), new Vector3(-0.9569404f, 0f, -0.2902846f), new Vector3(-0.9807853f, 0f, -0.1950904f), new Vector3(-0.9951848f, 0f, -0.09801698f), new Vector3(-1.0f, 0f, 0f), new Vector3(-0.9951847f, 0f, 0.09801739f), new Vector3(-0.9807853f, 0f, 0.1950904f), new Vector3(-0.9569402f, 0f, 0.2902851f), new Vector3(-0.9238795f, 0f, 0.3826835f), new Vector3(-0.8819213f, 0f, 0.4713967f), new Vector3(-0.8314695f, 0f, 0.5555705f), new Vector3(-0.7730104f, 0f, 0.6343933f), new Vector3(-0.7071066f, 0f, 0.707107f), new Vector3(-0.6343932f, 0f, 0.7730105f), new Vector3(-0.5555703f, 0f, 0.8314695f), new Vector3(-0.4713965f, 0f, 0.8819214f), new Vector3(-0.3826834f, 0f, 0.9238796f), new Vector3(-0.2902844f, 0f, 0.9569404f), new Vector3(-0.1950902f, 0f, 0.9807853f), new Vector3(-0.09801676f, 0f, 0.9951848f) }; + static Vector3[] _32precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward = new Vector3[] { new Vector3(0f, 0f, 1f), new Vector3(0.1950903f, 0f, 0.9807853f), new Vector3(0.3826834f, 0f, 0.9238795f), new Vector3(0.5555702f, 0f, 0.8314697f), new Vector3(0.7071068f, 0f, 0.7071067f), new Vector3(0.8314696f, 0f, 0.5555702f), new Vector3(0.9238795f, 0f, 0.3826834f), new Vector3(0.9807853f, 0f, 0.1950902f), new Vector3(1.0f, 0f, 0f), new Vector3(0.9807853f, 0f, -0.1950903f), new Vector3(0.9238795f, 0f, -0.3826835f), new Vector3(0.8314695f, 0f, -0.5555704f), new Vector3(0.7071068f, 0f, -0.7071067f), new Vector3(0.5555702f, 0f, -0.8314697f), new Vector3(0.3826833f, 0f, -0.9238796f), new Vector3(0.1950903f, 0f, -0.9807853f), new Vector3(0f, 0f, -1f), new Vector3(-0.1950905f, 0f, -0.9807853f), new Vector3(-0.3826834f, 0f, -0.9238794f), new Vector3(-0.5555703f, 0f, -0.8314694f), new Vector3(-0.7071069f, 0f, -0.7071067f), new Vector3(-0.8314698f, 0f, -0.5555701f), new Vector3(-0.9238797f, 0f, -0.3826832f), new Vector3(-0.9807853f, 0f, -0.1950904f), new Vector3(-1.0f, 0f, 0f), new Vector3(-0.9807853f, 0f, 0.1950904f), new Vector3(-0.9238795f, 0f, 0.3826835f), new Vector3(-0.8314695f, 0f, 0.5555705f), new Vector3(-0.7071066f, 0f, 0.707107f), new Vector3(-0.5555703f, 0f, 0.8314695f), new Vector3(-0.3826834f, 0f, 0.9238796f), new Vector3(-0.1950902f, 0f, 0.9807853f) }; + static Vector3[] _32precalcedUnitCirclePoints_aroundOrigin_insideZPlane_startingAtUpward_clockwiseWhenLookingAlongZForward = new Vector3[] { new Vector3(0f, 1f, 0f), new Vector3(0.1950903f, 0.9807853f, 0f), new Vector3(0.3826834f, 0.9238795f, 0f), new Vector3(0.5555702f, 0.8314697f, 0f), new Vector3(0.7071068f, 0.7071067f, 0f), new Vector3(0.8314696f, 0.5555702f, 0f), new Vector3(0.9238795f, 0.3826834f, 0f), new Vector3(0.9807853f, 0.1950902f, 0f), new Vector3(1.0f, 0f, 0f), new Vector3(0.9807853f, -0.1950903f, 0f), new Vector3(0.9238795f, -0.3826835f, 0f), new Vector3(0.8314695f, -0.5555704f, 0f), new Vector3(0.7071068f, -0.7071067f, 0f), new Vector3(0.5555702f, -0.8314697f, 0f), new Vector3(0.3826833f, -0.9238796f, 0f), new Vector3(0.1950903f, -0.9807853f, 0f), new Vector3(0f, -1f, 0f), new Vector3(-0.1950905f, -0.9807853f, 0f), new Vector3(-0.3826834f, -0.9238794f, 0f), new Vector3(-0.5555703f, -0.8314694f, 0f), new Vector3(-0.7071069f, -0.7071067f, 0f), new Vector3(-0.8314698f, -0.5555701f, 0f), new Vector3(-0.9238797f, -0.3826832f, 0f), new Vector3(-0.9807853f, -0.1950904f, 0f), new Vector3(-1.0f, 0f, 0f), new Vector3(-0.9807853f, 0.1950904f, 0f), new Vector3(-0.9238795f, 0.3826835f, 0f), new Vector3(-0.8314695f, 0.5555705f, 0f), new Vector3(-0.7071066f, 0.707107f, 0f), new Vector3(-0.5555703f, 0.8314695f, 0f), new Vector3(-0.3826834f, 0.9238796f, 0f), new Vector3(-0.1950902f, 0.9807853f, 0f) }; + static Vector3[] _10precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward = new Vector3[] { new Vector3(0f, 0f, 1f), new Vector3(0.5877853f, 0f, 0.809017f), new Vector3(0.9510565f, 0f, 0.309017f), new Vector3(0.9510565f, 0f, -0.3090172f), new Vector3(0.5877852f, 0f, -0.8090171f), new Vector3(0f, 0f, -1f), new Vector3(-0.5877855f, 0f, -0.8090168f), new Vector3(-0.9510564f, 0f, -0.3090171f), new Vector3(-0.9510565f, 0f, 0.3090172f), new Vector3(-0.5877853f, 0f, 0.8090169f) }; + static Vector3[] _8precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward = new Vector3[] { new Vector3(0f, 0f, 1f), new Vector3(0.7071068f, 0f, 0.7071067f), new Vector3(1f, 0f, 0f), new Vector3(0.7071068f, 0f, -0.7071067f), new Vector3(0f, 0f, -1f), new Vector3(-0.7071069f, 0f, -0.7071067f), new Vector3(-1f, 0f, 0f), new Vector3(-0.7071066f, 0f, 0.707107f) }; + static Vector3[] _7precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward = new Vector3[] { new Vector3(0f, 0f, 1f), new Vector3(0.7818314f, 0f, 0.6234899f), new Vector3(0.974928f, 0f, -0.2225208f), new Vector3(0.4338838f, 0f, -0.9009688f), new Vector3(-0.4338835f, 0f, -0.900969f), new Vector3(-0.9749281f, 0f, -0.2225206f), new Vector3(-0.7818316f, 0f, 0.6234897f) }; + static Vector3[] _6precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward = new Vector3[] { new Vector3(0f, 0f, 1f), new Vector3(0.8660254f, 0f, 0.5f), new Vector3(0.8660254f, 0f, -0.5f), new Vector3(0f, 0f, -1f), new Vector3(-0.8660255f, 0f, -0.5f), new Vector3(-0.8660255f, 0f, 0.5f) }; + static Vector3[] _5precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward = new Vector3[] { new Vector3(0f, 0f, 1f), new Vector3(0.9510565f, 0f, 0.309017f), new Vector3(0.5877852f, 0f, -0.8090171f), new Vector3(-0.5877855f, 0f, -0.8090168f), new Vector3(-0.9510565f, 0f, 0.3090172f) }; + static Vector3[] _4precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward = new Vector3[] { new Vector3(0f, 0f, 1f), new Vector3(1f, 0f, 0f), new Vector3(0f, 0f, -1f), new Vector3(-1f, 0f, 0f) }; + static Vector3[] _3precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward = new Vector3[] { new Vector3(0f, 0f, 1f), new Vector3(0.8660254f, 0f, -0.5f), new Vector3(-0.8660255f, 0f, -0.5f) }; + + static bool TryFillPrecalcedUnitCirclePointsList(int requestedNumberOfPolygonCorners) + { + //-> this function returns "requestedAmountOfCorners_hasPrecalcedPoints" + + switch (requestedNumberOfPolygonCorners) + { + case 3: + for (int i = 0; i < 3; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward, _3precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i], i); + } + return true; + case 4: + for (int i = 0; i < 4; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward, _4precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i], i); + } + return true; + case 5: + for (int i = 0; i < 5; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward, _5precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i], i); + } + return true; + case 6: + for (int i = 0; i < 6; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward, _6precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i], i); + } + return true; + case 7: + for (int i = 0; i < 7; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward, _7precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i], i); + } + return true; + case 8: + for (int i = 0; i < 8; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward, _8precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i], i); + } + return true; + case 10: + for (int i = 0; i < 10; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward, _10precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i], i); + } + return true; + case 32: + for (int i = 0; i < 32; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref precalcedUnitCirclePoints_forCurrentlyRequestedFlexNumberedFlatPolygon_aroundOrigin_insideYPlane_startingWithFirstVertexAtZForward_clockwiseWhenLookingDownward, _32precalcedUnitCirclePoints_aroundOrigin_insideYPlane_startingAtZForward_clockwiseWhenLookingDownward[i], i); + } + return true; + default: + return false; + } + } + + static bool Shape2DisConvex(DrawShapes.Shape2DType shapeToCheck) + { + switch (shapeToCheck) + { + case DrawShapes.Shape2DType.star3: + return false; + + case DrawShapes.Shape2DType.star4: + return false; + + case DrawShapes.Shape2DType.star5: + return false; + + case DrawShapes.Shape2DType.star6: + return false; + + case DrawShapes.Shape2DType.star8: + return false; + + case DrawShapes.Shape2DType.star10: + return false; + + case DrawShapes.Shape2DType.star16: + return false; + + case DrawShapes.Shape2DType.star32: + return false; + + case DrawShapes.Shape2DType.star64: + return false; + + default: + return true; + } + } + + static void ScaleX(ref List verticesToScale, float scaleFactor, int usedSlotsInList) + { + for (int i = 0; i < usedSlotsInList; i++) + { + Vector3 projectionOntoXPlane = new Vector3(0.0f, verticesToScale[i].y, verticesToScale[i].z); + Vector3 from_projectionOntoXPlane_to_unscaledPos = verticesToScale[i] - projectionOntoXPlane; + verticesToScale[i] = projectionOntoXPlane + from_projectionOntoXPlane_to_unscaledPos * scaleFactor; + } + } + + static void ScaleY(ref List verticesToScale, float scaleFactor, int usedSlotsInList) + { + for (int i = 0; i < usedSlotsInList; i++) + { + Vector3 projectionOntoYPlane = new Vector3(verticesToScale[i].x, 0.0f, verticesToScale[i].z); + Vector3 from_projectionOntoYPlane_to_unscaledPos = verticesToScale[i] - projectionOntoYPlane; + verticesToScale[i] = projectionOntoYPlane + from_projectionOntoYPlane_to_unscaledPos * scaleFactor; + } + } + + static void ScaleZ(ref List verticesToScale, float scaleFactor, int usedSlotsInList) + { + for (int i = 0; i < usedSlotsInList; i++) + { + Vector3 projectionOntoZPlane = new Vector3(verticesToScale[i].x, verticesToScale[i].y, 0.0f); + Vector3 from_projectionOntoZPlane_to_unscaledPos = verticesToScale[i] - projectionOntoZPlane; + verticesToScale[i] = projectionOntoZPlane + from_projectionOntoZPlane_to_unscaledPos * scaleFactor; + } + } + + static void RotateVertices(ref List verticesToRotate, Quaternion rotation, int usedSlotsInList) + { + for (int i = 0; i < usedSlotsInList; i++) + { + verticesToRotate[i] = rotation * verticesToRotate[i]; + } + } + + public static Vector3 ForceVectorPerpToOtherVector(Vector3 vectorToForcePerp, InternalDXXL_Plane planePerpToOtherVector) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(vectorToForcePerp)) + { + return UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(planePerpToOtherVector.normalDir); + } + else + { + Vector3 vectorProjectedIntoPerpToOtherVectorPlane = planePerpToOtherVector.Get_projectionOfVectorOntoPlane(vectorToForcePerp); + vectorProjectedIntoPerpToOtherVectorPlane = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(vectorProjectedIntoPerpToOtherVectorPlane); + if (UtilitiesDXXL_Math.ApproximatelyZero(vectorProjectedIntoPerpToOtherVectorPlane)) + { + return UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(planePerpToOtherVector.normalDir); + } + else + { + return vectorProjectedIntoPerpToOtherVectorPlane; + } + } + } + + public static void ConvertQuaternionToFlatShapesNormalAndUpInsideFlatPlane(out Vector3 normal, out Vector3 up_insideFlatPlane, Quaternion quaternion) + { + if (UtilitiesDXXL_Math.IsDefaultInvalidQuaternion(quaternion)) + { + //-> will use "DrawShapes.automaticOrientationOfFlatShapes" + normal = default(Vector3); + up_insideFlatPlane = default(Vector3); + } + else + { + normal = quaternion * Vector3.forward; + up_insideFlatPlane = quaternion * Vector3.up; + } + } + + static float shapeFillDensity_before; + public static void Set_shapeFillDensity_reversible(float new_shapeFillDensity) + { + shapeFillDensity_before = DrawShapes.ShapeFillDensity; + DrawShapes.ShapeFillDensity = new_shapeFillDensity; + } + + public static void Reverse_shapeFillDensity() + { + DrawShapes.ShapeFillDensity = shapeFillDensity_before; + } + + static int linesPerSphereCircle_before; + public static void Set_linesPerSphereCircle_reversible(int new_linesPerSphereCircle) + { + linesPerSphereCircle_before = DrawShapes.LinesPerSphereCircle; + DrawShapes.LinesPerSphereCircle = new_linesPerSphereCircle; + } + + public static void Reverse_linesPerSphereCircle() + { + DrawShapes.LinesPerSphereCircle = linesPerSphereCircle_before; + } + + static float forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before; + public static void Set_forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_reversible(float new_forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes) + { + forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before = DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes; + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = new_forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes; + } + + public static void Reverse_forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes() + { + DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes = forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_before; + } + + static float forcedConstantWorldspaceTextSize_forTextAtShapes_before; + public static void Set_forcedConstantWorldspaceTextSize_forTextAtShapes_reversible(float new_forcedConstantWorldspaceTextSize_forTextAtShapes) + { + forcedConstantWorldspaceTextSize_forTextAtShapes_before = DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes; + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = new_forcedConstantWorldspaceTextSize_forTextAtShapes; + } + + public static void Reverse_forcedConstantWorldspaceTextSize_forTextAtShapes() + { + DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes = forcedConstantWorldspaceTextSize_forTextAtShapes_before; + } + + public static void Set_bothForcedConstantTextSizes_forTextAtShapes_reversible(float forScreenSpace, float forWorldspace) + { + Set_forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_reversible(forScreenSpace); + Set_forcedConstantWorldspaceTextSize_forTextAtShapes_reversible(forWorldspace); + } + + public static void Disable_bothForcedConstantTextSizes_forTextAtShapes_reversible() + { + Set_forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes_reversible(0.0f); + Set_forcedConstantWorldspaceTextSize_forTextAtShapes_reversible(0.0f); + } + + public static void Reverse_disable_bothForcedConstantTextSizes_forTextAtShapes() + { + Reverse_forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes(); + Reverse_forcedConstantWorldspaceTextSize_forTextAtShapes(); + } + + static void Copy_globalVertices_to_localVertices(Vector3 globalCenter, int numberOfSlotsToCopy) + { + for (int i = 0; i < numberOfSlotsToCopy; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, verticesGlobal[i] - globalCenter, i); + } + } + + static void Copy_customGlobalVertices_to_localVertices(ref List customGlobalVerticesListFromWhereToCopy, Vector3 globalCenter, int numberOfSlotsToCopy) + { + for (int i = 0; i < numberOfSlotsToCopy; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref verticesLocal, customGlobalVerticesListFromWhereToCopy[i] - globalCenter, i); + } + } + + static void Copy_localVertices_to_globalVertices(Vector3 globalCenter, int numberOfSlotsToCopy) + { + for (int i = 0; i < numberOfSlotsToCopy; i++) + { + UtilitiesDXXL_List.AddToAVectorList(ref verticesGlobal, globalCenter + verticesLocal[i], i); + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Shapes.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Shapes.cs.meta new file mode 100644 index 0000000..7a2d749 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Shapes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 908efcaf2bf63f94a8e29d2940217339 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Text.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Text.cs new file mode 100644 index 0000000..48d2659 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Text.cs @@ -0,0 +1,1979 @@ +namespace DrawXXL +{ + using System; + using UnityEngine; + using System.Collections.Generic; + + public class UtilitiesDXXL_Text + { + public static float relLineDistance = 1.6f; + public static float minTextSize = 0.00001f; + public static int maxRelStrokeWidth_inPPMofSize = 240000; + static float minRelBoldStrokeWidth = 0.16f; + static float maxRelBoldStrokeWidth = 0.36f; + static float italicIntensity = 0.6f; + static float minRadius = 0.0001f; + static Vector3 duplicateTriangle_LeftLeftUp_normalized = new Vector3(-0.8660254f, 0.5f, 0.0f); + static Vector3 duplicateTriangle_RightRightUp_normalized = new Vector3(0.8660254f, 0.5f, 0.0f); + static Vector3 duplicateTriangle_LeftLeftDown_normalized = new Vector3(-0.8660254f, -0.5f, 0.0f); + static Vector3 duplicateTriangle_RightRightDown_normalized = new Vector3(0.8660254f, -0.5f, 0.0f); + static Vector3 duplicateTriangle_LeftUpUp_normalized = new Vector3(-0.5f, 0.8660254f, 0.0f); + static Vector3 duplicateTriangle_RightUpUp_normalized = new Vector3(0.5f, 0.8660254f, 0.0f); + static Vector3 duplicateTriangle_LeftDownDown_normalized = new Vector3(-0.5f, -0.8660254f, 0.0f); + static Vector3 duplicateTriangle_RightDownDown_normalized = new Vector3(0.5f, -0.8660254f, 0.0f); + + //0/1 markups: + public static string lineBreakMarkupString = "
"; + public static string boldStartMarkupString = ""; + public static string boldEndMarkupString = ""; + public static string italicStartMarkupString = ""; + public static string italicEndMarkupString = ""; + public static string deletedStartMarkupString = ""; + public static string deletedEndMarkupString = ""; + public static string underlinedStartMarkupString = ""; + public static string underlinedEndMarkupString = ""; + //value markups: + public static string strokeWidthStartMarkupString_preValue = " chars = new List(); + static InternalDXXL_CharConfig autoLineBreakChar = new InternalDXXL_CharConfig(); + static int usedCharConfigListSlots; + static List relStrokeWidthMarkupPhases = new List(); + static List sizeMarkupPhases = new List(); + static List colorMarkupPhases = new List(); + static InternalDXXL_CharConfig.SetCharStyleProperty MarkAsBold_preAllocated = InternalDXXL_CharConfig.MarkAsBold; + static InternalDXXL_CharConfig.SetCharStyleProperty MarkAsItalic_preAllocated = InternalDXXL_CharConfig.MarkAsItalic; + static InternalDXXL_CharConfig.SetCharStyleProperty MarkAsDeleted_preAllocated = InternalDXXL_CharConfig.MarkAsDeleted; + static InternalDXXL_CharConfig.SetCharStyleProperty MarkAsUnderlined_preAllocated = InternalDXXL_CharConfig.MarkAsUnderlined; + + + public static void WriteFramed(string text, Vector3 position, Color color, float size, Quaternion rotation, DrawText.TextAnchorDXXL textAnchor, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextBlockEnlargementToThisMinWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth, float autoLineBreakWidth, bool autoFlipToPreventMirrorInverted, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + bool rotationIsValid = UtilitiesDXXL_TextDirAndUpCalculation.ConvertQuaternionToTextDirAndUpVectors(out Vector3 textDir, out Vector3 textUp, rotation); + bool skipDraw = false; //-> The called method has (almost) the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + Write(text, position, color, size, textDir, textUp, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, skipDraw, false, rotationIsValid); + } + + public static void WriteFramed(string text, Vector3 position, Color color, float size, Vector3 textDirection, Vector3 textUp, DrawText.TextAnchorDXXL textAnchor, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextBlockEnlargementToThisMinWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth, float autoLineBreakWidth, bool autoFlipToPreventMirrorInverted, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + bool skipDraw = false; //-> The called method has the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + Write(text, position, color, size, textDirection, textUp, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, skipDraw, false, false); + } + + public static void Write2DFramed(string text, Vector2 position, Color color, float size, Vector2 textDirection, DrawText.TextAnchorDXXL textAnchor, float custom_zPos, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextBlockEnlargementToThisMinWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth, float autoLineBreakWidth, bool autoFlipToPreventMirrorInverted, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 positionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(position, zPos); + Vector3 textDirV3 = UtilitiesDXXL_DrawBasics2D.Direction_V2toV3(textDirection); + Vector3 textUpV3 = Vector3.Cross(Vector3.forward, textDirV3); + + bool skipDraw = false; //-> "skipDraw" can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + Write(text, positionV3, color, size, textDirV3, textUpV3, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, skipDraw, true, false); + } + + public static void Write2DFramed(string text, Vector2 position, Color color, float size, float zRotationDegCC, DrawText.TextAnchorDXXL textAnchor, float custom_zPos, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextBlockEnlargementToThisMinWidth, float forceRestrictTextBlockSizeToThisMaxTextWidth, float autoLineBreakWidth, bool autoFlipToPreventMirrorInverted, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 positionV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(position, zPos); + Quaternion rotation = UtilitiesDXXL_DrawBasics2D.QuaternionFromAngle(zRotationDegCC); + Vector3 textDirV3 = rotation * Vector3.right; + Vector3 textUpV3 = Vector3.Cross(Vector3.forward, textDirV3); + + bool skipDraw = false; //-> "skipDraw" can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + Write(text, positionV3, color, size, textDirV3, textUpV3, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextBlockEnlargementToThisMinWidth, forceRestrictTextBlockSizeToThisMaxTextWidth, autoLineBreakWidth, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, skipDraw, true, true); + } + + public static void WriteScreenSpace(Camera camera, string text, Vector2 position, Color color, float size_relToViewportHeight, Vector2 textDirection, DrawText.TextAnchorDXXL textAnchor, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextEnlargementToThisMinWidth_relToViewportWidth, float forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth, bool autoLineBreakAtScreenBorder, float autoLineBreakWidth_relToViewportWidth, bool autoFlipTextToPreventUpsideDown, float durationInSec, bool skipDraw) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textDirection, "textDirection")) { return; } + + if (InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportWithPadding(position, 6.0f)) { return; } + if (InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportXWithPadding(position, 2.0f) && InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportYWithPadding(position, 2.0f)) { return; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(textDirection)) + { + textDirection = Vector3.right; + } + + float zRotationDegCC = Vector2.Angle(Vector2.right, textDirection); + if (textDirection.y < 0.0f) + { + zRotationDegCC = -zRotationDegCC; + } + WriteScreenspace(camera, text, position, color, size_relToViewportHeight, zRotationDegCC, textAnchor, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextEnlargementToThisMinWidth_relToViewportWidth, forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth, autoLineBreakAtScreenBorder, autoLineBreakWidth_relToViewportWidth, autoFlipTextToPreventUpsideDown, durationInSec, skipDraw); + } + + public static void WriteScreenspace(Camera camera, string text, Vector2 position, Color color, float size_relToViewportHeight, float zRotationDegCC, DrawText.TextAnchorDXXL textAnchor, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextEnlargementToThisMinWidth_relToViewportWidth, float forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth, bool autoLineBreakAtScreenBorder, float autoLineBreakWidth_relToViewportWidth, bool autoFlipTextToPreventUpsideDown, float durationInSec, bool skipDraw) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(camera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size_relToViewportHeight, "size_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(zRotationDegCC, "zRotationDegCC")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(forceTextEnlargementToThisMinWidth_relToViewportWidth, "forceTextEnlargementToThisMinWidth_relToViewportWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth, "forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(autoLineBreakWidth_relToViewportWidth, "autoLineBreakWidth_relToViewportWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + + if (InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportWithPadding(position, 6.0f)) { return; } + if (InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportXWithPadding(position, 2.0f) && InternalDXXL_BoundsCamViewportSpace.IsOutsideViewportYWithPadding(position, 2.0f)) { return; } + + Vector3 pos_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(camera, position, false); + float size_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, position, false, size_relToViewportHeight); + + float forceTextEnlargementToThisMinWidth_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(forceTextEnlargementToThisMinWidth_relToViewportWidth) == false) + { + forceTextEnlargementToThisMinWidth_worldSpace = UtilitiesDXXL_Screenspace.HorizExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, position, false, forceTextEnlargementToThisMinWidth_relToViewportWidth); + } + + float forceRestrictTextSizeToThisMaxTextWidth_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth) == false) + { + forceRestrictTextSizeToThisMaxTextWidth_worldSpace = UtilitiesDXXL_Screenspace.HorizExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, position, false, forceRestrictTextSizeToThisMaxTextWidth_relToViewportWidth); + } + + autoLineBreakWidth_relToViewportWidth = GetCapped_autoLineBreakWidth_relToViewportWidth(camera, autoLineBreakAtScreenBorder, autoLineBreakWidth_relToViewportWidth, position, textAnchor, zRotationDegCC); + float autoLineBreakWidth_worldSpace = 0.0f; + if (UtilitiesDXXL_Math.ApproximatelyZero(autoLineBreakWidth_relToViewportWidth) == false) + { + autoLineBreakWidth_worldSpace = UtilitiesDXXL_Screenspace.HorizExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, position, false, autoLineBreakWidth_relToViewportWidth); + } + + Quaternion rotation_aroundCamForward = Quaternion.AngleAxis(zRotationDegCC, camera.transform.forward); + Vector3 textDir_worldSpace_normalized = rotation_aroundCamForward * camera.transform.right; + Vector3 textUp_worldSpace_normalized = Vector3.Cross(camera.transform.forward, textDir_worldSpace_normalized); + + enclosingBoxLineStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(enclosingBoxLineStyle); + UtilitiesDXXL_TextDirAndUpCalculation.TryAutoFlipScreenspaceTextToPreventUpsideDown(out DrawText.TextAnchorDXXL textAnchor_postFlip, out Vector3 textDir_worldSpace_normalized_postFlip, out Vector3 textUp_worldSpace_normalized_postFlip, textAnchor, textDir_worldSpace_normalized, textUp_worldSpace_normalized, autoFlipTextToPreventUpsideDown, camera); + + Write(text, pos_worldSpace, color, size_worldSpace, textDir_worldSpace_normalized_postFlip, textUp_worldSpace_normalized_postFlip, textAnchor_postFlip, enclosingBoxLineStyle, enclosingBox_lineWidth_relToTextSize, enclosingBox_paddingSize_relToTextSize, forceTextEnlargementToThisMinWidth_worldSpace, forceRestrictTextSizeToThisMaxTextWidth_worldSpace, autoLineBreakWidth_worldSpace, false, durationInSec, false, skipDraw, false, true); + ConvertParsedSpecs_toViewportSpace(camera, position, pos_worldSpace, textDir_worldSpace_normalized, textUp_worldSpace_normalized); + } + + public static void Write(string text, Vector3 position, Color color, float size, Vector3 textDirection, Vector3 textUp, DrawText.TextAnchorDXXL textAnchor, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_lineWidth_relToTextSize, float enclosingBox_paddingSize_relToTextSize, float forceTextEnlargementToThisMinWidth, float forceRestrictTextSizeToThisMaxTextWidth, float autoLineBreakWidth, bool autoFlipToPreventMirrorInverted, float durationInSec, bool hiddenByNearerObjects, bool skipDraw, bool isFrom_Write2D, bool dirAndUp_areAlreadyGuaranteed_perpAndNormalized) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + DrawText.parsedTextSpecs.widthOfLongestLine = 0.0f; + DrawText.parsedTextSpecs.numberOfChars_inLongestLine = 0; + DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine = 0.0f; + DrawText.parsedTextSpecs.height_wholeTextBlock = 0.0f; + DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine = 0.0f; + DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine = default; + DrawText.parsedTextSpecs.used_textDirection_normalized = default; + DrawText.parsedTextSpecs.used_textUp_normalized = default; + DrawText.parsedTextSpecs.usedTextAnchor = textAnchor; + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size, "size")) { return; } + DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine = size; + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(enclosingBox_lineWidth_relToTextSize, "enclosingBox_lineWidth_relToTextSize")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(enclosingBox_paddingSize_relToTextSize, "enclosingBox_paddingSize_relToTextSize")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(forceTextEnlargementToThisMinWidth, "forceTextEnlargementToThisMinWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(forceRestrictTextSizeToThisMaxTextWidth, "forceRestrictTextSizeToThisMaxTextWidth")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(autoLineBreakWidth, "autoLineBreakWidth")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(position, "position")) { return; } + DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine = position; + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textDirection, "textDirection")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textUp, "textUp")) { return; } + + if (text == null) + { + Debug.Log("Draw XXL: 'Write' (and parsing) is skipped, because 'text' is 'null'."); + return; + } + + if (text.Length == 0) + { + Debug.Log("Draw XXL: 'Write' (and parsing) is skipped, because 'text' has zero characters."); + return; + } + + size = UtilitiesDXXL_Math.AbsNonZeroValue(size); + if (size < minTextSize) + { + //preventing undefined behaviour in the region of calculation errors of very small float values. + //DO NOT fallback to "Point()" here, because "Point()" calls "Write()" again, which can create an endless loop. + Debug.Log("Draw XXL: 'Write' (and parsing) is skipped, because 'size' (" + size + ") is too small. The minimum text size is " + minTextSize + "."); + return; + } + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + forceTextEnlargementToThisMinWidth = UtilitiesDXXL_Math.AbsNonZeroValue(forceTextEnlargementToThisMinWidth); + forceRestrictTextSizeToThisMaxTextWidth = UtilitiesDXXL_Math.AbsNonZeroValue(forceRestrictTextSizeToThisMaxTextWidth); + + CreateCharConfigs(text, color, size); + InsertLineBreaks_fromRichTextMarkups(text); + SwitchTextStyle(text, boldStartMarkupString, boldEndMarkupString, MarkAsBold_preAllocated); + SwitchTextStyle(text, italicStartMarkupString, italicEndMarkupString, MarkAsItalic_preAllocated); + SwitchTextStyle(text, deletedStartMarkupString, deletedEndMarkupString, MarkAsDeleted_preAllocated); + SwitchTextStyle(text, underlinedStartMarkupString, underlinedEndMarkupString, MarkAsUnderlined_preAllocated); + + UtilitiesDXXL_TextDirAndUpCalculation.GetTextDirAndUpNormalized(out Vector3 textDirNormalized_preFlip, out Vector3 textUpNormalized_preFlip, textDirection, textUp, position, isFrom_Write2D, dirAndUp_areAlreadyGuaranteed_perpAndNormalized); + Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip = Vector3.Cross(textDirNormalized_preFlip, textUpNormalized_preFlip); + Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip; + UtilitiesDXXL_TextDirAndUpCalculation.TryAutoFlipStraightTextToPreventMirrorInverted(out textAnchor, out Vector3 textDirNormalized_postFlip, out Vector3 textUpNormalized_postFlip, out forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, textAnchor, textDirNormalized_preFlip, textUpNormalized_preFlip, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip, position, autoFlipToPreventMirrorInverted); + DrawText.parsedTextSpecs.used_textDirection_normalized = textDirNormalized_postFlip; + DrawText.parsedTextSpecs.used_textUp_normalized = textUpNormalized_postFlip; + + int usedSlotsInListOf_relStrokeWidthMarkupPhases = GetMarkupPhases(ref relStrokeWidthMarkupPhases, text, strokeWidthStartMarkupString_preValue, strokeWidthEndMarkupString); + Quaternion rotationOfChars = Quaternion.LookRotation(forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, textUpNormalized_postFlip); + AssignStrokeWidthOffsets(usedSlotsInListOf_relStrokeWidthMarkupPhases, size, rotationOfChars, skipDraw); + int usedSlotsInListOf_sizeMarkupPhases = GetMarkupPhases(ref sizeMarkupPhases, text, sizeStartMarkupString_preValue, sizeEndMarkupString); + ScaleSize_perChar(usedSlotsInListOf_sizeMarkupPhases, size); + int usedSlotsInListOf_colorMarkupPhases = GetMarkupPhases(ref colorMarkupPhases, text, colorStartMarkupString_preValue, colorEndMarkupString); + ApplyColor(usedSlotsInListOf_colorMarkupPhases, skipDraw); + InsertIcons(text); + InsertLineBreaks_fromEscapedUnicodeChars(); + + if (GetNumberOfNonStrippedChars() <= 0) + { + Debug.Log("Draw XXL: 'Write' is skipped, because there are no chars left after parsing. Unparsed text: " + text); + return; + } + + InsertLineBreaks_fromMaxTextBlockWidthParameter(autoLineBreakWidth, size); + FillParsedTextSpecs(); + + float scaleFactorFromForceWholeTextBlockWidth = ForceTextWidth(forceTextEnlargementToThisMinWidth, forceRestrictTextSizeToThisMaxTextWidth); + DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine = GetLowLeftPosOfFirstLine(position, textAnchor, textDirNormalized_postFlip, textUpNormalized_postFlip); + DrawEncapsulatingBox(skipDraw, size, scaleFactorFromForceWholeTextBlockWidth, color, textDirNormalized_postFlip, textUpNormalized_postFlip, enclosingBoxLineStyle, enclosingBox_paddingSize_relToTextSize, enclosingBox_lineWidth_relToTextSize, durationInSec, hiddenByNearerObjects); + if (skipDraw) { return; } + PrintChars(DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine, textDirNormalized_postFlip, textUpNormalized_postFlip, rotationOfChars, durationInSec, hiddenByNearerObjects); + } + + public static void WriteOnCircleScreenspace(Camera camera, string text, Vector2 circleCenterPosition, float radius_relToViewportHeight, Color color, float size_relToViewportHeight, Vector2 textsInitialUp, DrawText.TextAnchorCircledDXXL textAnchor, float autoLineBreakAngleDeg, float durationInSec, bool skipDraw) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textsInitialUp, "textsInitialUp")) { return; } + + if (UtilitiesDXXL_Math.ApproximatelyZero(textsInitialUp)) + { + textsInitialUp = Vector3.up; + } + + float initial_zRotationDeg_fromCamUp = Vector2.Angle(Vector2.up, textsInitialUp); + if (textsInitialUp.x > 0.0f) + { + initial_zRotationDeg_fromCamUp = -initial_zRotationDeg_fromCamUp; + } + + WriteOnCircleScreenspace(camera, text, circleCenterPosition, radius_relToViewportHeight, color, size_relToViewportHeight, initial_zRotationDeg_fromCamUp, textAnchor, autoLineBreakAngleDeg, durationInSec, skipDraw); + } + + public static void WriteOnCircleScreenspace(Camera camera, string text, Vector2 circleCenterPosition, float radius_relToViewportHeight, Color color, float size_relToViewportHeight, float initialTextDir_as_zRotationDegCCfromCamUp, DrawText.TextAnchorCircledDXXL textAnchor, float autoLineBreakAngleDeg, float durationInSec, bool skipDraw) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(camera, "camera")) { return; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(camera)) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius_relToViewportHeight, "radius_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size_relToViewportHeight, "size_relToViewportHeight")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(initialTextDir_as_zRotationDegCCfromCamUp, "initialTextDir_as_zRotationDegCCfromCamUp")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenterPosition, "circleCenterPosition")) { return; } + + Quaternion rotation_toInitialUp_inAspectCorrected1by1SquareViewportSpace = Quaternion.AngleAxis(initialTextDir_as_zRotationDegCCfromCamUp, Vector3.forward); + Vector2 initialUp_inAspectCorrected1by1SquareViewportSpace_normalized = rotation_toInitialUp_inAspectCorrected1by1SquareViewportSpace * Vector2.up; + //"approx", because radius is always used as "_relToViewportHeight" instead of correcting for non-uniform (non-1by1) viewport rects: + Vector2 approxStartPos_inAspectCorrected1by1SquareViewportSpace = circleCenterPosition + initialUp_inAspectCorrected1by1SquareViewportSpace_normalized * radius_relToViewportHeight; + Quaternion initialUpsRotation_aroundCamForward_worldSpace = Quaternion.AngleAxis(initialTextDir_as_zRotationDegCCfromCamUp, camera.transform.forward); + Vector3 textsInitialUp_worldSpace_normalized = initialUpsRotation_aroundCamForward_worldSpace * camera.transform.up; + Vector3 textsInitialDir_worldSpace_normalized = Vector3.Cross(textsInitialUp_worldSpace_normalized, camera.transform.forward); + float size_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, approxStartPos_inAspectCorrected1by1SquareViewportSpace, false, size_relToViewportHeight); + float radius_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(camera, approxStartPos_inAspectCorrected1by1SquareViewportSpace, false, radius_relToViewportHeight); + Vector3 circleCenterPosition_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(camera, circleCenterPosition, false); + WriteOnCircle(text, circleCenterPosition_worldSpace, radius_worldSpace, color, size_worldSpace, textsInitialDir_worldSpace_normalized, textsInitialUp_worldSpace_normalized, textAnchor, autoLineBreakAngleDeg, false, durationInSec, false, skipDraw, false, true); + ConvertParsedSpecsOnCircle_toViewportSpace(camera, circleCenterPosition_worldSpace, textsInitialUp_worldSpace_normalized, radius_worldSpace, approxStartPos_inAspectCorrected1by1SquareViewportSpace); + } + + public static void WriteOnCircle(string text, Vector3 textStartPos, Vector3 circleCenterPosition, Vector3 turnAxis_direction = default(Vector3), Color color = default(Color), float size = 0.1f, DrawText.TextAnchorCircledDXXL textAnchor = DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, float autoLineBreakAngleDeg = 0.0f, bool autoFlipToPreventMirrorInverted = true, float durationInSec = 0.0f, bool hiddenByNearerObjects = true) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textStartPos, "textStartPos")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenterPosition, "circleCenterPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(turnAxis_direction, "turnAxis_direction")) { return; } + + Vector3 textsInitialUp = textStartPos - circleCenterPosition; + Vector3 textsInitialUp_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(textsInitialUp, out float radius); //-> normalizing is actually not necessary here, but is also no problem, since length/magnitude is needed for the radius anyway + Vector3 textsInitialDir = Vector3.Cross(textsInitialUp_normalized, turnAxis_direction); + textsInitialDir = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(textsInitialDir); + + bool skipDraw = false; //-> The called method has (almost) the same parameters and can be used interchangeably, except that it has the additional parameter "skipDraw". This can be set to 'true' if only the 'parsedTextSpecs' should be filled (e.g. as decision base for the final placement of the text via an additinal DrawText-call). + WriteOnCircle(text, circleCenterPosition, radius, color, size, textsInitialDir, textsInitialUp_normalized, textAnchor, autoLineBreakAngleDeg, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, skipDraw, false, false); + } + + public static void WriteOnCircle(string text, Vector3 circleCenterPosition, float radius, Color color, float size, Vector3 textsInitialDir, Vector3 textsInitialUp, DrawText.TextAnchorCircledDXXL textAnchor, float autoLineBreakAngleDeg, bool autoFlipToPreventMirrorInverted, float durationInSec, bool hiddenByNearerObjects, bool skipDraw, bool isFrom_Write2D, bool dirAndUp_areAlreadyGuaranteed_perpAndNormalized) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + + DrawText.parsedTextOnCircleSpecs.angleDegOfLongestLine = 0.0f; + DrawText.parsedTextOnCircleSpecs.numberOfChars_inLongestLine = 0; + DrawText.parsedTextOnCircleSpecs.numberOfChars_afterParsingOutTheMarkupTags = 0; + DrawText.parsedTextOnCircleSpecs.sizeOfBiggestCharInFirstLine = 0.0f; + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(size, "size")) { return; } + DrawText.parsedTextOnCircleSpecs.sizeOfBiggestCharInFirstLine = size; + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(radius, "radius")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(autoLineBreakAngleDeg, "autoLineBreakAngleDeg")) { return; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(circleCenterPosition, "circleCenterPosition")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textsInitialDir, "textsInitialDir")) { return; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(textsInitialUp, "textsInitialUp")) { return; } + + if (text == null) + { + Debug.Log("Draw XXL: 'WriteOnCircle' (and parsing) is skipped, because 'text' is 'null'."); + return; + } + + if (text.Length == 0) + { + Debug.Log("Draw XXL: 'WriteOnCircle' (and parsing) is skipped, because 'text' has zero characters."); + return; + } + + size = UtilitiesDXXL_Math.AbsNonZeroValue(size); + if (size < 0.00001f) + { + //preventing undefined behaviour in the region of calculation errors of very small float values. + Debug.LogWarning("Draw XXL: 'WriteOnCircle' is skipped, because 'size' (" + size + ") is too small."); + return; + } + + color = UtilitiesDXXL_Colors.OverwriteDefaultColor(color); + radius = Mathf.Abs(radius); + radius = Mathf.Max(radius, minRadius); + + CreateCharConfigs(text, color, size); + InsertLineBreaks_fromRichTextMarkups(text); + SwitchTextStyle(text, boldStartMarkupString, boldEndMarkupString, MarkAsBold_preAllocated); + SwitchTextStyle(text, italicStartMarkupString, italicEndMarkupString, MarkAsItalic_preAllocated); + SwitchTextStyle(text, deletedStartMarkupString, deletedEndMarkupString, MarkAsDeleted_preAllocated); + SwitchTextStyle(text, underlinedStartMarkupString, underlinedEndMarkupString, MarkAsUnderlined_preAllocated); + + int usedSlotsInListOf_relStrokeWidthMarkupPhases = GetMarkupPhases(ref relStrokeWidthMarkupPhases, text, strokeWidthStartMarkupString_preValue, strokeWidthEndMarkupString); + int usedSlotsInListOf_sizeMarkupPhases = GetMarkupPhases(ref sizeMarkupPhases, text, sizeStartMarkupString_preValue, sizeEndMarkupString); + ScaleSize_perChar(usedSlotsInListOf_sizeMarkupPhases, size); + int usedSlotsInListOf_colorMarkupPhases = GetMarkupPhases(ref colorMarkupPhases, text, colorStartMarkupString_preValue, colorEndMarkupString); + ApplyColor(usedSlotsInListOf_colorMarkupPhases, skipDraw); + InsertIcons(text); + InsertLineBreaks_fromEscapedUnicodeChars(); + + if (GetNumberOfNonStrippedChars() <= 0) + { + Debug.Log("Draw XXL: 'Write' is skipped, because there are no chars left after parsing. Unparsed text: " + text); + return; + } + + Assign_coveredAnglePerChar_onTheLineAtTheReferenceRadius(radius, size); + radius = TryShiftTheTextToOutwardsOfRadius_soItEndsOnTheCircleInsteadOfStartingThere(textAnchor, autoLineBreakAngleDeg, size, radius); + InsertLineBreaksOnCircle_fromMaxTextBlockAngleParameter(autoLineBreakAngleDeg, size, radius); + Assign_coveredAnglePerChar_onTheCharsOwnLine(radius, size); + FillParsedTextOnCircleSpecs(); + if (skipDraw) { return; } + + UtilitiesDXXL_TextDirAndUpCalculation.GetTextDirAndUpNormalized(out Vector3 initialTextDirNormalized_preFlip, out Vector3 initialTextUpNormalized_preFlip, textsInitialDir, textsInitialUp, circleCenterPosition, isFrom_Write2D, dirAndUp_areAlreadyGuaranteed_perpAndNormalized); + Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip = Vector3.Cross(initialTextDirNormalized_preFlip, initialTextUpNormalized_preFlip); + Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip; + UtilitiesDXXL_TextDirAndUpCalculation.TryAutoFlipCircledTextToPreventMirrorInverted(out Vector3 initialTextDirNormalized_postFlip, out Vector3 initialTextUpNormalized_postFlip, out forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, initialTextDirNormalized_preFlip, initialTextUpNormalized_preFlip, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip, circleCenterPosition, autoFlipToPreventMirrorInverted, DrawText.parsedTextOnCircleSpecs.angleDegOfLongestLine); + + AssignIndividualRotation(initialTextUpNormalized_postFlip, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip); + Quaternion initialRotationOfChars = Quaternion.LookRotation(forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, initialTextUpNormalized_postFlip); + AssignStrokeWidthOffsets(usedSlotsInListOf_relStrokeWidthMarkupPhases, size, initialRotationOfChars, skipDraw); + TurnStrokeWidthOffsetsOnCircle(); //-> could probably be skipped without big visual disadvantage + PrintCharsOnCircle(circleCenterPosition, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, initialTextUpNormalized_postFlip, radius, durationInSec, hiddenByNearerObjects); + } + + static void PrintChars(Vector3 position, Vector3 textDirNormalized, Vector3 textUpNormalized, Quaternion rotationOfChars, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 startPosOfCurrLine = position; + Vector3 lineStart_to_charStart = Vector3.zero; + + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + if (chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself > 0) + { + float sizeOfBiggestCharInUpcomingLine = GetBiggestCharSizeInsideLine(i_char + chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself); + startPosOfCurrLine = startPosOfCurrLine - textUpNormalized * sizeOfBiggestCharInUpcomingLine * relLineDistance; + lineStart_to_charStart = Vector3.zero; + for (int i_charOfLineBreakString = 1; i_charOfLineBreakString < chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself; i_charOfLineBreakString++) + { + i_char++; + } + } + else + { + if (chars[i_char].strippedDueToParsing == false) + { + chars[i_char].pos = startPosOfCurrLine + lineStart_to_charStart; + PrintChar(chars[i_char], rotationOfChars, durationInSec, hiddenByNearerObjects); + lineStart_to_charStart = lineStart_to_charStart + chars[i_char].size * textDirNormalized; + } + } + } + } + + static void PrintCharsOnCircle(Vector3 circleCenterPosition, Vector3 forward, Vector3 initialTextUpNormalized, float radius, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 circleCenter_to_startPosOfMostOuterLine = initialTextUpNormalized * radius; + Vector3 circleCenter_to_startPosOfCurrLine = circleCenter_to_startPosOfMostOuterLine; + float angleDeg_lineStartToCurrChar = 0.0f; + + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + if (chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself > 0) + { + float sizeOfBiggestCharInUpcomingLine = GetBiggestCharSizeInsideLine(i_char + chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself); + Vector3 circleCenter_to_startPosOfPrevLine = circleCenter_to_startPosOfCurrLine; + circleCenter_to_startPosOfCurrLine = circleCenter_to_startPosOfCurrLine - initialTextUpNormalized * sizeOfBiggestCharInUpcomingLine * relLineDistance; + if (UtilitiesDXXL_Math.Check_ifVectorsPointAwayFromEachOther_perpCountsAsPointingAwayFromEachOther(circleCenter_to_startPosOfPrevLine, circleCenter_to_startPosOfCurrLine)) + { + circleCenter_to_startPosOfCurrLine = circleCenter_to_startPosOfMostOuterLine.normalized * minRadius; + } + angleDeg_lineStartToCurrChar = 0.0f; + for (int i_charOfLineBreakString = 1; i_charOfLineBreakString < chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself; i_charOfLineBreakString++) + { + i_char++; + } + } + else + { + if (chars[i_char].strippedDueToParsing == false) + { + Quaternion rotation = Quaternion.AngleAxis(angleDeg_lineStartToCurrChar, -forward); + chars[i_char].pos = circleCenterPosition + rotation * circleCenter_to_startPosOfCurrLine; + PrintCharOnCircle(chars[i_char], forward, chars[i_char].charUp, durationInSec, hiddenByNearerObjects); + angleDeg_lineStartToCurrChar = angleDeg_lineStartToCurrChar + chars[i_char].coveredAngleDegOnOwnLine; + } + } + } + } + + static void PrintChar(InternalDXXL_CharConfig printedChar, Quaternion rotationOfChar, float durationInSec, bool hiddenByNearerObjects) + { + UtilitiesDXXL_CharsAndIcons.RefillCurrPrintedCharDef(printedChar, out printedChar.hasMissingSymbolDefinition); + ShearTowardsItalic(printedChar); + + for (int i = 0; i < DrawXXL_LinesManager.instance.numberOfStrokes_forCurrUsedChar; i++) + { + TurnCharDef(ref DrawXXL_LinesManager.instance.currPrinted_charDef[i], rotationOfChar); + } + DrawTurnedDistortedCurrCharDef(printedChar, durationInSec, hiddenByNearerObjects); + } + + static void PrintCharOnCircle(InternalDXXL_CharConfig printedChar, Vector3 forward, Vector3 charUp, float durationInSec, bool hiddenByNearerObjects) + { + UtilitiesDXXL_CharsAndIcons.RefillCurrPrintedCharDef(printedChar, out printedChar.hasMissingSymbolDefinition); + ShearTowardsItalic(printedChar); + + for (int i = 0; i < DrawXXL_LinesManager.instance.numberOfStrokes_forCurrUsedChar; i++) + { + TurnCharDef(ref DrawXXL_LinesManager.instance.currPrinted_charDef[i], forward, charUp); + } + DrawTurnedDistortedCurrCharDef(printedChar, durationInSec, hiddenByNearerObjects); + } + + static void DrawTurnedDistortedCurrCharDef(InternalDXXL_CharConfig printedChar, float durationInSec, bool hiddenByNearerObjects) + { + for (int i_stroke = 0; i_stroke < DrawXXL_LinesManager.instance.numberOfStrokes_forCurrUsedChar; i_stroke++) + { + int linesInsideCurrStroke = DrawXXL_LinesManager.instance.numberOfPointsForEachStroke_forCurrUsedChar[i_stroke] - 1; + for (int i_point = 0; i_point < linesInsideCurrStroke; i_point++) + { + for (int i_duplicatePrint = 0; i_duplicatePrint < printedChar.usedSlots_inDuplicatesPrintOffsetList; i_duplicatePrint++) + { + Vector3 lineStartPos = printedChar.pos + printedChar.duplicatesPrintOffsets[i_duplicatePrint] * printedChar.sizeScalingFactor + DrawXXL_LinesManager.instance.currPrinted_charDef[i_stroke][i_point] * printedChar.size; + Vector3 lineEndPos = printedChar.pos + printedChar.duplicatesPrintOffsets[i_duplicatePrint] * printedChar.sizeScalingFactor + DrawXXL_LinesManager.instance.currPrinted_charDef[i_stroke][i_point + 1] * printedChar.size; + Line_fadeableAnimSpeed.InternalDraw(lineStartPos, lineEndPos, printedChar.color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + } + } + + static void ShearTowardsItalic(InternalDXXL_CharConfig printedChar) + { + if (printedChar.italic) + { + for (int i_stroke = 0; i_stroke < DrawXXL_LinesManager.instance.numberOfStrokes_forCurrUsedChar; i_stroke++) + { + for (int i_lineSegment = 0; i_lineSegment < DrawXXL_LinesManager.instance.numberOfPointsForEachStroke_forCurrUsedChar[i_stroke]; i_lineSegment++) + { + DrawXXL_LinesManager.instance.currPrinted_charDef[i_stroke][i_lineSegment].x = DrawXXL_LinesManager.instance.currPrinted_charDef[i_stroke][i_lineSegment].x + DrawXXL_LinesManager.instance.currPrinted_charDef[i_stroke][i_lineSegment].y * italicIntensity; + } + } + } + } + + static void TurnCharDef(ref Vector3[] charDef, Vector3 forward, Vector3 textUpNormalized) + { + Quaternion rotation = Quaternion.LookRotation(forward, textUpNormalized); + for (int i = 0; i < charDef.Length; i++) + { + charDef[i] = rotation * charDef[i]; + } + } + + public static void TurnCharDef(ref Vector3[] charDef, Quaternion rotation) + { + //tested via profiler: no performance gain if default rotations are skipped from this multiplication + for (int i = 0; i < charDef.Length; i++) + { + charDef[i] = rotation * charDef[i]; + } + } + + public static void TurnCharDef(ref List charDef, int usedSlotsInList, Quaternion rotation) + { + //tested via profiler: no performance gain if default rotations are skipped from this multiplication + for (int i = 0; i < usedSlotsInList; i++) + { + charDef[i] = rotation * charDef[i]; + } + } + + static void CreateCharConfigs(string text, Color color, float size) + { + // int i_char_highestPossibleSlotOfAutoLineBreakChars = Mathf.Min(text.Length - 1, chars.Count - 1); //<-Cannot save iteration cycles like this, because if only "text.Length - 1" chars are checked for autoLineBreakChar-removal, then autoLineBreakChar's at higher positions can be moved into the relevant range, which again should be removed. + int i_char_highestPossibleSlotOfAutoLineBreakChars = chars.Count - 1; + for (int i_char = i_char_highestPossibleSlotOfAutoLineBreakChars; i_char >= 0; i_char--) + { + if (chars[i_char] == autoLineBreakChar) + { + chars.RemoveAt(i_char); + } + } + + for (int i_char = 0; i_char < text.Length; i_char++) + { + if (i_char < chars.Count) + { + InternalDXXL_CharConfig currChar = chars[i_char]; + currChar.character = text[i_char]; + currChar.size = size; + currChar.color = color; + currChar.hasMissingSymbolDefinition = false; + currChar.bold = false; + currChar.italic = false; + currChar.deleted = false; + currChar.underlined = false; + currChar.sizeScalingFactor = 1.0f; + currChar.sizeHasBeenScaledViaRichtextMarkup = false; + currChar.strippedDueToParsing = false; + currChar.numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself = 0; + currChar.isIcon = false; + } + else + { + InternalDXXL_CharConfig currChar = new InternalDXXL_CharConfig(); + currChar.character = text[i_char]; + currChar.size = size; + currChar.color = color; + chars.Add(currChar); + } + } + usedCharConfigListSlots = text.Length; + } + + static void InsertLineBreaks_fromRichTextMarkups(string text) + { + //lineBreaks from embedded richtext "
" strings: + int maxNumberOfLineBreaks = 5000; //-> preventing endless loops + int i_endOfCurrLineBreak = 0; + int i_startOfCurrLineBreak; + for (int i_lineBreak = 0; i_lineBreak < maxNumberOfLineBreaks; i_lineBreak++) + { + i_startOfCurrLineBreak = text.IndexOf(lineBreakMarkupString, i_endOfCurrLineBreak); + if (i_startOfCurrLineBreak >= i_endOfCurrLineBreak) + { + chars[i_startOfCurrLineBreak].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself = lineBreakMarkupString.Length; + i_endOfCurrLineBreak = i_startOfCurrLineBreak + (lineBreakMarkupString.Length - 1); + for (int i_char = i_startOfCurrLineBreak; i_char <= i_endOfCurrLineBreak; i_char++) + { + chars[i_char].strippedDueToParsing = true; + } + } + else + { + break; + } + } + } + + static bool SwitchTextStyle(string text, string startMarkingString, string endMarkingString, InternalDXXL_CharConfig.SetCharStyleProperty StyleAssigningFunction) + { + bool foundAtLeastOneMarkup = false; + int maxNumberOfMarkups = 10000; + int i_endOfCurrMarkupPhase = 0; + int i_startOfCurrMarkupPhase; + for (int i_markup = 0; i_markup < maxNumberOfMarkups; i_markup++) + { + i_startOfCurrMarkupPhase = text.IndexOf(startMarkingString, i_endOfCurrMarkupPhase); + if (i_startOfCurrMarkupPhase >= i_endOfCurrMarkupPhase) + { + i_endOfCurrMarkupPhase = text.IndexOf(endMarkingString, i_startOfCurrMarkupPhase); + if (i_endOfCurrMarkupPhase > i_startOfCurrMarkupPhase) + { + foundAtLeastOneMarkup = true; + for (int i_char = i_startOfCurrMarkupPhase; i_char < i_startOfCurrMarkupPhase + startMarkingString.Length; i_char++) + { + chars[i_char].strippedDueToParsing = true; + } + + for (int i_char = i_endOfCurrMarkupPhase; i_char < i_endOfCurrMarkupPhase + endMarkingString.Length; i_char++) + { + chars[i_char].strippedDueToParsing = true; + } + + for (int i_char = i_startOfCurrMarkupPhase; i_char <= i_endOfCurrMarkupPhase; i_char++) + { + InternalDXXL_CharConfig currChar = chars[i_char]; + StyleAssigningFunction(ref currChar); + } + } + else + { + break; + } + } + else + { + break; + } + } + + return foundAtLeastOneMarkup; + } + + static int GetMarkupPhases(ref List markupPhasesList, string text, string startMarkingString_preValue, string endMarkingString) + { + //returns "usedSlotsInList" + + int i_nextFreeSlotInMarkupPhaseList = 0; + int maxNumberOfMarkupPhases = 10000; + int maxNumberOfEnclosingMarkupPhases = 1000; + int i_startOfCurrMarkupPhase = text.IndexOf(startMarkingString_preValue, 0); + + for (int i_markup = 0; i_markup < maxNumberOfMarkupPhases; i_markup++) + { + if (i_startOfCurrMarkupPhase >= 0) + { + int i_startOfValue = i_startOfCurrMarkupPhase + startMarkingString_preValue.Length; + int i_closingBracketAfterValue = text.IndexOf(valueMarkupString_postValue, i_startOfValue); + if (i_closingBracketAfterValue > i_startOfValue) + { + int valueLength = i_closingBracketAfterValue - i_startOfValue; + string value = text.Substring(i_startOfValue, valueLength); + + int i_endOfCurrMarkupPhase = -1; + int i_startPosForSearchingNext_markupEnd = i_closingBracketAfterValue; + int i_startPosForSearchingNext_markupStart = i_closingBracketAfterValue; + for (int i = 0; i < maxNumberOfEnclosingMarkupPhases; i++) + { + int i_nextCurrMarkupPhaseEnd = text.IndexOf(endMarkingString, i_startPosForSearchingNext_markupEnd); + if (i_nextCurrMarkupPhaseEnd >= i_startPosForSearchingNext_markupEnd) + { + i_endOfCurrMarkupPhase = i_nextCurrMarkupPhaseEnd; + int i_nextMarkupPhaseStart = text.IndexOf(startMarkingString_preValue, i_startPosForSearchingNext_markupStart); + if (i_nextMarkupPhaseStart >= i_startPosForSearchingNext_markupStart) + { + if (i_nextMarkupPhaseStart < i_nextCurrMarkupPhaseEnd) + { + i_startPosForSearchingNext_markupEnd = i_nextCurrMarkupPhaseEnd + 1; + i_startPosForSearchingNext_markupStart = i_nextMarkupPhaseStart + 1; + continue; + } + else + { + break; + } + } + else + { + break; + } + } + else + { + break; + } + } + + if (i_endOfCurrMarkupPhase > i_startOfCurrMarkupPhase) + { + for (int i_char = i_startOfCurrMarkupPhase; i_char < i_startOfCurrMarkupPhase + startMarkingString_preValue.Length + valueLength + valueMarkupString_postValue.Length; i_char++) + { + chars[i_char].strippedDueToParsing = true; + } + + for (int i_char = i_endOfCurrMarkupPhase; i_char < i_endOfCurrMarkupPhase + endMarkingString.Length; i_char++) + { + chars[i_char].strippedDueToParsing = true; + } + + InternalDXXL_MarkupPhase markupPhase = new InternalDXXL_MarkupPhase(); + markupPhase.unparsedValue = value; + markupPhase.i_firstChar = i_closingBracketAfterValue + 1; + markupPhase.i_lastChar = i_endOfCurrMarkupPhase - 1; + i_nextFreeSlotInMarkupPhaseList = AddToMarkupPhasesList(ref markupPhasesList, markupPhase, i_nextFreeSlotInMarkupPhaseList); + } + else + { + break; + } + } + else + { + break; + } + } + else + { + break; + } + + i_startOfCurrMarkupPhase = text.IndexOf(startMarkingString_preValue, i_startOfCurrMarkupPhase + 1); + } + return i_nextFreeSlotInMarkupPhaseList; + } + + static int AddToMarkupPhasesList(ref List markupPhasesList, InternalDXXL_MarkupPhase markupPhaseToAdd, int i_ofSlotWhereToAdd) + { + //function returns "i_nextFreeSlot" + //function is not ensuring yet if addSlot is the next higher nonExisting-slot + if (i_ofSlotWhereToAdd < markupPhasesList.Count) + { + markupPhasesList[i_ofSlotWhereToAdd] = markupPhaseToAdd; + } + else + { + markupPhasesList.Add(markupPhaseToAdd); + } + i_ofSlotWhereToAdd++; + return i_ofSlotWhereToAdd; + } + + static void AssignStrokeWidthOffsets(int usedSlotsInListOf_relStrokeWidthMarkupPhases, float unmodifiedCharSize, Quaternion rotationOfChars, bool skipDraw) + { + if (skipDraw == false) + { + //Add standard duplicate vector for zero-width-strokes: + int i_ofFirstBoldChar = -1; + for (int i = 0; i < usedCharConfigListSlots; i++) + { + if (chars[i].bold) + { + if (i_ofFirstBoldChar == (-1)) + { + chars[i].usedSlots_inDuplicatesPrintOffsetList = GetDuplicatesPrintOffsetsForBoldUnrotated(ref chars[i].duplicatesPrintOffsets, unmodifiedCharSize, 0.0f); + TurnCharDef(ref chars[i].duplicatesPrintOffsets, chars[i].usedSlots_inDuplicatesPrintOffsetList, rotationOfChars); + i_ofFirstBoldChar = i; + } + else + { + UtilitiesDXXL_List.CopyContentOfVectorLists(ref chars[i].duplicatesPrintOffsets, ref chars[i_ofFirstBoldChar].duplicatesPrintOffsets, chars[i_ofFirstBoldChar].usedSlots_inDuplicatesPrintOffsetList); + chars[i].usedSlots_inDuplicatesPrintOffsetList = chars[i_ofFirstBoldChar].usedSlots_inDuplicatesPrintOffsetList; + } + } + else + { + UtilitiesDXXL_List.AddToAVectorList(ref chars[i].duplicatesPrintOffsets, Vector3.zero, 0); + chars[i].usedSlots_inDuplicatesPrintOffsetList = 1; + } + } + + //Add additional duplicate vectors for nonZero-width-strokes (overwriting upper standard-thinStroke-block): + for (int i_markupPhase = 0; i_markupPhase < usedSlotsInListOf_relStrokeWidthMarkupPhases; i_markupPhase++) + { + int relCharLinesWidth_asPPMofSize = 0; + try + { + relCharLinesWidth_asPPMofSize = Convert.ToInt32(relStrokeWidthMarkupPhases[i_markupPhase].unparsedValue); + } + catch (OverflowException) + { + Debug.LogError("Overflow exception in rich text strokeWidth markup. Couldn't parse '" + relStrokeWidthMarkupPhases[i_markupPhase].unparsedValue + "'"); + continue; + } + catch (FormatException) + { + Debug.LogError("Wrong format in rich text strokeWidth markup. Couldn't parse '" + relStrokeWidthMarkupPhases[i_markupPhase].unparsedValue + "'"); + continue; + } + + relCharLinesWidth_asPPMofSize = Mathf.Max(relCharLinesWidth_asPPMofSize, 0); + if (relCharLinesWidth_asPPMofSize > maxRelStrokeWidth_inPPMofSize) + { + Debug.Log("relCharLinesWidth_asPPMofSize (" + relCharLinesWidth_asPPMofSize + ") has been reduced to maxRelStrokeWidth (" + maxRelStrokeWidth_inPPMofSize + "). (i_swMarkUpPhase = " + i_markupPhase + ")"); + relCharLinesWidth_asPPMofSize = maxRelStrokeWidth_inPPMofSize; + } + float relCharLinesWidth = 0.000001f * relCharLinesWidth_asPPMofSize; + + int i_ofFirstBoldCharOfPhase = -1; + int i_ofFirstNonBoldCharOfPhase = -1; + for (int i_char = relStrokeWidthMarkupPhases[i_markupPhase].i_firstChar; i_char <= relStrokeWidthMarkupPhases[i_markupPhase].i_lastChar; i_char++) + { + if (chars[i_char].bold) + { + if (i_ofFirstBoldCharOfPhase == (-1)) + { + chars[i_char].usedSlots_inDuplicatesPrintOffsetList = GetDuplicatesPrintOffsetsForBoldUnrotated(ref chars[i_char].duplicatesPrintOffsets, unmodifiedCharSize, relCharLinesWidth); + TurnCharDef(ref chars[i_char].duplicatesPrintOffsets, chars[i_char].usedSlots_inDuplicatesPrintOffsetList, rotationOfChars); + i_ofFirstBoldCharOfPhase = i_char; + } + else + { + UtilitiesDXXL_List.CopyContentOfVectorLists(ref chars[i_char].duplicatesPrintOffsets, ref chars[i_ofFirstBoldCharOfPhase].duplicatesPrintOffsets, chars[i_ofFirstBoldCharOfPhase].usedSlots_inDuplicatesPrintOffsetList); + chars[i_char].usedSlots_inDuplicatesPrintOffsetList = chars[i_ofFirstBoldCharOfPhase].usedSlots_inDuplicatesPrintOffsetList; + } + } + else + { + if (i_ofFirstNonBoldCharOfPhase == (-1)) + { + chars[i_char].usedSlots_inDuplicatesPrintOffsetList = GetDuplicatesPrintOffsetsUnrotated(ref chars[i_char].duplicatesPrintOffsets, unmodifiedCharSize, relCharLinesWidth); + TurnCharDef(ref chars[i_char].duplicatesPrintOffsets, chars[i_char].usedSlots_inDuplicatesPrintOffsetList, rotationOfChars); + i_ofFirstNonBoldCharOfPhase = i_char; + } + else + { + UtilitiesDXXL_List.CopyContentOfVectorLists(ref chars[i_char].duplicatesPrintOffsets, ref chars[i_ofFirstNonBoldCharOfPhase].duplicatesPrintOffsets, chars[i_ofFirstNonBoldCharOfPhase].usedSlots_inDuplicatesPrintOffsetList); + chars[i_char].usedSlots_inDuplicatesPrintOffsetList = chars[i_ofFirstNonBoldCharOfPhase].usedSlots_inDuplicatesPrintOffsetList; + } + } + } + } + } + } + + static void TurnStrokeWidthOffsetsOnCircle() + { + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + if (chars[i_char].usedSlots_inDuplicatesPrintOffsetList > 0) + { + for (int i_duplicateOffset = 0; i_duplicateOffset < chars[i_char].usedSlots_inDuplicatesPrintOffsetList; i_duplicateOffset++) + { + chars[i_char].duplicatesPrintOffsets[i_duplicateOffset] = chars[i_char].rotationFromCircleStart * chars[i_char].duplicatesPrintOffsets[i_duplicateOffset]; + } + } + } + } + + static void ScaleSize_perChar(int usedSlotsInListOf_sizeMarkupPhases, float size) + { + for (int i_markupPhase = 0; i_markupPhase < usedSlotsInListOf_sizeMarkupPhases; i_markupPhase++) + { + int parsedSizeModifierValue = 100; + try + { + parsedSizeModifierValue = Convert.ToInt32(sizeMarkupPhases[i_markupPhase].unparsedValue); + } + catch (OverflowException) + { + Debug.LogError("Overflow exception in rich text size markup. Couldn't parse '" + sizeMarkupPhases[i_markupPhase].unparsedValue + "'"); + continue; + } + catch (FormatException) + { + Debug.LogError("Wrong format in rich text size markup. Couldn't parse '" + sizeMarkupPhases[i_markupPhase].unparsedValue + "'"); + continue; + } + + if (parsedSizeModifierValue <= 0) + { + parsedSizeModifierValue = 1; + } + + for (int i_char = sizeMarkupPhases[i_markupPhase].i_firstChar; i_char <= sizeMarkupPhases[i_markupPhase].i_lastChar; i_char++) + { + //chars[i_char].sizeScalingFactor = (0.01f * (float)sizeModifier_inPercent); //-> if size would be in percent + chars[i_char].sizeScalingFactor = (0.090909090f * (float)parsedSizeModifierValue); //-> factor comes from: "size=11" seems to be the size that the unity console logs use. This is probably measured in pixels. + + //chars[i_char].size = chars[i_char].size * chars[i_char].sizeScalingFactor; //-> this causes nested size markup phases to scale RELATIVE to the enclosing size markup phase. + chars[i_char].size = size * chars[i_char].sizeScalingFactor; //-> this causes nested size markup phases to scale ABSOLUTE depending only on the size value of the own markup phase. + chars[i_char].sizeHasBeenScaledViaRichtextMarkup = true; //-> used only for performance optimization + } + } + } + + static void ApplyColor(int usedSlotsInListOf_colorMarkupPhases, bool skipDraw) + { + if (skipDraw == false) + { + for (int i_markupPhase = 0; i_markupPhase < usedSlotsInListOf_colorMarkupPhases; i_markupPhase++) + { + Color parsedColor; + bool colorSuccesfullyParsed = ColorUtility.TryParseHtmlString(colorMarkupPhases[i_markupPhase].unparsedValue, out parsedColor); //"TryParseHtmlString" takes hex-string or alternatively the color name strings supported by Unity rich text + if (colorSuccesfullyParsed) + { + for (int i_char = colorMarkupPhases[i_markupPhase].i_firstChar; i_char <= colorMarkupPhases[i_markupPhase].i_lastChar; i_char++) + { + chars[i_char].color = parsedColor; + } + } + else + { + if (colorMarkupPhases[i_markupPhase].unparsedValue.Contains("#")) + { + Debug.LogError("Color parse failure in rich text size markup. Couldn't parse '" + colorMarkupPhases[i_markupPhase].unparsedValue + "'"); + } + else + { + Debug.LogError("Color parse failure in rich text size markup. Couldn't parse '" + colorMarkupPhases[i_markupPhase].unparsedValue + "'. The reason may be a missing hashtag as start of the color definition."); + } + } + } + } + } + + static void InsertIcons(string text) + { + int maxNumberOfMarkupPhases = 10000; + int i_startOfCurrMarkupPhase; + int i_closingBracketAfterValue = 0; + for (int i_markup = 0; i_markup < maxNumberOfMarkupPhases; i_markup++) + { + i_startOfCurrMarkupPhase = text.IndexOf(iconMarkupString_preValue, i_closingBracketAfterValue); + if (i_startOfCurrMarkupPhase >= i_closingBracketAfterValue) + { + int i_startOfValue = i_startOfCurrMarkupPhase + iconMarkupString_preValue.Length; + i_closingBracketAfterValue = text.IndexOf(valueMarkupString_postValue, i_startOfValue); + if (i_closingBracketAfterValue > i_startOfValue) + { + int valueLength = i_closingBracketAfterValue - i_startOfValue; + string value = text.Substring(i_startOfValue, valueLength); + //The FIRST char of the icon-markupPhase is used as non-stripped icon-char (because 'InsertAutoLineBreaks()' inserts his linebreaks BEFORE non-stripped chars): + chars[i_startOfCurrMarkupPhase].isIcon = true; + chars[i_startOfCurrMarkupPhase].iconString = value; + for (int i_char = i_startOfCurrMarkupPhase + 1; i_char <= i_closingBracketAfterValue; i_char++) + { + chars[i_char].strippedDueToParsing = true; + } + } + else + { + break; + } + } + else + { + break; + } + } + } + + static int GetNumberOfNonStrippedChars() + { + int count = 0; + for (int i = 0; i < usedCharConfigListSlots; i++) + { + if (chars[i].strippedDueToParsing == false) + { + count++; + } + } + return count; + } + + static void InsertLineBreaks_fromEscapedUnicodeChars() + { + int maxNumberOfLineBreaks = 5000; //-> preventing endless loops + int insertedLineBreaks = 0; + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + if (chars[i_char].strippedDueToParsing == false) + { + if (insertedLineBreaks > maxNumberOfLineBreaks) + { + Debug.LogWarning("Stopped parsing lineFeeds and carriageReturns, because maxNumberOfLineBreaks (" + maxNumberOfLineBreaks + ") was reached."); + break; + } + + bool isALineBreakChar = false; + bool lineBreakConsistsOfTwoChars = false; + + //unicode 10 = linefeed + //unicode 13 = carriagereturn + if (13 == (int)chars[i_char].character) + { + if (((i_char + 1) < usedCharConfigListSlots) && (10 == (int)chars[i_char + 1].character)) + { + //-> sequence of "\r\n" was parsed into two unicode-chars: + isALineBreakChar = true; + lineBreakConsistsOfTwoChars = true; + chars[i_char + 1].hasMissingSymbolDefinition = true; + chars[i_char + 1].strippedDueToParsing = true; + } + else + { + //-> "\r" without following "\n" was parsed into one unicode-char: + isALineBreakChar = true; + } + } + else + { + if (10 == (int)chars[i_char].character) + { + //-> "\n" was parsed into one unicode-char: + isALineBreakChar = true; + } + } + + if (isALineBreakChar) + { + chars[i_char].hasMissingSymbolDefinition = true; + chars[i_char].strippedDueToParsing = true; + chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself = lineBreakConsistsOfTwoChars ? 2 : 1; + for (int i = 1; i < chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself; i++) + { + i_char++; + } + insertedLineBreaks++; + } + } + } + } + + static void InsertLineBreaks_fromMaxTextBlockWidthParameter(float autoLineBreakWidth, float size) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(autoLineBreakWidth) == false) + { + autoLineBreakWidth = Mathf.Max(autoLineBreakWidth, 0.0001f); + float lengthOfCurrLine = 0.0f; + int numberOfNonIgnoredChars_inCurrLine = 0; + int numberOfInsertedAutoLineBreaks = 0; + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + if (numberOfInsertedAutoLineBreaks > 10000) + { + Debug.LogWarning("Inserting autoLineBreaks stopped, coz numberOfInsertedAutoLineBreaks (" + numberOfInsertedAutoLineBreaks + ") is too high."); + break; + } + + if (chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself > 0) + { + lengthOfCurrLine = 0.0f; + numberOfNonIgnoredChars_inCurrLine = 0; + for (int i_charOfLineBreakString = 1; i_charOfLineBreakString < chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself; i_charOfLineBreakString++) + { + i_char++; + } + } + else + { + if (chars[i_char].strippedDueToParsing == false) + { + numberOfNonIgnoredChars_inCurrLine++; + lengthOfCurrLine = lengthOfCurrLine + chars[i_char].size; + if (numberOfNonIgnoredChars_inCurrLine > 1) //-> auto-lineBreaks can only be inserted if the line has at least one char (otherwise: Danger of endless loop) + { + if (lengthOfCurrLine > autoLineBreakWidth) + { + numberOfInsertedAutoLineBreaks++; + InsertLineBreakChar(i_char); + lengthOfCurrLine = 0.0f; + numberOfNonIgnoredChars_inCurrLine = 0; + } + } + } + } + } + } + } + + static void Assign_coveredAnglePerChar_onTheLineAtTheReferenceRadius(float referenceRadius, float size) + { + //"referenceRadius" is the one which has been specified by the user via function parameter(s) (and if no lineBreaks would exist). This "referenceRadius" can later be shifted outwards by "textAnchor == TextAnchorCircledDXXL.LowerLeftOfWholeTextBlock", which will also update the "coveredAngleDeg_onTheLineAtTheReferenceRadius"'s. + float coveredAngleDeg_onTheLineAtTheReferenceRadius_forADefaultSizedChar = Mathf.Rad2Deg * Mathf.Atan(size / referenceRadius); + for (int i = 0; i < usedCharConfigListSlots; i++) + { + if (chars[i].sizeHasBeenScaledViaRichtextMarkup) + { + chars[i].coveredAngleDeg_onTheLineAtTheReferenceRadius = Mathf.Rad2Deg * Mathf.Atan(chars[i].size / referenceRadius); + } + else + { + chars[i].coveredAngleDeg_onTheLineAtTheReferenceRadius = coveredAngleDeg_onTheLineAtTheReferenceRadius_forADefaultSizedChar; + } + } + } + + static float TryShiftTheTextToOutwardsOfRadius_soItEndsOnTheCircleInsteadOfStartingThere(DrawText.TextAnchorCircledDXXL textAnchor, float autoLineBreakAngleDeg, float size, float radius_beforeShifting) + { + if (textAnchor == DrawText.TextAnchorCircledDXXL.LowerLeftOfWholeTextBlock) + { + autoLineBreakAngleDeg = ForceDefault_autoLineBreakAngle(autoLineBreakAngleDeg); + float radiusShiftOffset_awayFromCircleCenter_perDefaultSizedLineBreak = size * relLineDistance; + float angleDegThatIsAlreadyCoveredByChars_forCurrLine = 0.0f; + float angleDeg_ofStandardSizedChar_inTheLineAtTheReferenceRadius = Mathf.Rad2Deg * Mathf.Atan(size / radius_beforeShifting); + float correctionFactor_forCoveredAnglePerChar_forCurrLine = 1.0f; + float currRadius = radius_beforeShifting; + float sizeOfBiggestChar_inCurrFinishedLine = 0.0f; + int numberOfNonIgnoredChars_inCurrLine = 0; + int numberOfShiftedLineBreaks = 0; + + for (int i_char = usedCharConfigListSlots - 1; i_char >= 0; i_char--) + { + if (numberOfShiftedLineBreaks > 10000) + { + //-> "InsertLineBreaksOnCircle_fromMaxTextBlockAngleParameter()" will print the log message for cases like this later + return radius_beforeShifting; + } + + if (chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself > 0) + { + //current char is already a lineBreak (from
-markup, or from unicode-chars, since autoLineBreakAngle is not done yet): + UpdateAndReset_charsPerLineCountingParameters_dueToLineShift(ref numberOfShiftedLineBreaks, out angleDegThatIsAlreadyCoveredByChars_forCurrLine, out numberOfNonIgnoredChars_inCurrLine, out currRadius, out correctionFactor_forCoveredAnglePerChar_forCurrLine, out sizeOfBiggestChar_inCurrFinishedLine, currRadius, radiusShiftOffset_awayFromCircleCenter_perDefaultSizedLineBreak, size, angleDeg_ofStandardSizedChar_inTheLineAtTheReferenceRadius); + } + else + { + if (chars[i_char].strippedDueToParsing == false) + { + numberOfNonIgnoredChars_inCurrLine++; + sizeOfBiggestChar_inCurrFinishedLine = Mathf.Max(sizeOfBiggestChar_inCurrFinishedLine, chars[i_char].size); + angleDegThatIsAlreadyCoveredByChars_forCurrLine = angleDegThatIsAlreadyCoveredByChars_forCurrLine + chars[i_char].coveredAngleDeg_onTheLineAtTheReferenceRadius * correctionFactor_forCoveredAnglePerChar_forCurrLine; + if (angleDegThatIsAlreadyCoveredByChars_forCurrLine > autoLineBreakAngleDeg) + { + if (numberOfNonIgnoredChars_inCurrLine > 1) + { + //-> lines with only 1 char, which already protrudes the "autoLineBreakAngleDeg" the char will stay as "protruding" and will stay in its line. His covered angle span is therefore already "used up" and we can proceed to the next char. These cases don't arrive here. + //-> in lines, where the first prodruding char is the 2nd char or a higher char: These cases arrive here. The protruding char will not be printed in this line, but will start the line after the line break. His covered angle span is not used up yet so when starting with the next line his angle span should be considered once again. Therefore "i_char" gets manually changed here. + i_char++; //-> ensuring that the angle span of the current charcter will be considered once again after the current line shift. + } + + float radiusShiftOffset_awayFromCircleCenter_forThisLineBreak = Get_radiusShiftOffset_awayFromCircleCenter_forThisLineBreak(numberOfNonIgnoredChars_inCurrLine, i_char, size, sizeOfBiggestChar_inCurrFinishedLine, radiusShiftOffset_awayFromCircleCenter_perDefaultSizedLineBreak); + UpdateAndReset_charsPerLineCountingParameters_dueToLineShift(ref numberOfShiftedLineBreaks, out angleDegThatIsAlreadyCoveredByChars_forCurrLine, out numberOfNonIgnoredChars_inCurrLine, out currRadius, out correctionFactor_forCoveredAnglePerChar_forCurrLine, out sizeOfBiggestChar_inCurrFinishedLine, currRadius, radiusShiftOffset_awayFromCircleCenter_forThisLineBreak, size, angleDeg_ofStandardSizedChar_inTheLineAtTheReferenceRadius); + } + } + } + } + + if (numberOfShiftedLineBreaks > 0) + { + ScaleAllAnglesOnTheLineAtTheReferenceRadius(correctionFactor_forCoveredAnglePerChar_forCurrLine); + return currRadius; + } + else + { + return radius_beforeShifting; + } + } + else + { + return radius_beforeShifting; + } + } + + static float Get_radiusShiftOffset_awayFromCircleCenter_forThisLineBreak(int numberOfNonIgnoredChars_inCurrLine, int i_char, float size, float sizeOfBiggestChar_inCurrFinishedLine, float radiusShiftOffset_awayFromCircleCenter_perDefaultSizedLineBreak) + { + //-> This tries to compensate the influence of size richtext markups + //-> This is not a fully precise substitue for "GetBiggestCharSizeInsideLine()" (which is not available yet) (and the detected lineShifts here are at different chars than the later determined lineBreaks, since we iterate the char-list backward here, but later we iterate forward), but it is better than nothing: + float approxRelSize_ofBiggestCharInTheLine; + if (numberOfNonIgnoredChars_inCurrLine == 1) + { + approxRelSize_ofBiggestCharInTheLine = chars[i_char].size / size; + } + else + { + float relSize_ofBiggestCharInTheLine = sizeOfBiggestChar_inCurrFinishedLine / size; + float weightOfBiggestFoundChar = 0.5f; + approxRelSize_ofBiggestCharInTheLine = Mathf.Lerp(1.0f, relSize_ofBiggestCharInTheLine, weightOfBiggestFoundChar); + } + + return (radiusShiftOffset_awayFromCircleCenter_perDefaultSizedLineBreak * approxRelSize_ofBiggestCharInTheLine); + } + + static void UpdateAndReset_charsPerLineCountingParameters_dueToLineShift(ref int numberOfShiftedLineBreaks, out float angleDegThatIsAlreadyCoveredByChars_forCurrLine, out int numberOfNonIgnoredChars_inCurrLine, out float radius_postShift, out float correctionFactor_forCoveredAnglePerChar_forCurrLine, out float sizeOfBiggestChar_startValueForUpcomingLine, float radius_preShift, float radiusShiftOffset_awayFromCircleCenter_forThisLineBreak, float sizePerChar_withoutRichtextSizeMarkupModification, float angleDeg_ofStandardSizedChar_inTheLineAtTheReferenceRadius) + { + numberOfShiftedLineBreaks++; + angleDegThatIsAlreadyCoveredByChars_forCurrLine = 0.0f; + numberOfNonIgnoredChars_inCurrLine = 0; + sizeOfBiggestChar_startValueForUpcomingLine = 0.0f; + radius_postShift = radius_preShift + radiusShiftOffset_awayFromCircleCenter_forThisLineBreak; //-> more correct would be to use "GetBiggestCharSizeInsideLine()" instead of "size", but it is not available yet, because the automaticLineBreaksAtMaxAngle are not inserted yet. Using the lineShifts that get detected here is not a sufficient substitute, because the lineBreaks here can be at differnt positions than those who get inserted afterwards in "InsertLineBreaksOnCircle_fromMaxTextBlockAngleParameter()". + correctionFactor_forCoveredAnglePerChar_forCurrLine = Calc_correctionFactor_forCoveredAnglePerChar_perLine(radius_postShift, sizePerChar_withoutRichtextSizeMarkupModification, angleDeg_ofStandardSizedChar_inTheLineAtTheReferenceRadius); //-> this "angleCorrectionFactorForCurrLine" is only provisional here, so not neccessarily fully precise, due to using "radius_postShift" (see notes there) + } + + static void ScaleAllAnglesOnTheLineAtTheReferenceRadius(float scaleFactor) + { + for (int i = 0; i < usedCharConfigListSlots; i++) + { + chars[i].coveredAngleDeg_onTheLineAtTheReferenceRadius = chars[i].coveredAngleDeg_onTheLineAtTheReferenceRadius * scaleFactor; + } + } + + static void InsertLineBreaksOnCircle_fromMaxTextBlockAngleParameter(float autoLineBreakAngleDeg, float size, float radius) + { + autoLineBreakAngleDeg = ForceDefault_autoLineBreakAngle(autoLineBreakAngleDeg); + + float angleDegThatIsAlreadyCoveredByChars_forCurrLine = 0.0f; + float angleDeg_ofStandardSizedChar_inTheLineAtTheReferenceRadius = Mathf.Rad2Deg * Mathf.Atan(size / radius); + float correctionFactor_forCoveredAnglePerChar_forCurrLine = 1.0f; + float currRadius = radius; + int numberOfNonIgnoredChars_inCurrLine = 0; + int numberOfInsertedAutoLineBreaks = 0; + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + if (numberOfInsertedAutoLineBreaks > 10000) + { + Debug.LogWarning("Inserting autoLineBreaks stopped, coz numberOfInsertedAutoLineBreaks (" + numberOfInsertedAutoLineBreaks + ") is too high."); + break; + } + + if (chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself > 0) + { + //current char is already a lineBreak (from
-markup, or from unicode-chars, since autoLineBreakAngle is not done yet): + UpdateAndReset_charsPerLineCountingParameters_dueToLineBreak(out angleDegThatIsAlreadyCoveredByChars_forCurrLine, out numberOfNonIgnoredChars_inCurrLine, out currRadius, out correctionFactor_forCoveredAnglePerChar_forCurrLine, currRadius, size, angleDeg_ofStandardSizedChar_inTheLineAtTheReferenceRadius); + for (int i_charOfLineBreakString = 1; i_charOfLineBreakString < chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself; i_charOfLineBreakString++) + { + i_char++; + } + } + else + { + if (chars[i_char].strippedDueToParsing == false) + { + numberOfNonIgnoredChars_inCurrLine++; + angleDegThatIsAlreadyCoveredByChars_forCurrLine = angleDegThatIsAlreadyCoveredByChars_forCurrLine + chars[i_char].coveredAngleDeg_onTheLineAtTheReferenceRadius * correctionFactor_forCoveredAnglePerChar_forCurrLine; + if (numberOfNonIgnoredChars_inCurrLine > 1) //-> auto-lineBreaks can only be inserted if the line has at least one char (otherwise: danger of endless loop) + { + if (angleDegThatIsAlreadyCoveredByChars_forCurrLine > autoLineBreakAngleDeg) + { + numberOfInsertedAutoLineBreaks++; + InsertLineBreakChar(i_char); + UpdateAndReset_charsPerLineCountingParameters_dueToLineBreak(out angleDegThatIsAlreadyCoveredByChars_forCurrLine, out numberOfNonIgnoredChars_inCurrLine, out currRadius, out correctionFactor_forCoveredAnglePerChar_forCurrLine, currRadius, size, angleDeg_ofStandardSizedChar_inTheLineAtTheReferenceRadius); + } + } + } + } + } + } + + static float ForceDefault_autoLineBreakAngle(float autoLineBreakAngleDeg) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(autoLineBreakAngleDeg)) { autoLineBreakAngleDeg = 360.0f; } + autoLineBreakAngleDeg = Mathf.Max(autoLineBreakAngleDeg, 0.01f); + autoLineBreakAngleDeg = Mathf.Min(autoLineBreakAngleDeg, 360.0f); + return autoLineBreakAngleDeg; + } + + static void UpdateAndReset_charsPerLineCountingParameters_dueToLineBreak(out float angleDegThatIsAlreadyCoveredByChars_forCurrLine, out int numberOfNonIgnoredChars_inCurrLine, out float radiusAfterLineBreak, out float correctionFactor_forCoveredAnglePerChar_forUpcomingLine, float radius_beforeLineBreak, float sizePerChar_withoutRichtextSizeMarkupModification, float angleDeg_ofStandardSizedChar_inTheLineAtTheReferenceRadius) + { + angleDegThatIsAlreadyCoveredByChars_forCurrLine = 0.0f; + numberOfNonIgnoredChars_inCurrLine = 0; + radiusAfterLineBreak = GetRadiusOfCirclesNextInnerLine(radius_beforeLineBreak, sizePerChar_withoutRichtextSizeMarkupModification); //-> more correct would be to use "GetBiggestCharSizeInsideLine()" instead of "size", but it is not available yet, since we would need all lineBreaks, but we are currently still in the process of inserting lineBreaks + correctionFactor_forCoveredAnglePerChar_forUpcomingLine = Calc_correctionFactor_forCoveredAnglePerChar_perLine(radiusAfterLineBreak, sizePerChar_withoutRichtextSizeMarkupModification, angleDeg_ofStandardSizedChar_inTheLineAtTheReferenceRadius); //-> this "angleCorrectionFactorForUpcomingLine" is only provisional here, so not neccessarily fully precise, since "GetBiggestCharSizeInsideLine()" hasn't been taken into account yet while calculating "radiusAfterLineBreak". + } + + static void InsertLineBreakChar(int i_whereToInsert) + { + autoLineBreakChar.hasMissingSymbolDefinition = true; + autoLineBreakChar.strippedDueToParsing = true; + autoLineBreakChar.numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself = 1; + chars.Insert(i_whereToInsert, autoLineBreakChar); + usedCharConfigListSlots++; + } + + static float Calc_correctionFactor_forCoveredAnglePerChar_perLine(float radiusOfConcernedLine, float sizeOfStandardSizedChar, float angleDeg_ofAStandardSizedChar_onTheLineAtTheReferenceRadius) + { + //"standard sized" means "the size specified by the textSize-paramter, but not scaled by a richtext size markup" + float angleDeg_ofAStandardSizedChar_inCurrLine = Mathf.Rad2Deg * Mathf.Atan(sizeOfStandardSizedChar / radiusOfConcernedLine); + return (angleDeg_ofAStandardSizedChar_inCurrLine / angleDeg_ofAStandardSizedChar_onTheLineAtTheReferenceRadius); + } + + static void Assign_coveredAnglePerChar_onTheCharsOwnLine(float radius, float size) + { + float coveredAngleDeg_ofAStandardSizedChar_onTheLineAtTheReferenceRadius = Mathf.Rad2Deg * Mathf.Atan(size / radius); + float correctionFactor_forCoveredAnglePerChar_forCurrLine = 1.0f; + float currRadius = radius; + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + if (chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself > 0) + { + //switching the lines: + float sizeOfBiggestCharInUpcomingLine = GetBiggestCharSizeInsideLine(i_char + chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself); + currRadius = GetRadiusOfCirclesNextInnerLine(currRadius, sizeOfBiggestCharInUpcomingLine); + correctionFactor_forCoveredAnglePerChar_forCurrLine = Calc_correctionFactor_forCoveredAnglePerChar_perLine(currRadius, size, coveredAngleDeg_ofAStandardSizedChar_onTheLineAtTheReferenceRadius); + + for (int i_charOfLineBreakString = 1; i_charOfLineBreakString < chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself; i_charOfLineBreakString++) + { + i_char++; + } + } + else + { + //correcting the sizes inside the current line: + chars[i_char].coveredAngleDegOnOwnLine = chars[i_char].coveredAngleDeg_onTheLineAtTheReferenceRadius * correctionFactor_forCoveredAnglePerChar_forCurrLine; + } + } + } + + static float GetRadiusOfCirclesNextInnerLine(float radiusOfLine_beforeJumpingDownToNextInnerLine, float sizeOfBiggestCharInUpcomingLine) + { + float reducedRadius = radiusOfLine_beforeJumpingDownToNextInnerLine - sizeOfBiggestCharInUpcomingLine * relLineDistance; + return Mathf.Max(reducedRadius, minRadius); + } + + static void FillParsedTextSpecs() + { + DrawText.parsedTextSpecs.widthOfLongestLine = 0.0f; + DrawText.parsedTextSpecs.numberOfChars_inLongestLine = 0; + DrawText.parsedTextSpecs.numberOfChars_afterParsingOutTheMarkupTags = 0; + DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine = GetBiggestCharSizeInsideLine(0); + DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine = 0.0f; + + float lengthOfCurrLine = 0.0f; + int numberOfChars_inCurrLine = 0; + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + if (chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself > 0) + { + DrawText.parsedTextSpecs.widthOfLongestLine = Math.Max(DrawText.parsedTextSpecs.widthOfLongestLine, lengthOfCurrLine); + DrawText.parsedTextSpecs.numberOfChars_inLongestLine = Math.Max(DrawText.parsedTextSpecs.numberOfChars_inLongestLine, numberOfChars_inCurrLine); + lengthOfCurrLine = 0.0f; + numberOfChars_inCurrLine = 0; + for (int i_charOfLineBreakString = 1; i_charOfLineBreakString < chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself; i_charOfLineBreakString++) + { + i_char++; + } + DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine = DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine + GetBiggestCharSizeInsideLine(i_char + 1) * relLineDistance; + } + else + { + if (chars[i_char].strippedDueToParsing == false) + { + lengthOfCurrLine = lengthOfCurrLine + chars[i_char].size; + numberOfChars_inCurrLine++; + DrawText.parsedTextSpecs.numberOfChars_afterParsingOutTheMarkupTags++; + } + } + } + + //last line (after last lineBreak): + DrawText.parsedTextSpecs.widthOfLongestLine = Math.Max(DrawText.parsedTextSpecs.widthOfLongestLine, lengthOfCurrLine); + DrawText.parsedTextSpecs.numberOfChars_inLongestLine = Math.Max(DrawText.parsedTextSpecs.numberOfChars_inLongestLine, numberOfChars_inCurrLine); + + DrawText.parsedTextSpecs.height_wholeTextBlock = DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine + DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine * relLineDistance; + } + + static void FillParsedTextOnCircleSpecs() + { + DrawText.parsedTextOnCircleSpecs.angleDegOfLongestLine = 0.0f; + DrawText.parsedTextOnCircleSpecs.numberOfChars_inLongestLine = 0; + DrawText.parsedTextOnCircleSpecs.numberOfChars_afterParsingOutTheMarkupTags = 0; + DrawText.parsedTextOnCircleSpecs.sizeOfBiggestCharInFirstLine = 0.0f; + + float angleDegOfCurrLine = 0.0f; + int numberOfChars_inCurrLine = 0; + bool isFirstLine = true; + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + if (chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself > 0) + { + isFirstLine = false; + DrawText.parsedTextOnCircleSpecs.angleDegOfLongestLine = Math.Max(DrawText.parsedTextOnCircleSpecs.angleDegOfLongestLine, angleDegOfCurrLine); + DrawText.parsedTextOnCircleSpecs.numberOfChars_inLongestLine = Math.Max(DrawText.parsedTextOnCircleSpecs.numberOfChars_inLongestLine, numberOfChars_inCurrLine); + angleDegOfCurrLine = 0.0f; + numberOfChars_inCurrLine = 0; + for (int i_charOfLineBreakString = 1; i_charOfLineBreakString < chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself; i_charOfLineBreakString++) + { + i_char++; + } + } + else + { + if (chars[i_char].strippedDueToParsing == false) + { + angleDegOfCurrLine = angleDegOfCurrLine + chars[i_char].coveredAngleDegOnOwnLine; + numberOfChars_inCurrLine++; + DrawText.parsedTextOnCircleSpecs.numberOfChars_afterParsingOutTheMarkupTags++; + if (isFirstLine) + { + DrawText.parsedTextOnCircleSpecs.sizeOfBiggestCharInFirstLine = Math.Max(DrawText.parsedTextOnCircleSpecs.sizeOfBiggestCharInFirstLine, chars[i_char].size); + } + } + } + } + + //last line (without lineBreak): + DrawText.parsedTextOnCircleSpecs.angleDegOfLongestLine = Math.Max(DrawText.parsedTextOnCircleSpecs.angleDegOfLongestLine, angleDegOfCurrLine); + DrawText.parsedTextOnCircleSpecs.numberOfChars_inLongestLine = Math.Max(DrawText.parsedTextOnCircleSpecs.numberOfChars_inLongestLine, numberOfChars_inCurrLine); + } + + static void AssignIndividualRotation(Vector3 initialTextUpNormalized, Vector3 forward) + { + float angleDegOfCurrLine = 0.0f; + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + if (chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself > 0) + { + angleDegOfCurrLine = 0.0f; + for (int i_charOfLineBreakString = 1; i_charOfLineBreakString < chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself; i_charOfLineBreakString++) + { + i_char++; + } + } + else + { + if (chars[i_char].strippedDueToParsing == false) + { + chars[i_char].rotationFromCircleStart = Quaternion.AngleAxis(angleDegOfCurrLine, -forward); + chars[i_char].charUp = chars[i_char].rotationFromCircleStart * initialTextUpNormalized; + //chars[i_char].charDirection = chars[i_char].rotationFromCircleStart * initialTextDirNormalized; + angleDegOfCurrLine = angleDegOfCurrLine + chars[i_char].coveredAngleDegOnOwnLine; + } + } + } + } + + static float ForceTextWidth(float forceTextEnlargementToThisMinWidth, float forceRestrictTextSizeToThisMaxTextWidth) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(forceTextEnlargementToThisMinWidth) == false || UtilitiesDXXL_Math.ApproximatelyZero(forceRestrictTextSizeToThisMaxTextWidth) == false) + { + float scaleFactor = 1.0f; + bool ignore_forceMin = false; + if (forceRestrictTextSizeToThisMaxTextWidth > 0.0f) + { + if (DrawText.parsedTextSpecs.widthOfLongestLine > forceRestrictTextSizeToThisMaxTextWidth) + { + scaleFactor = forceRestrictTextSizeToThisMaxTextWidth / DrawText.parsedTextSpecs.widthOfLongestLine; + } + + if (forceTextEnlargementToThisMinWidth > forceRestrictTextSizeToThisMaxTextWidth) + { + ignore_forceMin = true; + Debug.LogWarning("Contradiction: forceTextEnlargementToThisMinWidth (" + forceTextEnlargementToThisMinWidth + ") is bigger than forceRestrictTextSizeToThisMaxTextWidth (" + forceRestrictTextSizeToThisMaxTextWidth + ") -> forceTextEnlargementToThisMinWidth gets ignored."); + } + } + + if (ignore_forceMin == false) + { + if (forceTextEnlargementToThisMinWidth > 0.0f) + { + if (DrawText.parsedTextSpecs.widthOfLongestLine < forceTextEnlargementToThisMinWidth) + { + scaleFactor = forceTextEnlargementToThisMinWidth / DrawText.parsedTextSpecs.widthOfLongestLine; + } + } + } + + if (Mathf.Approximately(1.0f, scaleFactor) == false) + { + ScaleSizeOfAllChars(scaleFactor); + DrawText.parsedTextSpecs.widthOfLongestLine = DrawText.parsedTextSpecs.widthOfLongestLine * scaleFactor; + DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine = DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine * scaleFactor; + DrawText.parsedTextSpecs.height_wholeTextBlock = DrawText.parsedTextSpecs.height_wholeTextBlock * scaleFactor; + DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine = DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine * scaleFactor; + return scaleFactor; + } + } + return 1.0f; + } + + static void ScaleSizeOfAllChars(float scaleFactor) + { + for (int i_char = 0; i_char < usedCharConfigListSlots; i_char++) + { + chars[i_char].sizeScalingFactor = chars[i_char].sizeScalingFactor * scaleFactor; + chars[i_char].size = chars[i_char].size * scaleFactor; + } + } + + static int GetDuplicatesPrintOffsetsUnrotated(ref List concernedDuplicatesPrintOffsetsList, float size, float relativeStrokeWidth) + { + //function returns "usedSlots_inConcernedDuplicatesPrintOffsetsList" + if (UtilitiesDXXL_Math.ApproximatelyZero(relativeStrokeWidth) == false) + { + int usedSlots_inConcernedDuplicatesPrintOffsetsList = 0; + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, Vector3.zero, usedSlots_inConcernedDuplicatesPrintOffsetsList); + + float halfAbsStrokeWidth = 0.5f * size * relativeStrokeWidth; + + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * Vector3.up, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_LeftLeftDown_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_RightRightDown_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + + if (relativeStrokeWidth > 0.05f) + { + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * Vector3.down, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_LeftLeftUp_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_RightRightUp_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + } + + if (relativeStrokeWidth > 0.1f) + { + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * Vector3.left, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_RightUpUp_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_RightDownDown_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + } + + if (relativeStrokeWidth > 0.16f) + { + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * Vector3.right, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_LeftUpUp_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_LeftDownDown_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + } + + return usedSlots_inConcernedDuplicatesPrintOffsetsList; + } + else + { + UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, Vector3.zero, 0); + return 1; + } + } + + public static int GetDuplicatesPrintOffsetsUnrotated_ofTextIndependentIconOfSize1(ref List concernedDuplicatesPrintOffsetsList, float size, float relativeStrokeWidth) + { + //function returns "usedSlots_inConcernedDuplicatesPrintOffsetsList" + if (UtilitiesDXXL_Math.ApproximatelyZero(relativeStrokeWidth) == false) + { + int usedSlots_inConcernedDuplicatesPrintOffsetsList = 0; + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, Vector3.zero, usedSlots_inConcernedDuplicatesPrintOffsetsList); + float halfAbsStrokeWidth = 0.5f * size * relativeStrokeWidth; + + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * Vector3.up, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_LeftLeftDown_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_RightRightDown_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + + if (relativeStrokeWidth > 0.012f) + { + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * Vector3.down, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_LeftLeftUp_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_RightRightUp_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + } + + if (relativeStrokeWidth > 0.025f) + { + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * Vector3.left, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_RightUpUp_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_RightDownDown_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * Vector3.right, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_LeftUpUp_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + usedSlots_inConcernedDuplicatesPrintOffsetsList = UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, halfAbsStrokeWidth * duplicateTriangle_LeftDownDown_normalized, usedSlots_inConcernedDuplicatesPrintOffsetsList); + } + return usedSlots_inConcernedDuplicatesPrintOffsetsList; + } + else + { + UtilitiesDXXL_List.AddToAVectorList(ref concernedDuplicatesPrintOffsetsList, Vector3.zero, 0); + return 1; + } + } + + static int GetDuplicatesPrintOffsetsForBoldUnrotated(ref List concernedDuplicatesPrintOffsetsList, float size, float relativeStrokeWidth) + { + //function returns "usedSlots_inConcernedDuplicatesPrintOffsetsList" + float relBoldStrokeWidth = 3.0f * relativeStrokeWidth; + relBoldStrokeWidth = Mathf.Max(relBoldStrokeWidth, minRelBoldStrokeWidth); + relBoldStrokeWidth = Mathf.Min(relBoldStrokeWidth, maxRelBoldStrokeWidth); + return GetDuplicatesPrintOffsetsUnrotated(ref concernedDuplicatesPrintOffsetsList, size, relBoldStrokeWidth); + } + + static float GetBiggestCharSizeInsideLine(int i_startOfLine) + { + if (i_startOfLine < usedCharConfigListSlots) + { + float biggestSize = 0.0f; + for (int i_char = i_startOfLine; i_char < usedCharConfigListSlots; i_char++) + { + if (chars[i_char].numberOfChars_thatThisCharMarksAsASingleLineBreakIncludingItself > 0) + { + break; + } + + if (chars[i_char].strippedDueToParsing == false) + { + biggestSize = Mathf.Max(biggestSize, chars[i_char].size); + } + } + + if (UtilitiesDXXL_Math.ApproximatelyZero(biggestSize)) + { + return chars[i_startOfLine].size; + } + else + { + return biggestSize; + } + } + else + { + return 0.0f; + } + } + + static Vector3 GetLowLeftPosOfFirstLine(Vector3 position, DrawText.TextAnchorDXXL textAnchor, Vector3 textDirNormalized, Vector3 textUpNormalized) + { + Vector3 fromMiddleLeft_toLowLeftOfFirstLine; + switch (textAnchor) + { + case DrawText.TextAnchorDXXL.UpperLeft: + return position - textUpNormalized * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine * relLineDistance; + + case DrawText.TextAnchorDXXL.UpperCenter: + return position - 0.5f * textDirNormalized * DrawText.parsedTextSpecs.widthOfLongestLine - textUpNormalized * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine * relLineDistance; + + case DrawText.TextAnchorDXXL.UpperRight: + return position - textDirNormalized * DrawText.parsedTextSpecs.widthOfLongestLine - textUpNormalized * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine * relLineDistance; + + case DrawText.TextAnchorDXXL.MiddleLeft: + fromMiddleLeft_toLowLeftOfFirstLine = textUpNormalized * (0.5f * DrawText.parsedTextSpecs.height_wholeTextBlock - 0.775f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine * relLineDistance); + return position + fromMiddleLeft_toLowLeftOfFirstLine; + + case DrawText.TextAnchorDXXL.MiddleCenter: + fromMiddleLeft_toLowLeftOfFirstLine = textUpNormalized * (0.5f * DrawText.parsedTextSpecs.height_wholeTextBlock - 0.775f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine * relLineDistance); + return position - 0.5f * textDirNormalized * DrawText.parsedTextSpecs.widthOfLongestLine + fromMiddleLeft_toLowLeftOfFirstLine; + + case DrawText.TextAnchorDXXL.MiddleRight: + fromMiddleLeft_toLowLeftOfFirstLine = textUpNormalized * (0.5f * DrawText.parsedTextSpecs.height_wholeTextBlock - 0.775f * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine * relLineDistance); + return position - textDirNormalized * DrawText.parsedTextSpecs.widthOfLongestLine + fromMiddleLeft_toLowLeftOfFirstLine; + + case DrawText.TextAnchorDXXL.LowerLeft: + return position + textUpNormalized * DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine; + + case DrawText.TextAnchorDXXL.LowerCenter: + return position - 0.5f * textDirNormalized * DrawText.parsedTextSpecs.widthOfLongestLine + textUpNormalized * DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine; + + case DrawText.TextAnchorDXXL.LowerRight: + return position - textDirNormalized * DrawText.parsedTextSpecs.widthOfLongestLine + textUpNormalized * DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine; + + case DrawText.TextAnchorDXXL.LowerLeftOfFirstLine: + return position; + + case DrawText.TextAnchorDXXL.LowerCenterOfFirstLine: + return position - 0.5f * textDirNormalized * DrawText.parsedTextSpecs.widthOfLongestLine; + + case DrawText.TextAnchorDXXL.LowerRightOfFirstLine: + return position - textDirNormalized * DrawText.parsedTextSpecs.widthOfLongestLine; + + default: + Debug.LogError("TextAnchorExt of '" + textAnchor + "' not found. Fallback to 'LowerLeftOfFirstLine'"); + return position; + } + } + + static float GetCapped_autoLineBreakWidth_relToViewportWidth(Camera camera, bool autoLineBreakAtViewportBorder, float autoLineBreakWidth_relToViewportWidth, Vector2 position, DrawText.TextAnchorDXXL textAnchor, float zRotationDeg) + { + if (autoLineBreakAtViewportBorder) + { + Quaternion rotation_aroundForward = Quaternion.AngleAxis(zRotationDeg, Vector3.forward); + Vector2 textDir_inAspectCorrected1by1SquareViewportSpace_normalized = rotation_aroundForward * Vector2.right; + + if (textAnchor == DrawText.TextAnchorDXXL.LowerLeft || textAnchor == DrawText.TextAnchorDXXL.LowerLeftOfFirstLine || textAnchor == DrawText.TextAnchorDXXL.MiddleLeft || textAnchor == DrawText.TextAnchorDXXL.UpperLeft) + { + bool distanceToForwardViewportBorder_isValid; + float distanceToForwardViewportBorder_relToViewportWidth = GetDistanceToViewportBorder_relToViewportWidth(out distanceToForwardViewportBorder_isValid, camera, position, textDir_inAspectCorrected1by1SquareViewportSpace_normalized); + if (distanceToForwardViewportBorder_isValid) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(autoLineBreakWidth_relToViewportWidth)) + { + return distanceToForwardViewportBorder_relToViewportWidth; + } + else + { + return Mathf.Min(autoLineBreakWidth_relToViewportWidth, distanceToForwardViewportBorder_relToViewportWidth); + } + } + else + { + return autoLineBreakWidth_relToViewportWidth; + } + } + else + { + if (textAnchor == DrawText.TextAnchorDXXL.LowerRight || textAnchor == DrawText.TextAnchorDXXL.LowerRightOfFirstLine || textAnchor == DrawText.TextAnchorDXXL.MiddleRight || textAnchor == DrawText.TextAnchorDXXL.UpperRight) + { + bool distanceToBackwardViewportBorder_isValid; + float distanceToBackwardViewportBorder_relToViewportWidth = GetDistanceToViewportBorder_relToViewportWidth(out distanceToBackwardViewportBorder_isValid, camera, position, -textDir_inAspectCorrected1by1SquareViewportSpace_normalized); + if (distanceToBackwardViewportBorder_isValid) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(autoLineBreakWidth_relToViewportWidth)) + { + return distanceToBackwardViewportBorder_relToViewportWidth; + } + else + { + return Mathf.Min(autoLineBreakWidth_relToViewportWidth, distanceToBackwardViewportBorder_relToViewportWidth); + } + } + else + { + return autoLineBreakWidth_relToViewportWidth; + } + } + else + { + //TextAnchorExt: Middle + bool distanceToForwardViewportBorder_isValid; + float distanceToForwardViewportBorder_relToViewportWidth = GetDistanceToViewportBorder_relToViewportWidth(out distanceToForwardViewportBorder_isValid, camera, position, textDir_inAspectCorrected1by1SquareViewportSpace_normalized); + bool distanceToBackwardViewportBorder_isValid; + float distanceToBackwardViewportBorder_relToViewportWidth = GetDistanceToViewportBorder_relToViewportWidth(out distanceToBackwardViewportBorder_isValid, camera, position, -textDir_inAspectCorrected1by1SquareViewportSpace_normalized); + if (distanceToForwardViewportBorder_isValid && distanceToBackwardViewportBorder_isValid) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(autoLineBreakWidth_relToViewportWidth)) + { + return Mathf.Min(2.0f * distanceToForwardViewportBorder_relToViewportWidth, 2.0f * distanceToBackwardViewportBorder_relToViewportWidth); + } + else + { + return UtilitiesDXXL_Math.Min(autoLineBreakWidth_relToViewportWidth, 2.0f * distanceToForwardViewportBorder_relToViewportWidth, 2.0f * distanceToBackwardViewportBorder_relToViewportWidth); + } + } + else + { + if (distanceToForwardViewportBorder_isValid) + { + return Mathf.Min(2.0f * distanceToForwardViewportBorder_relToViewportWidth, autoLineBreakWidth_relToViewportWidth); + } + else + { + if (distanceToBackwardViewportBorder_isValid) + { + return Mathf.Min(autoLineBreakWidth_relToViewportWidth, 2.0f * distanceToBackwardViewportBorder_relToViewportWidth); + } + else + { + return autoLineBreakWidth_relToViewportWidth; + } + } + } + } + } + } + else + { + return autoLineBreakWidth_relToViewportWidth; + } + } + + static InternalDXXL_Line2D line2D_inNonSquareViewportSpace_forViewportBorderDistanceCalculation = new InternalDXXL_Line2D(); + static InternalDXXL_Line2D line2D_inAspectCorrected1by1SquareViewportSpace_forViewportBorderDistanceCalculation = new InternalDXXL_Line2D(); + static float GetDistanceToViewportBorder_relToViewportWidth(out bool distanceIsValid, Camera camera, Vector2 fromPosition, Vector2 textDir_inAspectCorrected1by1SquareViewportSpace_normalized) + { + if (Mathf.Abs(textDir_inAspectCorrected1by1SquareViewportSpace_normalized.y) < 0.0001f) + { + //dir is horizontal: + if (textDir_inAspectCorrected1by1SquareViewportSpace_normalized.x > 0.0f) + { + distanceIsValid = (fromPosition.x < 1.0f); + return (1.0f - fromPosition.x); + } + else + { + distanceIsValid = (fromPosition.x > 0.0f); + return fromPosition.x; + } + } + else + { + if (Mathf.Abs(textDir_inAspectCorrected1by1SquareViewportSpace_normalized.x) < 0.0001f) + { + //dir is vertical: + if (textDir_inAspectCorrected1by1SquareViewportSpace_normalized.y > 0.0f) + { + distanceIsValid = (fromPosition.y < 1.0f); + return (1.0f - fromPosition.y) / camera.aspect; + } + else + { + distanceIsValid = (fromPosition.y > 0.0f); + return fromPosition.y / camera.aspect; + } + } + else + { + //dir is NOT horizonal/vertical: + Vector2 textDir_inNonSquareViewportSpace = new Vector2(textDir_inAspectCorrected1by1SquareViewportSpace_normalized.x, textDir_inAspectCorrected1by1SquareViewportSpace_normalized.y * camera.aspect); + line2D_inNonSquareViewportSpace_forViewportBorderDistanceCalculation.Recalc_line_throughTwoPoints_notVertLineProof(fromPosition, fromPosition + textDir_inNonSquareViewportSpace); + if (textDir_inAspectCorrected1by1SquareViewportSpace_normalized.y > 0.0f) + { + //dir is skewed upward: + Vector2 intersectionWithUpperViewportBorder = new Vector2(line2D_inNonSquareViewportSpace_forViewportBorderDistanceCalculation.GetXatY(1.0f), 1.0f); + if (0.0f <= intersectionWithUpperViewportBorder.x && intersectionWithUpperViewportBorder.x <= 1.0f) + { + //line intersects with upper viewport border: + distanceIsValid = (fromPosition.y < 1.0f); + Vector3 toNearestBoarder = intersectionWithUpperViewportBorder - fromPosition; + toNearestBoarder.y = toNearestBoarder.y / camera.aspect; + return toNearestBoarder.magnitude; + } + else + { + //line intersects with a side border: + line2D_inAspectCorrected1by1SquareViewportSpace_forViewportBorderDistanceCalculation.Recalc_line_throughTwoPoints_notVertLineProof(fromPosition, fromPosition + textDir_inAspectCorrected1by1SquareViewportSpace_normalized); + if (textDir_inAspectCorrected1by1SquareViewportSpace_normalized.x > 0.0f) + { + //dir to upward-right: + Vector2 intersectionWithRightViewportBorder = new Vector2(1.0f, line2D_inAspectCorrected1by1SquareViewportSpace_forViewportBorderDistanceCalculation.GetYatX(1.0f)); + distanceIsValid = ((fromPosition.x < 1.0f) && (fromPosition.y < 1.0f)); + Vector3 toNearestBoarder = intersectionWithRightViewportBorder - fromPosition; + return toNearestBoarder.magnitude; + } + else + { + //dir to upward-left: + Vector2 intersectionWithLeftViewportBorder = new Vector2(0.0f, line2D_inAspectCorrected1by1SquareViewportSpace_forViewportBorderDistanceCalculation.GetYatX(0.0f)); + distanceIsValid = ((fromPosition.x > 0.0f) && (fromPosition.y < 1.0f)); + Vector3 toNearestBoarder = intersectionWithLeftViewportBorder - fromPosition; + return toNearestBoarder.magnitude; + } + } + } + else + { + //dir is skewed downward: + Vector2 intersectionWithLowerViewportBorder = new Vector2(line2D_inNonSquareViewportSpace_forViewportBorderDistanceCalculation.GetXatY(0.0f), 0.0f); + if (0.0f <= intersectionWithLowerViewportBorder.x && intersectionWithLowerViewportBorder.x <= 1.0f) + { + //line intersects with lower viewport border: + distanceIsValid = (fromPosition.y > 0.0f); + Vector3 toNearestBoarder = intersectionWithLowerViewportBorder - fromPosition; + toNearestBoarder.y = toNearestBoarder.y / camera.aspect; + return toNearestBoarder.magnitude; + } + else + { + //line intersects with a side border: + line2D_inAspectCorrected1by1SquareViewportSpace_forViewportBorderDistanceCalculation.Recalc_line_throughTwoPoints_notVertLineProof(fromPosition, fromPosition + textDir_inAspectCorrected1by1SquareViewportSpace_normalized); + if (textDir_inAspectCorrected1by1SquareViewportSpace_normalized.x > 0.0f) + { + //dir to downward-right: + Vector2 intersectionWithRightViewportBorder = new Vector2(1.0f, line2D_inAspectCorrected1by1SquareViewportSpace_forViewportBorderDistanceCalculation.GetYatX(1.0f)); + distanceIsValid = ((fromPosition.x < 1.0f) && (fromPosition.y > 0.0f)); + Vector3 toNearestBoarder = intersectionWithRightViewportBorder - fromPosition; + return toNearestBoarder.magnitude; + } + else + { + //dir to downward-left: + Vector2 intersectionWithLeftViewportBorder = new Vector2(0.0f, line2D_inAspectCorrected1by1SquareViewportSpace_forViewportBorderDistanceCalculation.GetYatX(0.0f)); + distanceIsValid = ((fromPosition.x > 0.0f) && (fromPosition.y > 0.0f)); + Vector3 toNearestBoarder = intersectionWithLeftViewportBorder - fromPosition; + return toNearestBoarder.magnitude; + } + } + } + } + } + } + + static InternalDXXL_Plane planeInWhichTextLies = new InternalDXXL_Plane(); + static LineAnimationProgress unusedLineAnimProgress = new LineAnimationProgress(); + static void DrawEncapsulatingBox(bool skipDraw, float size, float scaleFactorFromForceWholeTextBlockWidth, Color color, Vector3 textDirNormalized, Vector3 textUpNormalized, DrawBasics.LineStyle enclosingBoxLineStyle, float enclosingBox_paddingOffset_relToTextSize, float enclosingBox_lineWidth_relToTextSize, float durationInSec, bool hiddenByNearerObjects) + { + if (enclosingBoxLineStyle != DrawBasics.LineStyle.invisible) + { + float used_size = size * scaleFactorFromForceWholeTextBlockWidth; + planeInWhichTextLies.Recreate(DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine, DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine + textDirNormalized, DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine + textUpNormalized); + float patternScaleFactor = used_size * 10.0f; + float enclosingBox_paddingOffset_worldSpace = enclosingBox_paddingOffset_relToTextSize * used_size; + float enclosingBox_lineWidth_worldSpace; + if (UtilitiesDXXL_Math.ApproximatelyZero(enclosingBox_lineWidth_relToTextSize)) + { + enclosingBox_lineWidth_worldSpace = 0.0f; + } + else + { + enclosingBox_lineWidth_worldSpace = enclosingBox_lineWidth_relToTextSize * used_size; + } + enclosingBox_lineWidth_worldSpace = UtilitiesDXXL_Math.AbsNonZeroValue(enclosingBox_lineWidth_worldSpace); + float halfLineWidth_worldSpace = 0.5f * enclosingBox_lineWidth_worldSpace; + float approximateLengthOfLongestBoxEdge = Math.Max(Mathf.Abs(DrawText.parsedTextSpecs.widthOfLongestLine + 2.0f * enclosingBox_paddingOffset_worldSpace + enclosingBox_lineWidth_worldSpace), Mathf.Abs(DrawText.parsedTextSpecs.height_wholeTextBlock + 2.0f * enclosingBox_paddingOffset_worldSpace + enclosingBox_lineWidth_worldSpace)); + approximateLengthOfLongestBoxEdge = Mathf.Max(approximateLengthOfLongestBoxEdge, used_size); + float amplitude; + if (enclosingBoxLineStyle == DrawBasics.LineStyle.solid) { patternScaleFactor = 1.0f; } //-> omits a warning for small lines, that doesn't apply for solid lines + UtilitiesDXXL_LineStyles.RefillListOfSubLines(Vector3.zero, new Vector3(approximateLengthOfLongestBoxEdge, 0.0f, 0.0f), enclosingBoxLineStyle, patternScaleFactor, enclosingBox_lineWidth_worldSpace, out amplitude, Vector3.up, 0.0f, ref unusedLineAnimProgress, false, false, 1.0f); //<- Is only for obtaining the "amplitude", but not for drawing + amplitude = UtilitiesDXXL_Math.AbsNonZeroValue(amplitude); + float halfAmplitude = 0.5f * amplitude; + + Vector3 offsetForMiteredCornerStyle_towardsRight = textDirNormalized * halfLineWidth_worldSpace; + Vector3 offsetForMiteredCornerStyle_towardsUp = textUpNormalized * halfLineWidth_worldSpace; + float additionalShiftThatExceedsTheTightParsedSpecsBoundingBox = enclosingBox_paddingOffset_worldSpace + halfLineWidth_worldSpace + halfAmplitude; + Vector3 lowLeftPosOfFirstLine_shiftedToUpperLine = DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine + textUpNormalized * ((0.8f * relLineDistance * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine) + additionalShiftThatExceedsTheTightParsedSpecsBoundingBox); + Vector3 lowLeftPosOfFirstLine_shiftedToLowerLine = DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine - textUpNormalized * (DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine + additionalShiftThatExceedsTheTightParsedSpecsBoundingBox + 0.2f * relLineDistance * used_size); + + Vector3 upperLeftCorner_exclOffsetForMiteredCornerStyle = lowLeftPosOfFirstLine_shiftedToUpperLine - textDirNormalized * (additionalShiftThatExceedsTheTightParsedSpecsBoundingBox + 0.1f * relLineDistance * used_size); + Vector3 upperRightCorner_exclOffsetForMiteredCornerStyle = lowLeftPosOfFirstLine_shiftedToUpperLine + textDirNormalized * (DrawText.parsedTextSpecs.widthOfLongestLine + additionalShiftThatExceedsTheTightParsedSpecsBoundingBox + 0.1f * relLineDistance * used_size); + Vector3 lowerLeftCorner_exclOffsetForMiteredCornerStyle = lowLeftPosOfFirstLine_shiftedToLowerLine - textDirNormalized * (additionalShiftThatExceedsTheTightParsedSpecsBoundingBox + 0.1f * relLineDistance * used_size); + Vector3 lowerRightCorner_exclOffsetForMiteredCornerStyle = lowLeftPosOfFirstLine_shiftedToLowerLine + textDirNormalized * (DrawText.parsedTextSpecs.widthOfLongestLine + additionalShiftThatExceedsTheTightParsedSpecsBoundingBox + 0.1f * relLineDistance * used_size); + + if (skipDraw == false) + { + UtilitiesDXXL_DrawBasics.Line(upperLeftCorner_exclOffsetForMiteredCornerStyle - offsetForMiteredCornerStyle_towardsRight, upperRightCorner_exclOffsetForMiteredCornerStyle + offsetForMiteredCornerStyle_towardsRight, color, enclosingBox_lineWidth_worldSpace, null, enclosingBoxLineStyle, patternScaleFactor, 0.0f, null, planeInWhichTextLies, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(lowerLeftCorner_exclOffsetForMiteredCornerStyle - offsetForMiteredCornerStyle_towardsRight, lowerRightCorner_exclOffsetForMiteredCornerStyle + offsetForMiteredCornerStyle_towardsRight, color, enclosingBox_lineWidth_worldSpace, null, enclosingBoxLineStyle, patternScaleFactor, 0.0f, null, planeInWhichTextLies, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(upperLeftCorner_exclOffsetForMiteredCornerStyle + offsetForMiteredCornerStyle_towardsUp, lowerLeftCorner_exclOffsetForMiteredCornerStyle - offsetForMiteredCornerStyle_towardsUp, color, enclosingBox_lineWidth_worldSpace, null, enclosingBoxLineStyle, patternScaleFactor, 0.0f, null, planeInWhichTextLies, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + UtilitiesDXXL_DrawBasics.Line(upperRightCorner_exclOffsetForMiteredCornerStyle + offsetForMiteredCornerStyle_towardsUp, lowerRightCorner_exclOffsetForMiteredCornerStyle - offsetForMiteredCornerStyle_towardsUp, color, enclosingBox_lineWidth_worldSpace, null, enclosingBoxLineStyle, patternScaleFactor, 0.0f, null, planeInWhichTextLies, true, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f); + } + + DrawText.parsedTextSpecs.lowLeftPos_ofEnclosingBox = lowerLeftCorner_exclOffsetForMiteredCornerStyle; + DrawText.parsedTextSpecs.lowRightPos_ofEnclosingBox = lowerRightCorner_exclOffsetForMiteredCornerStyle; + DrawText.parsedTextSpecs.upperLeftPos_ofEnclosingBox = upperLeftCorner_exclOffsetForMiteredCornerStyle; + DrawText.parsedTextSpecs.upperRightPos_ofEnclosingBox = upperRightCorner_exclOffsetForMiteredCornerStyle; + } + } + + static void ConvertParsedSpecs_toViewportSpace(Camera camera, Vector2 position, Vector3 pos_worldSpace, Vector3 textDir_worldSpace_normalized, Vector3 textUp_worldSpace_normalized) + { + Vector3 endPos_ofLongestLine_worldSpace = pos_worldSpace + textDir_worldSpace_normalized * DrawText.parsedTextSpecs.widthOfLongestLine; + Vector2 endPos_ofLongestLine_nonSquareViewportSpace0to1 = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(camera, endPos_ofLongestLine_worldSpace, false); + DrawText.parsedTextSpecs.widthOfLongestLine = (endPos_ofLongestLine_nonSquareViewportSpace0to1 - position).magnitude; //=magnitude in (warped) nonSquareViewportSpace + + Vector3 endPos_ofBiggestCharAfterStartPosIfWroteUpwards_worldSpace = pos_worldSpace + camera.transform.up * DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine; + Vector2 endPos_ofBiggestCharAfterStartPosIfWroteUpwards_nonSquareViewportSpace0to1 = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(camera, endPos_ofBiggestCharAfterStartPosIfWroteUpwards_worldSpace, false); + DrawText.parsedTextSpecs.sizeOfBiggestCharInFirstLine = (endPos_ofBiggestCharAfterStartPosIfWroteUpwards_nonSquareViewportSpace0to1 - position).magnitude; //=magnitude in (warped) nonSquareViewportSpace + + //slightly imprecise due to the transformation happening at posible shifted positions (could be improved by considering 'textAnchorPos' instead of 'pos_worldSpace'): + Vector3 highestPos_worldSpace = pos_worldSpace + textUp_worldSpace_normalized * DrawText.parsedTextSpecs.height_wholeTextBlock; + Vector2 highestPos_nonSquareViewportSpace0to1 = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(camera, highestPos_worldSpace, false); + DrawText.parsedTextSpecs.height_wholeTextBlock = (highestPos_nonSquareViewportSpace0to1 - position).magnitude; //=magnitude in (warped) nonSquareViewportSpace + + //slightly imprecise due to the transformation happening at posible shifted positions (could be improved by considering 'textAnchorPos' instead of 'pos_worldSpace'): + Vector3 highestPosLines_worldSpace = pos_worldSpace + textUp_worldSpace_normalized * DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine; + Vector2 highestPosLines_nonSquareViewportSpace0to1 = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(camera, highestPosLines_worldSpace, false); + DrawText.parsedTextSpecs.height_lowFirstLine_toLowLastLine = (highestPosLines_nonSquareViewportSpace0to1 - position).magnitude; //=magnitude in (warped) nonSquareViewportSpace + + DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(camera, DrawText.parsedTextSpecs.lowLeftPos_ofFirstLine, false); + } + + static void ConvertParsedSpecsOnCircle_toViewportSpace(Camera camera, Vector3 circleCenterPosition_worldSpace, Vector3 textsInitialUp_worldSpace_normalized, float radius_worldSpace, Vector2 approxStartPos_inAspectCorrected1by1SquareViewportSpace) + { + Vector3 startPos_worldSpace = circleCenterPosition_worldSpace + textsInitialUp_worldSpace_normalized * radius_worldSpace; + //using "camera.transform.up" here means: result is relative to viewport height: + Vector3 endPos_ofBiggestCharAfterStartPosIfWroteUpwards_worldSpace = startPos_worldSpace + camera.transform.up * DrawText.parsedTextOnCircleSpecs.sizeOfBiggestCharInFirstLine; + Vector2 endPos_ofBiggestCharAfterStartPosIfWroteUpwards_viewportSpace0to1 = UtilitiesDXXL_Screenspace.WorldPos_to_ViewportPos0to1(camera, endPos_ofBiggestCharAfterStartPosIfWroteUpwards_worldSpace, false); + DrawText.parsedTextOnCircleSpecs.sizeOfBiggestCharInFirstLine = (endPos_ofBiggestCharAfterStartPosIfWroteUpwards_viewportSpace0to1 - approxStartPos_inAspectCorrected1by1SquareViewportSpace).magnitude; + } + + static DrawText.AutomaticTextOrientation automaticTextOrientation_before; + public static void Set_automaticTextOrientation_reversible(DrawText.AutomaticTextOrientation new_automaticTextOrientation) + { + automaticTextOrientation_before = DrawText.automaticTextOrientation; + DrawText.automaticTextOrientation = new_automaticTextOrientation; + } + public static void Reverse_automaticTextOrientation() + { + DrawText.automaticTextOrientation = automaticTextOrientation_before; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Text.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Text.cs.meta new file mode 100644 index 0000000..0e05738 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_Text.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2be317109d9d5de419cdbe1aab9e66e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextDirAndUpCalculation.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextDirAndUpCalculation.cs new file mode 100644 index 0000000..4ca55a8 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextDirAndUpCalculation.cs @@ -0,0 +1,443 @@ +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; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextDirAndUpCalculation.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextDirAndUpCalculation.cs.meta new file mode 100644 index 0000000..7546684 --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextDirAndUpCalculation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb79887f4c3332347841d897351c7c40 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextTagForPointCollection.cs b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextTagForPointCollection.cs new file mode 100644 index 0000000..c62f47b --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextTagForPointCollection.cs @@ -0,0 +1,209 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class UtilitiesDXXL_TextTagForPointCollection + { + public static void TagPointCollection(string text, string headerText, Vector3 position, int usedSlotsInVerticesLocalList, float linesWidth, float textScalingFactor, Color colorForLinesAndHeader, Color colorForText, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + Vector3 virtualTransformScale = new Vector3(textScalingFactor, textScalingFactor, textScalingFactor); + TagPointCollection(text, headerText, position, usedSlotsInVerticesLocalList, linesWidth, virtualTransformScale, colorForLinesAndHeader, colorForText, textBlockAboveLine, durationInSec, hiddenByNearerObjects); + } + + public static void TagPointCollection(string text, string headerText, Vector3 position, int usedSlotsInVerticesLocalList, float linesWidth, Vector3 scaleOfTaggedTransform, Color colorForLinesAndHeader, Color colorForText, bool textBlockAboveLine, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (usedSlotsInVerticesLocalList <= 0) + { + UtilitiesDXXL_Log.PrintErrorCode("26-" + usedSlotsInVerticesLocalList + "(no textTagDrawing)"); + return; + } + + if ((text != null && text != "") || (headerText != null && headerText != "")) + { + GetTextPosAndOrientation(out Vector3 lineKinkWhereTextStarts_local, out Vector3 nearestVertexToText_local, out Vector3 textDir_normalized, out Vector3 textUp_normalized, usedSlotsInVerticesLocalList, position); + float biggestAbsDim = UtilitiesDXXL_Math.GetBiggestAbsComponent(scaleOfTaggedTransform); + biggestAbsDim = Mathf.Max(biggestAbsDim, 0.0001f); + Vector3 approxTextPosition = position + lineKinkWhereTextStarts_local; + float textSize_unclamped = Get_textSize_unclamped(biggestAbsDim, approxTextPosition); + float minTextSize = 0.01f; + float textSize = Mathf.Max(textSize_unclamped, minTextSize); + float maxWidthOfLinesTowardsText = textSize * 0.05f; + float widthOfLinesTowardsText = linesWidth; + widthOfLinesTowardsText = Mathf.Min(widthOfLinesTowardsText, maxWidthOfLinesTowardsText); + Color color_ofConnectionLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorForLinesAndHeader, 0.5f); + Line_fadeableAnimSpeed.InternalDraw(position + nearestVertexToText_local, position + lineKinkWhereTextStarts_local, color_ofConnectionLine, widthOfLinesTowardsText, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + + float lengthOfHorizLine = textSize; + Vector3 textPosition = position + lineKinkWhereTextStarts_local + textUp_normalized * (0.5f * widthOfLinesTowardsText + 0.32f * textSize); + if (text != null && text != "") + { + DrawText.TextAnchorDXXL textAnchor = textBlockAboveLine ? DrawText.TextAnchorDXXL.LowerLeft : DrawText.TextAnchorDXXL.UpperLeft; + UtilitiesDXXL_Text.Write(text, textPosition, colorForText, textSize, textDir_normalized, textUp_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + float lengthOfLongestLine_inText = DrawText.parsedTextSpecs.widthOfLongestLine; + lengthOfHorizLine = Mathf.Max(lengthOfLongestLine_inText, textSize); + } + + if (headerText != null && headerText != "") + { + //no strokeWidth-markup: trading execution time and code readability for GC.Alloc()-prevention: + DrawText.TextAnchorDXXL textAnchor_forHeader = textBlockAboveLine ? DrawText.TextAnchorDXXL.UpperLeft : DrawText.TextAnchorDXXL.LowerLeft; + Vector3 offsetForDoubledPrint = textDir_normalized * textSize * 0.11f; + Vector3 offsetForTripledPrint = textDir_normalized * textSize * 0.055f + textUp_normalized * textSize * 0.08f; + UtilitiesDXXL_Text.Write(headerText, textPosition, colorForLinesAndHeader, textSize, textDir_normalized, textUp_normalized, textAnchor_forHeader, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + float lengthOfLongestLine_inHeaderText = DrawText.parsedTextSpecs.widthOfLongestLine; + UtilitiesDXXL_Text.Write(headerText, textPosition + offsetForDoubledPrint, colorForLinesAndHeader, textSize, textDir_normalized, textUp_normalized, textAnchor_forHeader, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + UtilitiesDXXL_Text.Write(headerText, textPosition + offsetForTripledPrint, colorForLinesAndHeader, textSize, textDir_normalized, textUp_normalized, textAnchor_forHeader, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); + lengthOfHorizLine = Mathf.Max(lengthOfLongestLine_inHeaderText, lengthOfHorizLine); + } + + Line_fadeableAnimSpeed.InternalDraw(position + lineKinkWhereTextStarts_local, position + lineKinkWhereTextStarts_local + textDir_normalized * lengthOfHorizLine, color_ofConnectionLine, widthOfLinesTowardsText, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); + } + } + + static void GetTextPosAndOrientation(out Vector3 lineKinkWhereTextStarts_local, out Vector3 nearestVertexToText_local, out Vector3 textDir_normalized, out Vector3 textUp_normalized, int usedSlotsInVerticesLocalList, Vector3 position) + { + switch (DrawText.automaticTextOrientation) + { + case DrawText.AutomaticTextOrientation.screen: + GetTextPosAndOrientation_forAutoOrientationCase_screen(out lineKinkWhereTextStarts_local, out nearestVertexToText_local, out textDir_normalized, out textUp_normalized, usedSlotsInVerticesLocalList, position); + return; + case DrawText.AutomaticTextOrientation.screen_butVerticalInWorldSpace: + GetTextPosAndOrientation_forAutoOrientationCase_screen_butVerticalInWorldSpace(out lineKinkWhereTextStarts_local, out nearestVertexToText_local, out textDir_normalized, out textUp_normalized, usedSlotsInVerticesLocalList, position); + return; + case DrawText.AutomaticTextOrientation.xyPlane: + GetTextPosAndOrientation_forAutoOrientationCase_xyPlane(out lineKinkWhereTextStarts_local, out nearestVertexToText_local, out textDir_normalized, out textUp_normalized, usedSlotsInVerticesLocalList); + return; + case DrawText.AutomaticTextOrientation.xzPlane: + GetTextPosAndOrientation_forAutoOrientationCase_xzPlane(out lineKinkWhereTextStarts_local, out nearestVertexToText_local, out textDir_normalized, out textUp_normalized, usedSlotsInVerticesLocalList); + return; + case DrawText.AutomaticTextOrientation.zyPlane: + GetTextPosAndOrientation_forAutoOrientationCase_zyPlane(out lineKinkWhereTextStarts_local, out nearestVertexToText_local, out textDir_normalized, out textUp_normalized, usedSlotsInVerticesLocalList); + return; + default: + Debug.LogError("DrawText.automaticTextOrientation of " + DrawText.automaticTextOrientation + " is not implemented."); + GetTextPosAndOrientation_forAutoOrientationCase_xyPlane(out lineKinkWhereTextStarts_local, out nearestVertexToText_local, out textDir_normalized, out textUp_normalized, usedSlotsInVerticesLocalList); + return; + } + } + + static void GetTextPosAndOrientation_forAutoOrientationCase_screen(out Vector3 lineKinkWhereTextStarts_local, out Vector3 nearestVertexToText_local, out Vector3 textDir_normalized, out Vector3 textUp_normalized, int usedSlotsInVerticesLocalList, Vector3 position) + { + UtilitiesDXXL_TextDirAndUpCalculation.GetTextDirAndUpNormalized(out textDir_normalized, out textUp_normalized, default(Vector3), default(Vector3), position, false, false); + Vector3 virtualRawPosToWhichTextShouldHead_local = textDir_normalized * 1000.0f + Vector3.up; //-> adding "Vector3.up" so that the bistable horizontal case consistently chooses the upper vertices over the lower ones + nearestVertexToText_local = UtilitiesDXXL_Math.GetNearestVertex(virtualRawPosToWhichTextShouldHead_local, UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float positiveXEnd_local = UtilitiesDXXL_Math.GetHighestXComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float positiveYEnd_local = UtilitiesDXXL_Math.GetHighestYComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float positiveZEnd_local = UtilitiesDXXL_Math.GetHighestZComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float textOffsetDistance = UtilitiesDXXL_Math.Max(positiveXEnd_local, positiveYEnd_local, positiveZEnd_local) * 0.6f; + Vector3 observerCamera_forward = Vector3.Cross(textDir_normalized, textUp_normalized); + Quaternion rotation_aroundObserverCamForward_kinkingDirTowardsText = Quaternion.AngleAxis(45.0f, observerCamera_forward); + Vector3 offsetDir_normalized = rotation_aroundObserverCamForward_kinkingDirTowardsText * textDir_normalized; + lineKinkWhereTextStarts_local = nearestVertexToText_local + offsetDir_normalized * textOffsetDistance; + } + + static void GetTextPosAndOrientation_forAutoOrientationCase_screen_butVerticalInWorldSpace(out Vector3 lineKinkWhereTextStarts_local, out Vector3 nearestVertexToText_local, out Vector3 textDir_normalized, out Vector3 textUp_normalized, int usedSlotsInVerticesLocalList, Vector3 position) + { + UtilitiesDXXL_TextDirAndUpCalculation.GetTextDirAndUpNormalized(out textDir_normalized, out textUp_normalized, default(Vector3), default(Vector3), position, false, false); + Vector3 virtualRawPosToWhichTextShouldHead_local = textDir_normalized * 1000.0f + Vector3.up;//-> adding "Vector3.up" so that the bistable horizontal case consistently chooses the upper vertices over the lower ones + nearestVertexToText_local = UtilitiesDXXL_Math.GetNearestVertex(virtualRawPosToWhichTextShouldHead_local, UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float positiveXEnd_local = UtilitiesDXXL_Math.GetHighestXComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float positiveYEnd_local = UtilitiesDXXL_Math.GetHighestYComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float textOffsetDistance = Mathf.Max(positiveXEnd_local, positiveYEnd_local) * 0.6f; + Vector3 textOffset_unscaled = new Vector3(textDir_normalized.x, 1.0f, textDir_normalized.z); + lineKinkWhereTextStarts_local = nearestVertexToText_local + textOffset_unscaled * textOffsetDistance; + } + + static void GetTextPosAndOrientation_forAutoOrientationCase_xyPlane(out Vector3 lineKinkWhereTextStarts_local, out Vector3 nearestVertexToText_local, out Vector3 textDir_normalized, out Vector3 textUp_normalized, int usedSlotsInVerticesLocalList) + { + float positiveXEnd_local = UtilitiesDXXL_Math.GetHighestXComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float positiveYEnd_local = UtilitiesDXXL_Math.GetHighestYComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float negativeZEnd_local = UtilitiesDXXL_Math.GetLowestZComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + Vector3 textOffset = new Vector3(positiveXEnd_local * 0.5f, positiveYEnd_local * 0.5f, 0.0f); + lineKinkWhereTextStarts_local = new Vector3(positiveXEnd_local, positiveYEnd_local, negativeZEnd_local) + textOffset; + nearestVertexToText_local = UtilitiesDXXL_Math.GetNearestVertex(lineKinkWhereTextStarts_local, UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + textDir_normalized = Vector3.right; + textUp_normalized = Vector3.up; + } + + static void GetTextPosAndOrientation_forAutoOrientationCase_xzPlane(out Vector3 lineKinkWhereTextStarts_local, out Vector3 nearestVertexToText_local, out Vector3 textDir_normalized, out Vector3 textUp_normalized, int usedSlotsInVerticesLocalList) + { + float positiveXEnd_local = UtilitiesDXXL_Math.GetHighestXComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float positiveYEnd_local = UtilitiesDXXL_Math.GetHighestYComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float positiveZEnd_local = UtilitiesDXXL_Math.GetLowestZComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + Vector3 textOffset = new Vector3(positiveXEnd_local * 0.5f, 0.0f, positiveZEnd_local * 0.5f); + lineKinkWhereTextStarts_local = new Vector3(positiveXEnd_local, positiveYEnd_local, positiveZEnd_local) + textOffset; + nearestVertexToText_local = UtilitiesDXXL_Math.GetNearestVertex(lineKinkWhereTextStarts_local, UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + textDir_normalized = Vector3.right; + textUp_normalized = Vector3.forward; + } + + static void GetTextPosAndOrientation_forAutoOrientationCase_zyPlane(out Vector3 lineKinkWhereTextStarts_local, out Vector3 nearestVertexToText_local, out Vector3 textDir_normalized, out Vector3 textUp_normalized, int usedSlotsInVerticesLocalList) + { + float negativeXEnd_local = UtilitiesDXXL_Math.GetLowestXComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float positiveYEnd_local = UtilitiesDXXL_Math.GetHighestYComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + float negativeZEnd_local = UtilitiesDXXL_Math.GetLowestZComponent(UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + Vector3 textOffset = new Vector3(0.0f, positiveYEnd_local * 0.5f, negativeZEnd_local * 0.5f); + lineKinkWhereTextStarts_local = new Vector3(negativeXEnd_local, positiveYEnd_local, negativeZEnd_local) + textOffset; + nearestVertexToText_local = UtilitiesDXXL_Math.GetNearestVertex(lineKinkWhereTextStarts_local, UtilitiesDXXL_Shapes.verticesLocal, usedSlotsInVerticesLocalList); + textDir_normalized = Vector3.back; + textUp_normalized = Vector3.up; + } + + static float Get_textSize_unclamped(float biggestAbsDim, Vector3 approxTextPosition) + { + if (UtilitiesDXXL_Math.ApproximatelyZero(DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes) == false) + { + if (DrawBasics.cameraForAutomaticOrientation == DrawBasics.CameraForAutomaticOrientation.sceneViewCamera) + { +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + float distanceFromCam = (approxTextPosition - UnityEditor.SceneView.lastActiveSceneView.camera.transform.position).magnitude; + float lengthOfScreenHeight_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_vertExtentOfViewport_at_distanceFromCam(UnityEditor.SceneView.lastActiveSceneView.camera, distanceFromCam); + return lengthOfScreenHeight_atDrawnObjectsPosition * DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes; + } + else + { + return Get_textSizeRelativeToPointCollectionExtent(biggestAbsDim); + } +#else + return Get_textSizeRelativeToPointCollectionExtent(biggestAbsDim); +#endif + } + else + { + bool gameviewCameraIsAvailable = UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera gameviewCameraForDrawing, null, false); + if (gameviewCameraIsAvailable) + { + float distanceFromCam = (approxTextPosition - gameviewCameraForDrawing.transform.position).magnitude; + float lengthOfScreenHeight_atDrawnObjectsPosition = UtilitiesDXXL_Screenspace.Get_vertExtentOfViewport_at_distanceFromCam(gameviewCameraForDrawing, distanceFromCam); + return lengthOfScreenHeight_atDrawnObjectsPosition * DrawShapes.forcedConstantScreenspaceTextSize_relToScreenHeight_forTextAtShapes; + } + else + { + return Get_textSizeRelativeToPointCollectionExtent(biggestAbsDim); + } + } + } + else + { + if (UtilitiesDXXL_Math.ApproximatelyZero(DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes) == false) + { + return DrawShapes.forcedConstantWorldspaceTextSize_forTextAtShapes; + } + else + { + return Get_textSizeRelativeToPointCollectionExtent(biggestAbsDim); + } + } + } + + static float Get_textSizeRelativeToPointCollectionExtent(float biggestAbsDim) + { + return (biggestAbsDim * 0.2f); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextTagForPointCollection.cs.meta b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextTagForPointCollection.cs.meta new file mode 100644 index 0000000..75d8d2b --- /dev/null +++ b/Runtime/DrawDebugLibrary/internal utilities/UtilitiesDXXL_TextTagForPointCollection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8302712f13d0c044887e143f2dbf2f04 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous.meta b/Runtime/DrawDebugLibrary/miscellaneous.meta new file mode 100644 index 0000000..21f7502 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5c8e42dc5ef369b47a96f44c0794215f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/DXXLWrapperForUntiysBuildInDrawLines.cs b/Runtime/DrawDebugLibrary/miscellaneous/DXXLWrapperForUntiysBuildInDrawLines.cs new file mode 100644 index 0000000..76ea3a3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/DXXLWrapperForUntiysBuildInDrawLines.cs @@ -0,0 +1,438 @@ +//#define DRAWXXLGIZMODEBUG //-> delete the two slashes ("//") at the start of this line so that "//#define DRAWXXLGIZMODEBUG" becomes "#define DRAWXXLGIZMODEBUG" to start debugging. To end debugging simply add the two slashes as they were before. + +//-> Debugging with "#define DRAWXXLGIZMODEBUG" can help to fix errors like "ArgumentException: Gizmo drawing functions can only be used in OnDrawGizmos and OnDrawGizmosSelected." +//-> make sure to draw only one line when using "#define DRAWXXLGIZMODEBUG", respectively two lines: One from "Update()" and one from "OnDrawGizmos()". Otherwise there can be log spam that significantly slows down the Unity Editor. +//-> if you add a Gizmo Line Count Manager beforehand via "automatic" you may see more what's going on, because of the continuous repaint in Edit mode. +//-> the following snippet is handy for drawing the line [while I recommend to change the two "Vector3.zero" and the color to distinguish between the "Update()"-line and the "OnDrawGizmos()"-line]: +// DrawBasics.Line(Vector3.zero, Vector3.zero + new Vector3(Mathf.Sin((float)UnityEditor.EditorApplication.timeSinceStartup), Mathf.Cos((float)UnityEditor.EditorApplication.timeSinceStartup), 0), Color.red); + +namespace DrawXXL +{ + using UnityEngine; + using System.Collections.Generic; + + public class DXXLWrapperForUntiysBuildInDrawLines + { + static int mostRecentFrameCount_forWhichLinesPerFrameHasBeenZeroed = -1; + static bool drawingStopped_dueToTooManyDrawnLinesPerFrame = false; + static bool maxLinesPerFrameWarningTextDraw_hasAlreadyBeenStarted_duringCurrFrame = false; + static bool maxLinesPerFrameWarningTextDraw_hasAlreadyBeenFinished_duringCurrFrame = false; + static int frameCount_ofFrameInsidePausePhaseThatCanSafelyUseGizmoLines; + static int virtualGizmoCycleCount_inTheMomentOfLastClickOnPauseOrStepButton; + static int frameCountAfterStepDuringPausePhase_inWhichTheGizmoCycleCounterStarted; + + private static int drawnLinesSinceFrameStart = 0; + public static int DrawnLinesSinceFrameStart + { + get { return drawnLinesSinceFrameStart; } + set { Debug.Log("Not allowed to set 'DrawnLinesSinceFrameStart' manually."); } + } + + private static long drawnLinesSinceStart = 0; + public static long DrawnLinesSinceStart + { + get { return drawnLinesSinceStart; } + set { Debug.Log("Not allowed to set 'DrawnLinesSinceStart' manually."); } + } + + public static float globalAlphaFactor = 1.0f; //Don't change this value here. Use "DrawBasics.GlobalAlphaFactor" instead. + public static bool globalAlphaFactor_is0 = false; + public static bool globalAlphaFactor_is1 = true; + public static ChartDrawing currentlyDrawingChart = null; + public static PieChartDrawing currentlyDrawingPieChart = null; + + static DXXLWrapperForUntiysBuildInDrawLines() + { +#if UNITY_EDITOR + XericLibraryEditor.DrawDebug.DrawContextEditorIntegration.RegisterPauseCallback(OnPauseStateChanged); +#endif + } + + private static void OnPauseStateChanged() + { + frameCount_ofFrameInsidePausePhaseThatCanSafelyUseGizmoLines = Time.frameCount; + frameCountAfterStepDuringPausePhase_inWhichTheGizmoCycleCounterStarted = Time.frameCount; + } + + public static void TryDrawLine(Vector3 start, Vector3 end, Color color, float duration, bool depthTest) + { + //-> all draw operations of Draw XXL arrive here + //-> from here the lines may be forwarded to a wrapper that displays lines based on other preferred technology (e.g. optimized meshes). + + if (globalAlphaFactor_is1 == false) { color.a = color.a * globalAlphaFactor; } + + if (drawingStopped_dueToTooManyDrawnLinesPerFrame == false) + { + switch (DrawBasics.usedUnityLineDrawingMethod) + { + case DrawBasics.UsedUnityLineDrawingMethod.debugLinesInPlayMode_gizmoLinesInEditModeAndPlaymodePauses: + ChooseDebugOrGizmoLines_dependingOnPlayModeState(start, end, color, duration, depthTest); + break; + case DrawBasics.UsedUnityLineDrawingMethod.debugLines: + DrawLine_viaDebugDrawLine(start, end, color, duration, depthTest); + break; + case DrawBasics.UsedUnityLineDrawingMethod.gizmoLines: + DrawLine_viaGizmosDrawLine(start, end, color); + break; + case DrawBasics.UsedUnityLineDrawingMethod.handlesLines: + DrawLine_viaHandlesDrawLine(start, end, color); + break; + case DrawBasics.UsedUnityLineDrawingMethod.wireMesh: + AddLineToCacheForMesh(start, end, color, duration, depthTest); + break; + default: + //-> do not throw a log here, since it could happen poentially ten thousands of times per frame + //UtilitiesDXXL_Log.PrintErrorCode("**-" + DrawBasics.usedUnityLineDrawingMethod); //-> "DrawBasics.UsedUnityLineDrawingMethod.disabled" should already have been prevented earlier in "CheckIfDrawingIsCurrentlySkipped()" + break; + } + IncrementDrawnLinesPerFrameAndPreventEditorFreeze(); + } + } + + static void ChooseDebugOrGizmoLines_dependingOnPlayModeState(Vector3 start, Vector3 end, Color color, float duration, bool depthTest) + { +#if UNITY_EDITOR + // 委托给 DrawContext 处理 Debug/Gizmos 的选择 + // DrawContext 自动根据 Application.isPlaying / EditorApplication.isPaused 选择绘制器 + XericLibraryEditor.DrawDebug.DrawContext.DrawLine(start, end, color, duration, depthTest); +#else + // 非编辑器环境直接使用 Debug.DrawLine + DrawLine_viaDebugDrawLine(start, end, color, duration, depthTest); +#endif + } + + static void DrawLine_viaDebugDrawLine(Vector3 start, Vector3 end, Color color, float duration, bool depthTest) + { + float used_duration = overwrite_durationInSec_globally ? globalOverwriteValueOf_durationInSec : duration; + bool used_depthTest = overwrite_hiddenByNearerObjects_globally ? globalOverwriteValueOf_hiddenByNearerObjects : depthTest; + Debug.DrawLine(start, end, color, used_duration, used_depthTest); + } + + static void DrawLine_viaGizmosDrawLine(Vector3 start, Vector3 end, Color color) + { + Color gizmoColor_before = Gizmos.color; + Gizmos.color = color; + Gizmos.DrawLine(start, end); + Gizmos.color = gizmoColor_before; + } + + static void DrawLine_viaHandlesDrawLine(Vector3 start, Vector3 end, Color color) + { + //-> lines with non-0-width could possibly be drawn cheaper when using Handles by using the "thickness"-parameter in "Handles.DrawLine()" + //-> but this thickness paramter isn't there in older Unity versions + //-> Unity's code on Github for "Handles.DrawLine()" has a comment, that describes that thick lines sometimes don't work: "can happen when editor is actually using OpenGL ES 2 (no instancing)" + +#if UNITY_EDITOR + Color handlesColor_before = UnityEditor.Handles.color; + UnityEditor.Handles.color = color; + UnityEditor.Handles.DrawLine(start, end); + UnityEditor.Handles.color = handlesColor_before; +#endif + } + + static void AddLineToCacheForMesh(Vector3 start, Vector3 end, Color color, float duration, bool depthTest) + { + if (Application.isPlaying) + { + if (depthTest) + { + DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices.Add(start); + DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices.Add(end); + DrawXXL_LinesManager.instance.colors_perMeshVertex.Add(color); + DrawXXL_LinesManager.instance.colors_perMeshVertex.Add(color); + } + else + { + DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_overlay.Add(start); + DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_overlay.Add(end); + DrawXXL_LinesManager.instance.colors_perMeshVertex_overlay.Add(color); + DrawXXL_LinesManager.instance.colors_perMeshVertex_overlay.Add(color); + } + + if (duration > 0.0f) + { + //implementation of "duration" combined with "overlay" is not existing yet. "duration" already works, but if an overlay shader will be activated in "DrawXXL_LinesManager.RecreateMaterialsArrayToFitTheSubMeshes" the duration-using-lines may get assigned to the wrong shader. + + //flip-flop-kindOfThing of "_version1" and "_version2" to prevent high number of expensive "list.Insert()" and "list.RemoveAt()": + float time_whenMeshLinesDelayedDisplayEnds = Time.time + duration; + + if (DrawXXL_LinesManager.instance.activeDurationCacheVersion == 1) + { + DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_delayed_version1.Add(start); + DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_delayed_version1.Add(end); + DrawXXL_LinesManager.instance.colors_perMeshVertex_delayed_version1.Add(color); + DrawXXL_LinesManager.instance.colors_perMeshVertex_delayed_version1.Add(color); //-> the second "Add()" is only to keep the lists symetric to the "lineStartAndEndPoints_asMeshVertices_delayed_version*"-lists, but is actually not necessary + DrawXXL_LinesManager.instance.time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version1.Add(time_whenMeshLinesDelayedDisplayEnds); + DrawXXL_LinesManager.instance.time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version1.Add(time_whenMeshLinesDelayedDisplayEnds); //-> the second "Add()" is only to keep the lists symetric to the "lineStartAndEndPoints_asMeshVertices_delayed_version*"-lists, but is actually not necessary + } + + if (DrawXXL_LinesManager.instance.activeDurationCacheVersion == 2) + { + DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_delayed_version2.Add(start); + DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_delayed_version2.Add(end); + DrawXXL_LinesManager.instance.colors_perMeshVertex_delayed_version2.Add(color); + DrawXXL_LinesManager.instance.colors_perMeshVertex_delayed_version2.Add(color); //-> the second "Add()" is only to keep the lists symetric to the "lineStartAndEndPoints_asMeshVertices_delayed_version*"-lists, but is actually not necessary + DrawXXL_LinesManager.instance.time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version2.Add(time_whenMeshLinesDelayedDisplayEnds); + DrawXXL_LinesManager.instance.time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version2.Add(time_whenMeshLinesDelayedDisplayEnds); //-> the second "Add()" is only to keep the lists symetric to the "lineStartAndEndPoints_asMeshVertices_delayed_version*"-lists, but is actually not necessary + } + } + } + else + { + DrawLine_viaDebugDrawLine(start, end, color, duration, depthTest); + } + } + + public static bool CheckIfDrawingIsCurrentlySkipped() + { + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.disabled) + { + return true; + } + else + { + if (globalAlphaFactor_is0) + { + return true; + } + else + { +#if UNITY_EDITOR + //-> when using only "usedUnityLineDrawingMethod == debugLines" then a gameobject instance would actually be not necessary. Though a distinction in code would potentially become complex for situations where the usedUnityLineDrawingMethod gets changed in all thinkable directions and at all thinkable times (also with and without domain reloads on enterPlaymode/reloadScripts) + DrawXXL_LinesManager.TryCreate(); +#else + DrawBasics.usedUnityLineDrawingMethod = DrawBasics.UsedUnityLineDrawingMethod.wireMesh; + DrawXXL_LinesManager.TryCreate(); +#endif + TryResetLinesPerFrameCounter(); //-> has only effect in the first call inside each FrameUpdate + return drawingStopped_dueToTooManyDrawnLinesPerFrame; + } + } + } + + static Camera[] activeCamerasOfTheScene = null; + static void IncrementDrawnLinesPerFrameAndPreventEditorFreeze() + { + drawnLinesSinceFrameStart++; + drawnLinesSinceStart++; + + TryResetLinesPerFrameCounter(); + if (drawnLinesSinceFrameStart >= DrawBasics.MaxAllowedDrawnLinesPerFrame) + { + if (maxLinesPerFrameWarningTextDraw_hasAlreadyBeenStarted_duringCurrFrame == false) + { + maxLinesPerFrameWarningTextDraw_hasAlreadyBeenStarted_duringCurrFrame = true; + try + { + if (activeCamerasOfTheScene == null) { activeCamerasOfTheScene = UnityEngine.Object.FindObjectsOfType(); } + if (activeCamerasOfTheScene != null) + { + int numberOfCamerasThatGetTheWarningDrawing = Mathf.Min(activeCamerasOfTheScene.Length, 25); + for (int i = 0; i < numberOfCamerasThatGetTheWarningDrawing; i++) + { + if (activeCamerasOfTheScene[i] != null) + { + if (activeCamerasOfTheScene[i].gameObject.activeInHierarchy) + { + if (activeCamerasOfTheScene[i].enabled) + { + if (i > 0) + { + //other cameras than first: + switch (DrawBasics.maxLinesExceededNotificationOnScreenType) + { + case DrawBasics.MaxLinesExceededNotificationOnScreenType.None: + break; + + default: + UtilitiesDXXL_Text.WriteScreenspace(activeCamerasOfTheScene[i], "", new Vector2(1.0f, 1.0f), default, 0.2f, 0.0f, DrawText.TextAnchorDXXL.UpperRight, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, false, 0.0f, false); + break; + } + } + else + { + //first camera: + switch (DrawBasics.maxLinesExceededNotificationOnScreenType) + { + case DrawBasics.MaxLinesExceededNotificationOnScreenType.ExplanationText: + UtilitiesDXXL_Text.WriteScreenspace(activeCamerasOfTheScene[i], "Draw XXL skips drawing of some lines because the adjustable limit of maxLinesPerFrame (currently set to '" + DrawBasics.MaxAllowedDrawnLinesPerFrame + "') was exceeded.)", new Vector2(1.0f, 1.0f), Color.red, 0.03f, 0.0f, DrawText.TextAnchorDXXL.UpperRight, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, false, 0.0f, false); + break; + + case DrawBasics.MaxLinesExceededNotificationOnScreenType.WarningSymbol: + UtilitiesDXXL_Text.WriteScreenspace(activeCamerasOfTheScene[i], "", new Vector2(1.0f, 1.0f), default, 0.2f, 0.0f, DrawText.TextAnchorDXXL.UpperRight, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, true, 0.0f, false, 0.0f, false); + break; + + case DrawBasics.MaxLinesExceededNotificationOnScreenType.None: + break; + } + } + } + } + } + } + } + } + catch + { + UtilitiesDXXL_Log.PrintErrorCode("12"); + } + + if (currentlyDrawingChart != null) { currentlyDrawingChart.DrawWarningForMaxLinesPerFrame(); } + if (currentlyDrawingPieChart != null) { currentlyDrawingPieChart.DrawWarningForMaxLinesPerFrame(); } + maxLinesPerFrameWarningTextDraw_hasAlreadyBeenFinished_duringCurrFrame = true; + + string message = (DrawBasics.maxLinesExceededNotificationInLogConsoleType == DrawBasics.MaxLinesExceededNotificationInLogConsoleType.None) ? null : GetErrorLogStringFor_maxLinesExceeded(); + switch (DrawBasics.maxLinesExceededNotificationInLogConsoleType) + { + case DrawBasics.MaxLinesExceededNotificationInLogConsoleType.Log: + Debug.Log(message); + break; + case DrawBasics.MaxLinesExceededNotificationInLogConsoleType.Warning: + Debug.LogWarning(message); + break; + case DrawBasics.MaxLinesExceededNotificationInLogConsoleType.Error: + Debug.LogError(message); + break; + case DrawBasics.MaxLinesExceededNotificationInLogConsoleType.None: + break; + } + } + else + { + if (maxLinesPerFrameWarningTextDraw_hasAlreadyBeenFinished_duringCurrFrame) + { + drawingStopped_dueToTooManyDrawnLinesPerFrame = true; + } + } + } + } + + static string GetErrorLogStringFor_maxLinesExceeded() + { + string textWithoutGizmoManagerComponentSuffix = "Draw XXL skips drawing of some lines because the limit of maxLinesPerFrame (currently set to '" + DrawBasics.MaxAllowedDrawnLinesPerFrame + "') was exceeded. This is done to prevent accidentally freezing the editor by massive use of draw operations. You can increase this threshold via 'DrawXXL.DrawBasics.MaxAllowedDrawnLinesPerFrame' if your computer can handle more calculations, though at your own risk."; + return textWithoutGizmoManagerComponentSuffix; + } + + public static void TryResetLinesPerFrameCounter() + { + if (Time.frameCount != mostRecentFrameCount_forWhichLinesPerFrameHasBeenZeroed) + { + ResetLinesPerFrameCounter(); + } + } + + public static void ResetLinesPerFrameCounter() + { + mostRecentFrameCount_forWhichLinesPerFrameHasBeenZeroed = Time.frameCount; + drawingStopped_dueToTooManyDrawnLinesPerFrame = false; + drawnLinesSinceFrameStart = 0; + maxLinesPerFrameWarningTextDraw_hasAlreadyBeenStarted_duringCurrFrame = false; + maxLinesPerFrameWarningTextDraw_hasAlreadyBeenFinished_duringCurrFrame = false; + + if (DrawXXL_LinesManager.instance != null) + { + if (DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices != null) + { + DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices.Clear(); + DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_overlay.Clear(); + DrawXXL_LinesManager.instance.colors_perMeshVertex.Clear(); + DrawXXL_LinesManager.instance.colors_perMeshVertex_overlay.Clear(); + + if (DrawBasics.usedUnityLineDrawingMethod == DrawBasics.UsedUnityLineDrawingMethod.wireMesh) + { + TryDrawEnduringLines(); + } + } + } + + } + + static void TryDrawEnduringLines() + { + if (DrawXXL_LinesManager.instance.activeDurationCacheVersion == 1) + { + DrawEnduringLinesAndFlipLinesCache(ref DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_delayed_version1, ref DrawXXL_LinesManager.instance.colors_perMeshVertex_delayed_version1, ref DrawXXL_LinesManager.instance.time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version1, ref DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_delayed_version2, ref DrawXXL_LinesManager.instance.colors_perMeshVertex_delayed_version2, ref DrawXXL_LinesManager.instance.time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version2); + } + else + { + if (DrawXXL_LinesManager.instance.activeDurationCacheVersion == 2) + { + DrawEnduringLinesAndFlipLinesCache(ref DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_delayed_version2, ref DrawXXL_LinesManager.instance.colors_perMeshVertex_delayed_version2, ref DrawXXL_LinesManager.instance.time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version2, ref DrawXXL_LinesManager.instance.lineStartAndEndPoints_asMeshVertices_delayed_version1, ref DrawXXL_LinesManager.instance.colors_perMeshVertex_delayed_version1, ref DrawXXL_LinesManager.instance.time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version1); + } + } + } + + static void DrawEnduringLinesAndFlipLinesCache(ref List lineStartAndEndPoints_asMeshVertices_delayed_activeVersionUntilNow,ref List colors_perMeshVertex_delayed_activeVersionUntilNow, ref List time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_activeVersionUntilNow, ref List lineStartAndEndPoints_asMeshVertices_delayed_activeVersionFromNowOn, ref List colors_perMeshVertex_delayed_activeVersionFromNowOn, ref List time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_activeVersionFromNowOn) + { + //This uses a flip-flop kind of thing of "_version1" and "_version2" to prevent high numbers of expensive "list.Insert()" and "list.RemoveAt()", which would be there for only one delayed-lines cache list + + //Clear the upcoming lists, so they only contain the lines from the untilNowActive-list that still persist after the time check of the untilNowActive-lists: + lineStartAndEndPoints_asMeshVertices_delayed_activeVersionFromNowOn.Clear(); + colors_perMeshVertex_delayed_activeVersionFromNowOn.Clear(); + time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_activeVersionFromNowOn.Clear(); + + float currentTime = Time.time; + for (int i_currentlyTreatedLineStartSlot = 0; i_currentlyTreatedLineStartSlot < time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_activeVersionUntilNow.Count; i_currentlyTreatedLineStartSlot++) + { + float ceasingTimeOfCurrentlyTreatedLine = time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_activeVersionUntilNow[i_currentlyTreatedLineStartSlot]; + if (currentTime <= ceasingTimeOfCurrentlyTreatedLine) + { + Vector3 startPos_ofStillEnduringLine = lineStartAndEndPoints_asMeshVertices_delayed_activeVersionUntilNow[i_currentlyTreatedLineStartSlot]; + Vector3 endPos_ofStillEnduringLine = lineStartAndEndPoints_asMeshVertices_delayed_activeVersionUntilNow[i_currentlyTreatedLineStartSlot + 1]; + Color color_ofStillEnduringLine = colors_perMeshVertex_delayed_activeVersionUntilNow[i_currentlyTreatedLineStartSlot]; + + //This line from a previous frame still exists and therefore will be drawn now right at the beginning of this frame, so its existence persist for now: + float durationInSec = 0.0f; //-> since it lives on in the "time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version*"-lists this redrawing will be done without another "durationInSec"-sheduling + bool hiddenByNearerObjects = true; //-> "hiddenByNearerObjects" is not finally implemented for "usedUnityLineDrawingMethod = mesh", therefore the default value is used here. + UtilitiesDXXL_DrawBasics.Line(startPos_ofStillEnduringLine, endPos_ofStillEnduringLine, color_ofStillEnduringLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false, null, false, 0.0f, 1.0f); + + //The line still exists and another ceasedExistence-check will be done with the other version of "time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_version*" in the next frame. + lineStartAndEndPoints_asMeshVertices_delayed_activeVersionFromNowOn.Add(startPos_ofStillEnduringLine); + lineStartAndEndPoints_asMeshVertices_delayed_activeVersionFromNowOn.Add(endPos_ofStillEnduringLine); + colors_perMeshVertex_delayed_activeVersionFromNowOn.Add(color_ofStillEnduringLine); + colors_perMeshVertex_delayed_activeVersionFromNowOn.Add(color_ofStillEnduringLine); + time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_activeVersionFromNowOn.Add(ceasingTimeOfCurrentlyTreatedLine); + time_perMeshVertex_whenMeshLinesDelayedDisplayEnds_activeVersionFromNowOn.Add(ceasingTimeOfCurrentlyTreatedLine); + } + else + { + //-> The time of this line has run up + //-> It will not be drawn in this frame + //-> It will not be transferred to the next frame, but cease its existence with the list.Clear() below. + } + + i_currentlyTreatedLineStartSlot++; //-> additional proceed, because: each line consists of two slots in the cache lists (one for "line start" and one for "line end") + } + + if (DrawXXL_LinesManager.instance.activeDurationCacheVersion == 1) + { + DrawXXL_LinesManager.instance.activeDurationCacheVersion = 2; + } + else + { + if (DrawXXL_LinesManager.instance.activeDurationCacheVersion == 2) + { + DrawXXL_LinesManager.instance.activeDurationCacheVersion = 1; + } + } + } + + static bool overwrite_durationInSec_globally = false; + static float globalOverwriteValueOf_durationInSec = 0.0f; + public static void ToggleGlobalOverwriteFor_durationInSec(bool globalOverwriteIsEnabled, float valueOf_durationInSec_thatShouldAlwaysBeEnforced = 0.0f) + { + overwrite_durationInSec_globally = globalOverwriteIsEnabled; + globalOverwriteValueOf_durationInSec = valueOf_durationInSec_thatShouldAlwaysBeEnforced; + } + + static bool overwrite_hiddenByNearerObjects_globally = false; + static bool globalOverwriteValueOf_hiddenByNearerObjects = true; + public static void ToggleGlobalOverwriteFor_hiddenByNearerObjects(bool globalOverwriteIsEnabled, bool valueOf_hiddenByNearerObjects_thatShouldAlwaysBeEnforced = true) + { + overwrite_hiddenByNearerObjects_globally = globalOverwriteIsEnabled; + globalOverwriteValueOf_hiddenByNearerObjects = valueOf_hiddenByNearerObjects_thatShouldAlwaysBeEnforced; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/DXXLWrapperForUntiysBuildInDrawLines.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/DXXLWrapperForUntiysBuildInDrawLines.cs.meta new file mode 100644 index 0000000..074264c --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/DXXLWrapperForUntiysBuildInDrawLines.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c32ff3adc694b244699fbc8a3fed716b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextOnCircleSpecs.cs b/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextOnCircleSpecs.cs new file mode 100644 index 0000000..8c9c70f --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextOnCircleSpecs.cs @@ -0,0 +1,21 @@ +namespace DrawXXL +{ + public class ParsedTextOnCircleSpecs + { + public float angleDegOfLongestLine; + public int numberOfChars_inLongestLine; //like "numberOfChars_afterParsingOutTheMarkupTags" this only contains characters that are still there after parsing out the richtext markup tags + public int numberOfChars_afterParsingOutTheMarkupTags; + public float sizeOfBiggestCharInFirstLine; + + public ParsedTextOnCircleSpecs GetCopy() + { + ParsedTextOnCircleSpecs copiedSpecs = new ParsedTextOnCircleSpecs(); + copiedSpecs.angleDegOfLongestLine = angleDegOfLongestLine; + copiedSpecs.numberOfChars_inLongestLine = numberOfChars_inLongestLine; + copiedSpecs.numberOfChars_afterParsingOutTheMarkupTags = numberOfChars_afterParsingOutTheMarkupTags; + copiedSpecs.sizeOfBiggestCharInFirstLine = sizeOfBiggestCharInFirstLine;//default in world units. If the drawing was exectuted using "WriteScreenspace" then it is relative to the viewport height, and might then by slighly inaccurate. + return copiedSpecs; + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextOnCircleSpecs.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextOnCircleSpecs.cs.meta new file mode 100644 index 0000000..9216ed2 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextOnCircleSpecs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f29e5433438a3dc4f80e5f7574956d5d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextSpecs.cs b/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextSpecs.cs new file mode 100644 index 0000000..b96d7da --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextSpecs.cs @@ -0,0 +1,52 @@ +namespace DrawXXL +{ + + using UnityEngine; + + public class ParsedTextSpecs + { + public float widthOfLongestLine; //default in world units. If the drawing was exectuted using "WriteScreenspace" then it is in viewportSpaceUnits. (note that viewportSpace mostly is non-square, resulting in same distances appearing with different lenths depending on wheather they are alined in x or y direction ) + public int numberOfChars_inLongestLine; //like "numberOfChars_afterParsingOutTheMarkupTags" this only contains characters that are still there after parsing out the richtext markup tags + public int numberOfChars_afterParsingOutTheMarkupTags; + public float sizeOfBiggestCharInFirstLine;//default in world units.If the drawing was exectuted using "WriteScreenspace" then it is in viewportSpaceUnits. (note that viewportSpace mostly is non-square, resulting in same distances appearing with different lenths depending on wheather they are alined in x or y direction ) + public float height_wholeTextBlock; //default in world units. If the drawing was exectuted using "WriteScreenspace" then it is in viewportSpaceUnits, and then (so only for SS) might be slightly imprecise. (note that viewportSpace mostly is non-square, resulting in same distances appearing with different lenths depending on wheather they are alined in x or y direction ) + public float height_lowFirstLine_toLowLastLine; //default in world units. If the drawing was exectuted using "WriteScreenspace" then it is in viewportSpaceUnits, and then (so only for SS) might be slightly imprecise. (note that viewportSpace mostly is non-square, resulting in same distances appearing with different lenths depending on wheather they are alined in x or y direction ) + public DrawText.TextAnchorDXXL usedTextAnchor; //may get unintuitively changed if "WriteScreenSpace(...autoFlipTextToPreventUpsideDown...)" is used + public Vector3 lowLeftPos_ofFirstLine; //may get unintuitively shifted if "WriteScreenSpace(...autoFlipTextToPreventUpsideDown...)" is used + public Vector3 used_textDirection_normalized; //If you didn't specify the textDirection/text-rotation by yourself then this is the direction that has been finally used by the automatic orientation (see "DrawText.automaticTextOrientation"(link)). This can be useful, if you want to draw automatically oriented text and then align other shapes relative to the text in an aligned layout. If you are drawing in screenspace then this is still in worldspace units, not in screenspace units, so you get a vector, that lies somehow in the camera plane. + public Vector3 used_textUp_normalized; //If you didn't specify the textUp-direction/text-rotation by yourself then this is the up direction that has been finally used by the automatic orientation (see "DrawText.automaticTextOrientation"(link)). This can be useful, if you want to draw automatically oriented text and then align other shapes relative to the text in an aligned layout. If you are drawing in screenspace then this is still in worldspace units, not in screenspace units, so you get a vector, that lies somehow in the camera plane. + public Vector3 lowLeftPos_ofEnclosingBox; //only filled for "boxStyle != invisible" + public Vector3 lowRightPos_ofEnclosingBox; //only filled for "boxStyle != invisible" + public Vector3 upperLeftPos_ofEnclosingBox; //only filled for "boxStyle != invisible" + public Vector3 upperRightPos_ofEnclosingBox; //only filled for "boxStyle != invisible" + + public ParsedTextSpecs GetCopy() + { + ParsedTextSpecs copiedSpecs = new ParsedTextSpecs(); + copiedSpecs.widthOfLongestLine = widthOfLongestLine; + copiedSpecs.numberOfChars_inLongestLine = numberOfChars_inLongestLine; + copiedSpecs.numberOfChars_afterParsingOutTheMarkupTags = numberOfChars_afterParsingOutTheMarkupTags; + copiedSpecs.sizeOfBiggestCharInFirstLine = sizeOfBiggestCharInFirstLine; + copiedSpecs.height_wholeTextBlock = height_wholeTextBlock; + copiedSpecs.height_lowFirstLine_toLowLastLine = height_lowFirstLine_toLowLastLine; + copiedSpecs.usedTextAnchor = usedTextAnchor; + copiedSpecs.lowLeftPos_ofFirstLine = lowLeftPos_ofFirstLine; + copiedSpecs.used_textDirection_normalized = used_textDirection_normalized; + copiedSpecs.used_textUp_normalized = used_textUp_normalized; + copiedSpecs.lowLeftPos_ofEnclosingBox = lowLeftPos_ofEnclosingBox; + copiedSpecs.lowRightPos_ofEnclosingBox = lowRightPos_ofEnclosingBox; + copiedSpecs.upperLeftPos_ofEnclosingBox = upperLeftPos_ofEnclosingBox; + copiedSpecs.upperRightPos_ofEnclosingBox = upperRightPos_ofEnclosingBox; + return copiedSpecs; + } + + public Vector3 RightEndOfWholeTextBlock_atLowEndOfFirstLine + { + //note that the y-value of the returned positon is at the low end of the first line, but the first line is not necessarly the longest line. The x-value is defined by the longest line. + get { return (lowLeftPos_ofFirstLine + used_textDirection_normalized * widthOfLongestLine); } + set { } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextSpecs.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextSpecs.cs.meta new file mode 100644 index 0000000..b942d43 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/ParsedTextSpecs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f98c11c1a0d8f564a9a000d5d68965fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects.meta new file mode 100644 index 0000000..8d393ab --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1d8555acb7392f54abbf5a5e0135cf78 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D.meta new file mode 100644 index 0000000..82ef975 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 86748cae89d7d6543b81735a0398be25 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineFrom_fadeableAnimSpeed_2D.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineFrom_fadeableAnimSpeed_2D.cs new file mode 100644 index 0000000..26ced04 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineFrom_fadeableAnimSpeed_2D.cs @@ -0,0 +1,46 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class LineFrom_fadeableAnimSpeed_2D : ParentOf_Lines_fadeableAnimSpeed_2D + { + public Vector2 start = Vector2.zero; + public Vector2 direction = Vector2.one; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public LineFrom_fadeableAnimSpeed_2D(Vector2 start, Vector2 direction) + { + this.start = start; + this.direction = direction; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(start, direction, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + lineAnimationProgress = InternalDraw_withColorFade(start, direction, color, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + + public static LineAnimationProgress InternalDraw(Vector2 start, Vector2 direction, Color color, float width, string text, DrawBasics.LineStyle style, float custom_zPos, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + return Ray_fadeableAnimSpeed_2D.InternalDraw(start, direction, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + public static LineAnimationProgress InternalDraw_withColorFade(Vector2 start, Vector2 direction, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float custom_zPos, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + return Ray_fadeableAnimSpeed_2D.InternalDrawColorFade(start, direction, startColor, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineFrom_fadeableAnimSpeed_2D.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineFrom_fadeableAnimSpeed_2D.cs.meta new file mode 100644 index 0000000..e3c5776 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineFrom_fadeableAnimSpeed_2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 088adf8aae92ab043aaf562383a64900 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineTo_fadeableAnimSpeed_2D.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineTo_fadeableAnimSpeed_2D.cs new file mode 100644 index 0000000..ab034d3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineTo_fadeableAnimSpeed_2D.cs @@ -0,0 +1,53 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class LineTo_fadeableAnimSpeed_2D : ParentOf_Lines_fadeableAnimSpeed_2D + { + public Vector2 direction = Vector2.one; + public Vector2 end = Vector2.zero; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public LineTo_fadeableAnimSpeed_2D(Vector2 direction, Vector2 end) + { + this.direction = direction; + this.end = end; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(direction, end, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + lineAnimationProgress = InternalDraw_withColorFade(direction, end, color, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + + public static LineAnimationProgress InternalDraw(Vector2 direction, Vector2 end, Color color, float width, string text, DrawBasics.LineStyle style, float custom_zPos, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + return Ray_fadeableAnimSpeed_2D.InternalDraw(end - direction, direction, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + public static LineAnimationProgress InternalDraw_withColorFade(Vector2 direction, Vector2 end, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float custom_zPos, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + return Ray_fadeableAnimSpeed_2D.InternalDrawColorFade(end - direction, direction, startColor, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineTo_fadeableAnimSpeed_2D.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineTo_fadeableAnimSpeed_2D.cs.meta new file mode 100644 index 0000000..ffc0fe2 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineTo_fadeableAnimSpeed_2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: edbac6eb23275604f8945fd659b58f64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineWithAlternatingColors_fadeableAnimSpeed_2D.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineWithAlternatingColors_fadeableAnimSpeed_2D.cs new file mode 100644 index 0000000..1078e20 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineWithAlternatingColors_fadeableAnimSpeed_2D.cs @@ -0,0 +1,47 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class LineWithAlternatingColors_fadeableAnimSpeed_2D : ParentOf_Lines_fadeableAnimSpeed_2D + { + public Vector2 start = Vector2.zero; + public Vector2 end = Vector2.one; + public Color alternatingColor = DrawBasics.defaultColor2_ofAlternatingColorLines; + public float lengthOfStripes = 0.04f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public LineWithAlternatingColors_fadeableAnimSpeed_2D(Vector2 start, Vector2 end) + { + this.start = start; + this.end = end; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + lineAnimationProgress = InternalDraw(start, end, color, alternatingColor, width, lengthOfStripes, text, custom_zPos, animationSpeed, lineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + public static LineAnimationProgress InternalDraw(Vector2 start, Vector2 end, Color color1, Color color2, float width, float lengthOfStripes, string text, float custom_zPos, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + //Lines drawn with this function have a higher likelyhood of accidentially using up high numbers of drawnLinePerFrame, because "lengthOfStripes" can be set manually instead of beeing determined by the lineStyle-code + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lengthOfStripes, "lengthOfStripes")) { return null; } + + lengthOfStripes = Mathf.Max(lengthOfStripes, 0.001f); + UtilitiesDXXL_LineStyles.curr_dashLength_forAlternatingColorStripesLine = lengthOfStripes; + Color prev_defaultAlternateColorOfStripedLines = DrawBasics.defaultColor2_ofAlternatingColorLines; + if (UtilitiesDXXL_Colors.IsDefaultColor(color2) == false) + { + DrawBasics.defaultColor2_ofAlternatingColorLines = color2; + } + LineAnimationProgress lineAnimationProgress = Line_fadeableAnimSpeed_2D.InternalDraw(start, end, color1, width, text, DrawBasics.LineStyle.alternatingColorStripes, custom_zPos, 1.0f, animationSpeed, precedingLineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + UtilitiesDXXL_LineStyles.curr_dashLength_forAlternatingColorStripesLine = UtilitiesDXXL_LineStyles.default_dashLength_forAlternatingColorStripesLine; + DrawBasics.defaultColor2_ofAlternatingColorLines = prev_defaultAlternateColorOfStripedLines; + return lineAnimationProgress; + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineWithAlternatingColors_fadeableAnimSpeed_2D.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineWithAlternatingColors_fadeableAnimSpeed_2D.cs.meta new file mode 100644 index 0000000..c063e5d --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/LineWithAlternatingColors_fadeableAnimSpeed_2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49f154dfbca7db94fbd0853a4becea96 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Line_fadeableAnimSpeed_2D.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Line_fadeableAnimSpeed_2D.cs new file mode 100644 index 0000000..78ea763 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Line_fadeableAnimSpeed_2D.cs @@ -0,0 +1,56 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class Line_fadeableAnimSpeed_2D : ParentOf_Lines_fadeableAnimSpeed_2D + { + public Vector2 start = Vector2.zero; + public Vector2 end = Vector2.one; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public Line_fadeableAnimSpeed_2D(Vector2 start, Vector2 end) + { + this.start = start; + this.end = end; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(start, end, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + lineAnimationProgress = InternalDrawColorFade(start, end, color, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + + public static LineAnimationProgress InternalDraw(Vector2 start, Vector2 end, Color color, float width, string text, DrawBasics.LineStyle style, float custom_zPos, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 startV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(start, zPos); + Vector3 endV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(end, zPos); + style = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(style); + return UtilitiesDXXL_DrawBasics.Line(startV3, endV3, color, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero, true, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, null, true, endPlates_size); + } + + public static LineAnimationProgress InternalDrawColorFade(Vector2 start, Vector2 end, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float custom_zPos, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 startV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(start, zPos); + Vector3 endV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(end, zPos); + style = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(style); + return UtilitiesDXXL_DrawBasics.LineColorFade(startV3, endV3, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero, true, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, null, true, endPlates_size, 1.0f); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Line_fadeableAnimSpeed_2D.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Line_fadeableAnimSpeed_2D.cs.meta new file mode 100644 index 0000000..33d3ca3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Line_fadeableAnimSpeed_2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3e548e7fc1483d468a96d2f848ae2b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsLine_fadeableAnimSpeed_2D.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsLine_fadeableAnimSpeed_2D.cs new file mode 100644 index 0000000..16c1653 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsLine_fadeableAnimSpeed_2D.cs @@ -0,0 +1,38 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class MovingArrowsLine_fadeableAnimSpeed_2D : ParentOf_Lines_fadeableAnimSpeed_2D + { + public Vector2 start = Vector2.zero; + public Vector2 end = Vector2.one; + public float distanceBetweenArrows = 0.5f; + public float lengthOfArrows = 0.15f; + public bool backwardAnimationFlipsArrowDirection = true; + + public MovingArrowsLine_fadeableAnimSpeed_2D(Vector2 start, Vector2 end) + { + this.start = start; + this.end = end; + width = 0.05f; + animationSpeed = 0.5f; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + lineAnimationProgress = InternalDraw(start, end, color, width, distanceBetweenArrows, lengthOfArrows, text, custom_zPos, animationSpeed, lineAnimationProgress, backwardAnimationFlipsArrowDirection, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + public static LineAnimationProgress InternalDraw(Vector2 start, Vector2 end, Color color, float lineWidth, float distanceBetweenArrows, float lengthOfArrows, string text, float custom_zPos, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, bool backwardAnimationFlipsArrowDirection, float endPlates_size, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + float zPos = UtilitiesDXXL_DrawBasics2D.TryFallbackToDefaultZ(custom_zPos); + Vector3 startV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(start, zPos); + Vector3 endV3 = UtilitiesDXXL_DrawBasics2D.Position_V2toV3(end, zPos); + return UtilitiesDXXL_DrawBasics.MovingArrowsLine(startV3, endV3, color, lineWidth, distanceBetweenArrows, lengthOfArrows, text, animationSpeed, precedingLineAnimationProgress, backwardAnimationFlipsArrowDirection, true, UtilitiesDXXL_DrawBasics2D.xyPlane_throughZero, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, true); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsLine_fadeableAnimSpeed_2D.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsLine_fadeableAnimSpeed_2D.cs.meta new file mode 100644 index 0000000..58ac111 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsLine_fadeableAnimSpeed_2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 659ff1f21b2084545adb1b16388f8eff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsRay_fadeableAnimSpeed_2D.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsRay_fadeableAnimSpeed_2D.cs new file mode 100644 index 0000000..9d5358e --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsRay_fadeableAnimSpeed_2D.cs @@ -0,0 +1,39 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class MovingArrowsRay_fadeableAnimSpeed_2D : ParentOf_Lines_fadeableAnimSpeed_2D + { + public Vector2 start = Vector2.zero; + public Vector2 direction = Vector2.one; + public float distanceBetweenArrows = 0.5f; + public float lengthOfArrows = 0.15f; + public bool backwardAnimationFlipsArrowDirection = true; + + public MovingArrowsRay_fadeableAnimSpeed_2D(Vector2 start, Vector2 direction) + { + this.start = start; + this.direction = direction; + width = 0.05f; + animationSpeed = 0.5f; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + lineAnimationProgress = InternalDraw(start, direction, color, width, distanceBetweenArrows, lengthOfArrows, text, custom_zPos, animationSpeed, lineAnimationProgress, backwardAnimationFlipsArrowDirection, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + public static LineAnimationProgress InternalDraw(Vector2 start, Vector2 direction, Color color, float lineWidth, float distanceBetweenArrows, float lengthOfArrows, string text, float custom_zPos, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, bool backwardAnimationFlipsArrowDirection, float endPlates_size, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + + Vector2 end = start + direction; + return MovingArrowsLine_fadeableAnimSpeed_2D.InternalDraw(start, end, color, lineWidth, distanceBetweenArrows, lengthOfArrows, text, custom_zPos, animationSpeed, precedingLineAnimationProgress, backwardAnimationFlipsArrowDirection, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsRay_fadeableAnimSpeed_2D.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsRay_fadeableAnimSpeed_2D.cs.meta new file mode 100644 index 0000000..b1a4aff --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/MovingArrowsRay_fadeableAnimSpeed_2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e028a464c86618c4dae6c4ce5794d09d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/RayWithAlternatingColors_fadeableAnimSpeed_2D.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/RayWithAlternatingColors_fadeableAnimSpeed_2D.cs new file mode 100644 index 0000000..f6c4acf --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/RayWithAlternatingColors_fadeableAnimSpeed_2D.cs @@ -0,0 +1,39 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class RayWithAlternatingColors_fadeableAnimSpeed_2D : ParentOf_Lines_fadeableAnimSpeed_2D + { + public Vector2 start = Vector2.zero; + public Vector2 direction = Vector2.one; + public Color alternatingColor = DrawBasics.defaultColor2_ofAlternatingColorLines; + public float lengthOfStripes = 0.04f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public RayWithAlternatingColors_fadeableAnimSpeed_2D(Vector2 start, Vector2 direction) + { + this.start = start; + this.direction = direction; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + lineAnimationProgress = InternalDraw(start, direction, color, alternatingColor, width, lengthOfStripes, text, custom_zPos, animationSpeed, lineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + public static LineAnimationProgress InternalDraw(Vector2 start, Vector2 direction, Color color1, Color color2, float width, float lengthOfStripes, string text, float custom_zPos, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + + Vector2 end = start + direction; + return LineWithAlternatingColors_fadeableAnimSpeed_2D.InternalDraw(start, end, color1, color2, width, lengthOfStripes, text, custom_zPos, animationSpeed, precedingLineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/RayWithAlternatingColors_fadeableAnimSpeed_2D.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/RayWithAlternatingColors_fadeableAnimSpeed_2D.cs.meta new file mode 100644 index 0000000..aba15c5 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/RayWithAlternatingColors_fadeableAnimSpeed_2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ec7bbe5c073a8d4cb21c6d776eb9b8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Ray_fadeableAnimSpeed_2D.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Ray_fadeableAnimSpeed_2D.cs new file mode 100644 index 0000000..ac523c1 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Ray_fadeableAnimSpeed_2D.cs @@ -0,0 +1,52 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class Ray_fadeableAnimSpeed_2D : ParentOf_Lines_fadeableAnimSpeed_2D + { + public Vector2 start = Vector2.zero; + public Vector2 direction = Vector2.one; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public Ray_fadeableAnimSpeed_2D(Vector2 start, Vector2 direction) + { + this.start = start; + this.direction = direction; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(start, direction, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + lineAnimationProgress = InternalDrawColorFade(start, direction, color, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + + public static LineAnimationProgress InternalDraw(Vector2 start, Vector2 direction, Color color, float width, string text, DrawBasics.LineStyle style, float custom_zPos, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + return Line_fadeableAnimSpeed_2D.InternalDraw(start, start + direction, color, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + public static LineAnimationProgress InternalDrawColorFade(Vector2 start, Vector2 direction, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float custom_zPos, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + return Line_fadeableAnimSpeed_2D.InternalDrawColorFade(start, start + direction, startColor, endColor, width, text, style, custom_zPos, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Ray_fadeableAnimSpeed_2D.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Ray_fadeableAnimSpeed_2D.cs.meta new file mode 100644 index 0000000..4b08d1a --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/2D/Ray_fadeableAnimSpeed_2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02f1cbdf9dc4b9a48a7a7f638519ea99 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D.meta new file mode 100644 index 0000000..f7e77da --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 352a7b71083683f4eb786a177d9f32b0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineFrom_fadeableAnimSpeed.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineFrom_fadeableAnimSpeed.cs new file mode 100644 index 0000000..e9d33f9 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineFrom_fadeableAnimSpeed.cs @@ -0,0 +1,46 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class LineFrom_fadeableAnimSpeed : ParentOf_Lines_fadeableAnimSpeed_3D + { + public Vector3 start = Vector3.zero; + public Vector3 direction = Vector3.one; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public LineFrom_fadeableAnimSpeed(Vector3 start, Vector3 direction) + { + this.start = start; + this.direction = direction; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(start, direction, color, width, text, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + lineAnimationProgress = InternalDraw_withColorFade(start, direction, color, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + + public static LineAnimationProgress InternalDraw(Vector3 start, Vector3 direction, Color color, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + return Ray_fadeableAnimSpeed.InternalDraw(start, direction, color, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + public static LineAnimationProgress InternalDraw_withColorFade(Vector3 start, Vector3 direction, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + return Ray_fadeableAnimSpeed.InternalDrawColorFade(start, direction, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineFrom_fadeableAnimSpeed.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineFrom_fadeableAnimSpeed.cs.meta new file mode 100644 index 0000000..ffc6430 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineFrom_fadeableAnimSpeed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f55aa9f1563678c45af983d400b79b5d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineTo_fadeableAnimSpeed.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineTo_fadeableAnimSpeed.cs new file mode 100644 index 0000000..c3de244 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineTo_fadeableAnimSpeed.cs @@ -0,0 +1,52 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class LineTo_fadeableAnimSpeed : ParentOf_Lines_fadeableAnimSpeed_3D + { + public Vector3 direction = Vector3.one; + public Vector3 end = Vector3.zero; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public LineTo_fadeableAnimSpeed(Vector3 direction, Vector3 end) + { + this.direction = direction; + this.end = end; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(direction, end, color, width, text, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + lineAnimationProgress = InternalDraw_withColorFade(direction, end, color, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + + public static LineAnimationProgress InternalDraw(Vector3 direction, Vector3 end, Color color, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + return Ray_fadeableAnimSpeed.InternalDraw(end - direction, direction, color, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + public static LineAnimationProgress InternalDraw_withColorFade(Vector3 direction, Vector3 end, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + return Ray_fadeableAnimSpeed.InternalDrawColorFade(end - direction, direction, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineTo_fadeableAnimSpeed.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineTo_fadeableAnimSpeed.cs.meta new file mode 100644 index 0000000..357aeed --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineTo_fadeableAnimSpeed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd6cc3a8b3c3a36448f7a2e8afdf74cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineWithAlternatingColors_fadeableAnimSpeed.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineWithAlternatingColors_fadeableAnimSpeed.cs new file mode 100644 index 0000000..c5ccac4 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineWithAlternatingColors_fadeableAnimSpeed.cs @@ -0,0 +1,49 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class LineWithAlternatingColors_fadeableAnimSpeed : ParentOf_Lines_fadeableAnimSpeed_3D + { + public Vector3 start = Vector3.zero; + public Vector3 end = Vector3.one; + public Color alternatingColor = DrawBasics.defaultColor2_ofAlternatingColorLines; + public float lengthOfStripes = 0.04f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public LineWithAlternatingColors_fadeableAnimSpeed(Vector3 start, Vector3 end) + { + this.start = start; + this.end = end; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + lineAnimationProgress = InternalDraw(start, end, color, alternatingColor, width, lengthOfStripes, text, animationSpeed, lineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + public static LineAnimationProgress InternalDraw(Vector3 start, Vector3 end, Color color1, Color color2, float width, float lengthOfStripes, string text, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + //Lines drawn with this function have a higher likelyhood of accidentially using up high numbers of drawnLinePerFrame, because "lengthOfStripes" can be set manually instead of beeing determined by the lineStyle-code + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lengthOfStripes, "lengthOfStripes")) { return null; } + + lengthOfStripes = Mathf.Max(lengthOfStripes, UtilitiesDXXL_DrawBasics.min_lengthOfStripes_ofAlternatingColorLine); + UtilitiesDXXL_LineStyles.curr_dashLength_forAlternatingColorStripesLine = lengthOfStripes; + Color prev_defaultAlternateColorOfStripedLines = DrawBasics.defaultColor2_ofAlternatingColorLines; + if (UtilitiesDXXL_Colors.IsDefaultColor(color2) == false) + { + DrawBasics.defaultColor2_ofAlternatingColorLines = color2; + } + LineAnimationProgress lineAnimationProgress = Line_fadeableAnimSpeed.InternalDraw(start, end, color1, width, text, DrawBasics.LineStyle.alternatingColorStripes, 1.0f, animationSpeed, precedingLineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + UtilitiesDXXL_LineStyles.curr_dashLength_forAlternatingColorStripesLine = UtilitiesDXXL_LineStyles.default_dashLength_forAlternatingColorStripesLine; + DrawBasics.defaultColor2_ofAlternatingColorLines = prev_defaultAlternateColorOfStripedLines; + + return lineAnimationProgress; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineWithAlternatingColors_fadeableAnimSpeed.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineWithAlternatingColors_fadeableAnimSpeed.cs.meta new file mode 100644 index 0000000..b3f8f61 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/LineWithAlternatingColors_fadeableAnimSpeed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8efbd770a0aaefc4cbf7335dabcdb7cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Line_fadeableAnimSpeed.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Line_fadeableAnimSpeed.cs new file mode 100644 index 0000000..ea6ac5e --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Line_fadeableAnimSpeed.cs @@ -0,0 +1,49 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class Line_fadeableAnimSpeed : ParentOf_Lines_fadeableAnimSpeed_3D + { + public Vector3 start = Vector3.zero; + public Vector3 end = Vector3.one; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public Line_fadeableAnimSpeed(Vector3 start, Vector3 end) + { + this.start = start; + this.end = end; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(start, end, color, width, text, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + lineAnimationProgress = InternalDrawColorFade(start, end, color, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + + public static LineAnimationProgress InternalDraw(Vector3 start, Vector3 end, Color color, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + return UtilitiesDXXL_DrawBasics.Line(start, end, color, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, null, false, endPlates_size); + } + + public static LineAnimationProgress InternalDrawColorFade(Vector3 start, Vector3 end, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + return UtilitiesDXXL_DrawBasics.LineColorFade(start, end, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, null, false, endPlates_size, 1.0f); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Line_fadeableAnimSpeed.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Line_fadeableAnimSpeed.cs.meta new file mode 100644 index 0000000..a13d64b --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Line_fadeableAnimSpeed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db944b0253fc33141b208bff0876b429 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsLine_fadeableAnimSpeed.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsLine_fadeableAnimSpeed.cs new file mode 100644 index 0000000..53b5cb5 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsLine_fadeableAnimSpeed.cs @@ -0,0 +1,35 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class MovingArrowsLine_fadeableAnimSpeed : ParentOf_Lines_fadeableAnimSpeed_3D + { + public Vector3 start = Vector3.zero; + public Vector3 end = Vector3.one; + public float distanceBetweenArrows = 0.5f; + public float lengthOfArrows = 0.15f; + public bool backwardAnimationFlipsArrowDirection = true; + + public MovingArrowsLine_fadeableAnimSpeed(Vector3 start, Vector3 end) + { + this.start = start; + this.end = end; + width = 0.05f; + animationSpeed = 0.5f; + flattenThickRoundLineIntoAmplitudePlane = true; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + lineAnimationProgress = InternalDraw(start, end, color, width, distanceBetweenArrows, lengthOfArrows, text, animationSpeed, lineAnimationProgress, backwardAnimationFlipsArrowDirection, flattenThickRoundLineIntoAmplitudePlane, customAmplitudeAndTextDir, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + public static LineAnimationProgress InternalDraw(Vector3 start, Vector3 end, Color color, float lineWidth, float distanceBetweenArrows, float lengthOfArrows, string text, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, bool backwardAnimationFlipsArrowDirection, bool flattenThickRoundLineIntoAmplitudePlane, Vector3 customAmplitudeAndTextDir, float endPlates_size, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + return UtilitiesDXXL_DrawBasics.MovingArrowsLine(start, end, color, lineWidth, distanceBetweenArrows, lengthOfArrows, text, animationSpeed, precedingLineAnimationProgress, backwardAnimationFlipsArrowDirection, flattenThickRoundLineIntoAmplitudePlane, customAmplitudeAndTextDir, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, false); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsLine_fadeableAnimSpeed.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsLine_fadeableAnimSpeed.cs.meta new file mode 100644 index 0000000..b2c95fc --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsLine_fadeableAnimSpeed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dba55a0ef6c4de94691d8f6a10ffcf3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsRay_fadeableAnimSpeed.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsRay_fadeableAnimSpeed.cs new file mode 100644 index 0000000..c2229de --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsRay_fadeableAnimSpeed.cs @@ -0,0 +1,39 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class MovingArrowsRay_fadeableAnimSpeed : ParentOf_Lines_fadeableAnimSpeed_3D + { + public Vector3 start = Vector3.zero; + public Vector3 direction = Vector3.one; + public float distanceBetweenArrows = 0.5f; + public float lengthOfArrows = 0.15f; + public bool backwardAnimationFlipsArrowDirection = true; + + public MovingArrowsRay_fadeableAnimSpeed(Vector3 start, Vector3 direction) + { + this.start = start; + this.direction = direction; + width = 0.05f; + animationSpeed = 0.5f; + flattenThickRoundLineIntoAmplitudePlane = true; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + lineAnimationProgress = InternalDraw(start, direction, color, width, distanceBetweenArrows, lengthOfArrows, text, animationSpeed, lineAnimationProgress, backwardAnimationFlipsArrowDirection, flattenThickRoundLineIntoAmplitudePlane, customAmplitudeAndTextDir, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + + public static LineAnimationProgress InternalDraw(Vector3 start, Vector3 direction, Color color, float lineWidth, float distanceBetweenArrows, float lengthOfArrows, string text, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, bool backwardAnimationFlipsArrowDirection, bool flattenThickRoundLineIntoAmplitudePlane, Vector3 customAmplitudeAndTextDir, float endPlates_size, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + + Vector3 end = start + direction; + return MovingArrowsLine_fadeableAnimSpeed.InternalDraw(start, end, color, lineWidth, distanceBetweenArrows, lengthOfArrows, text, animationSpeed, precedingLineAnimationProgress, backwardAnimationFlipsArrowDirection, flattenThickRoundLineIntoAmplitudePlane, customAmplitudeAndTextDir, endPlates_size, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsRay_fadeableAnimSpeed.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsRay_fadeableAnimSpeed.cs.meta new file mode 100644 index 0000000..e3789b8 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/MovingArrowsRay_fadeableAnimSpeed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33e033046cc797f4b991d256e32e2f01 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/RayWithAlternatingColors_fadeableAnimSpeed.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/RayWithAlternatingColors_fadeableAnimSpeed.cs new file mode 100644 index 0000000..a741c86 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/RayWithAlternatingColors_fadeableAnimSpeed.cs @@ -0,0 +1,38 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class RayWithAlternatingColors_fadeableAnimSpeed : ParentOf_Lines_fadeableAnimSpeed_3D + { + public Vector3 start = Vector3.zero; + public Vector3 direction = Vector3.one; + public Color alternatingColor = DrawBasics.defaultColor2_ofAlternatingColorLines; + public float lengthOfStripes = 0.04f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public RayWithAlternatingColors_fadeableAnimSpeed(Vector3 start, Vector3 direction) + { + this.start = start; + this.direction = direction; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + lineAnimationProgress = InternalDraw(start, direction, color, alternatingColor, width, lengthOfStripes, text, animationSpeed, lineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + public static LineAnimationProgress InternalDraw(Vector3 start, Vector3 direction, Color color1, Color color2, float width, float lengthOfStripes, string text, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + + Vector3 end = start + direction; + return LineWithAlternatingColors_fadeableAnimSpeed.InternalDraw(start, end, color1, color2, width, lengthOfStripes, text, animationSpeed, precedingLineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/RayWithAlternatingColors_fadeableAnimSpeed.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/RayWithAlternatingColors_fadeableAnimSpeed.cs.meta new file mode 100644 index 0000000..0356543 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/RayWithAlternatingColors_fadeableAnimSpeed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a46b33f652462f047a58dedefb02fefd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Ray_fadeableAnimSpeed.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Ray_fadeableAnimSpeed.cs new file mode 100644 index 0000000..a0dddbb --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Ray_fadeableAnimSpeed.cs @@ -0,0 +1,53 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class Ray_fadeableAnimSpeed : ParentOf_Lines_fadeableAnimSpeed_3D + { + public Vector3 start = Vector3.zero; + public Vector3 direction = Vector3.one; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public float alphaFadeOutLength_0to1 = 0.0f; + public bool skipPatternEnlargementForLongLines = false; + public bool skipPatternEnlargementForShortLines = false; + + public Ray_fadeableAnimSpeed(Vector3 start, Vector3 direction) + { + this.start = start; + this.direction = direction; + } + + public void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(start, direction, color, width, text, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + else + { + lineAnimationProgress = InternalDrawColorFade(start, direction, color, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + } + + public static LineAnimationProgress InternalDraw(Vector3 start, Vector3 direction, Color color, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + + return Line_fadeableAnimSpeed.InternalDraw(start, start + direction, color, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, endPlates_size, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines); + } + + public static LineAnimationProgress InternalDrawColorFade(Vector3 start, Vector3 direction, Color startColor, Color endColor, float width, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, Vector3 customAmplitudeAndTextDir, bool flattenThickRoundLineIntoAmplitudePlane, float endPlates_size, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinTextSize, float durationInSec, bool hiddenByNearerObjects, bool skipPatternEnlargementForLongLines, bool skipPatternEnlargementForShortLines) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + return UtilitiesDXXL_DrawBasics.LineColorFade(start, start + direction, startColor, endColor, width, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, customAmplitudeAndTextDir, flattenThickRoundLineIntoAmplitudePlane, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinTextSize, durationInSec, hiddenByNearerObjects, skipPatternEnlargementForLongLines, skipPatternEnlargementForShortLines, null, false, endPlates_size, 1.0f); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Ray_fadeableAnimSpeed.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Ray_fadeableAnimSpeed.cs.meta new file mode 100644 index 0000000..8041ea6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/3D/Ray_fadeableAnimSpeed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75110228cd54ab0468af7f5bbd019510 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/LineAnimationProgress.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/LineAnimationProgress.cs new file mode 100644 index 0000000..67d3937 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/LineAnimationProgress.cs @@ -0,0 +1,9 @@ +namespace DrawXXL +{ + public class LineAnimationProgress + { + //is "class" instead of "struct" because it should be nullable. + public float animProgress; + public float timeOfDraw; + } +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/LineAnimationProgress.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/LineAnimationProgress.cs.meta new file mode 100644 index 0000000..1164321 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/LineAnimationProgress.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b6395f649e315c48befc5c92fc421fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace.meta new file mode 100644 index 0000000..9d78d44 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2f06d5d12ab8b4542886503ff2bb5b52 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineFrom_fadeableAnimSpeed_screenspace.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineFrom_fadeableAnimSpeed_screenspace.cs new file mode 100644 index 0000000..a450d12 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineFrom_fadeableAnimSpeed_screenspace.cs @@ -0,0 +1,55 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class LineFrom_fadeableAnimSpeed_screenspace : ParentOf_Lines_fadeableAnimSpeed_screenspace + { + public Vector2 start = Vector2.zero; + public Vector2 direction = Vector2.one; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public bool interpretDirectionAsUnwarped = false; + public float alphaFadeOutLength_0to1 = 0.0f; + public float enlargeSmallTextToThisMinRelTextSize = DrawScreenspace.minTextSize_relToViewportHeight; + + public LineFrom_fadeableAnimSpeed_screenspace(Vector2 start, Vector2 direction) + { + this.start = start; + this.direction = direction; + } + + public override void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (TryFetchCamera("LineFrom_fadeableAnimSpeed_screenspace.Draw") == false) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace.Add(this); + return; + } + + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(targetCamera, start, direction, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + else + { + lineAnimationProgress = InternalDraw_withColorFade(targetCamera, start, direction, color, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + } + + public static LineAnimationProgress InternalDraw(Camera targetCamera, Vector2 start, Vector2 direction, Color color, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + return Ray_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, direction, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static LineAnimationProgress InternalDraw_withColorFade(Camera targetCamera, Vector2 start, Vector2 direction, Color startColor, Color endColor, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + return Ray_fadeableAnimSpeed_screenspace.InternalDrawColorFade(targetCamera, start, direction, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineFrom_fadeableAnimSpeed_screenspace.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineFrom_fadeableAnimSpeed_screenspace.cs.meta new file mode 100644 index 0000000..bfff3b0 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineFrom_fadeableAnimSpeed_screenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b46f03e70807374dba929743dfa98b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineTo_fadeableAnimSpeed_screenspace.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineTo_fadeableAnimSpeed_screenspace.cs new file mode 100644 index 0000000..91e5e77 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineTo_fadeableAnimSpeed_screenspace.cs @@ -0,0 +1,61 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class LineTo_fadeableAnimSpeed_screenspace : ParentOf_Lines_fadeableAnimSpeed_screenspace + { + public Vector2 direction = Vector2.one; + public Vector2 end = Vector2.one; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public bool interpretDirectionAsUnwarped = false; + public float alphaFadeOutLength_0to1 = 0.0f; + public float enlargeSmallTextToThisMinRelTextSize = DrawScreenspace.minTextSize_relToViewportHeight; + + public LineTo_fadeableAnimSpeed_screenspace(Vector2 direction, Vector2 end) + { + this.direction = direction; + this.end = end; + } + + public override void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (TryFetchCamera("LineTo_fadeableAnimSpeed_screenspace.Draw") == false) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace.Add(this); + return; + } + + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(targetCamera, direction, end, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + else + { + lineAnimationProgress = InternalDraw_withColorFade(targetCamera, direction, end, color, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + } + + public static LineAnimationProgress InternalDraw(Camera targetCamera, Vector2 direction, Vector2 end, Color color, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + return Ray_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, end - direction, direction, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static LineAnimationProgress InternalDraw_withColorFade(Camera targetCamera, Vector2 direction, Vector2 end, Color startColor, Color endColor, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + return Ray_fadeableAnimSpeed_screenspace.InternalDrawColorFade(targetCamera, end - direction, direction, startColor, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineTo_fadeableAnimSpeed_screenspace.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineTo_fadeableAnimSpeed_screenspace.cs.meta new file mode 100644 index 0000000..2ea63d4 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineTo_fadeableAnimSpeed_screenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 958c9ceb6f9f09d4ba0987f6e0b03f4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineWithAlternatingColors_fadeableAnimSpeed_screenspace.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineWithAlternatingColors_fadeableAnimSpeed_screenspace.cs new file mode 100644 index 0000000..a5c492d --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineWithAlternatingColors_fadeableAnimSpeed_screenspace.cs @@ -0,0 +1,81 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class LineWithAlternatingColors_fadeableAnimSpeed_screenspace : ParentOf_Lines_fadeableAnimSpeed_screenspace + { + public Vector2 start = Vector2.zero; + public Vector2 end = Vector2.one; + public Color alternatingColor = DrawBasics.defaultColor2_ofAlternatingColorLines; + public float lengthOfStripes_relToViewportHeight = 0.03f; + public float alphaFadeOutLength_0to1 = 0.0f; + + public LineWithAlternatingColors_fadeableAnimSpeed_screenspace(Vector2 start, Vector2 end) + { + this.start = start; + this.end = end; + } + + public override void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (TryFetchCamera("LineWithAlternatingColors_fadeableAnimSpeed_screenspace.Draw") == false) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace.Add(this); + return; + } + + lineAnimationProgress = InternalDraw(targetCamera, start, end, color, alternatingColor, width_relToViewportHeight, lengthOfStripes_relToViewportHeight, text, animationSpeed, lineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, durationInSec); + } + + public static LineAnimationProgress InternalDraw(Camera targetCamera, Vector2 start, Vector2 end, Color color1, Color color2, float lineWidth_relToViewportHeight, float lengthOfStripes_relToViewportHeight, string text, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float durationInSec) + { + //Lines drawn with this function have a higher likelyhood of accidentially using up high numbers of drawnLinePerFrame, because "lengthOfStripes" can be set manually instead of beeing determined by the lineStyle-code + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return null; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return null; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth_relToViewportHeight, "lineWidth_relToViewportHeight")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lengthOfStripes_relToViewportHeight, "lengthOfStripes_relToViewportHeight")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(animationSpeed, "animationSpeed")) { return null; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + + Vector3 start_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, start, false); + Vector3 end_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, end, false); + Vector2 lineCenter = 0.5f * (start + end); + UtilitiesDXXL_Screenspace.camPlane.Recreate(start_worldSpace, targetCamera.transform.forward); + + lineWidth_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth_relToViewportHeight); + float lineWidth_worldSpace = UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_relToViewportHeight) ? 0.0f : UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, lineWidth_relToViewportHeight); + float animationDirection = Mathf.Sign(animationSpeed); + animationSpeed = UtilitiesDXXL_Screenspace.animationSpeedConversionFactor_viewportToWorldSpace * animationSpeed; + float animationSpeed_worldSpace = UtilitiesDXXL_Math.ApproximatelyZero(animationSpeed) ? 0.0f : UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, animationSpeed); + animationSpeed_worldSpace = animationSpeed_worldSpace * animationDirection; + float minTextSize_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, DrawScreenspace.minTextSize_relToViewportHeight); + lengthOfStripes_relToViewportHeight = Mathf.Max(lengthOfStripes_relToViewportHeight, UtilitiesDXXL_DrawBasics.min_lengthOfStripes_ofAlternatingColorLine); + float lengthOfStripes_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, lengthOfStripes_relToViewportHeight); + UtilitiesDXXL_LineStyles.curr_dashLength_forAlternatingColorStripesLine = lengthOfStripes_worldSpace; + Color prev_defaultAlternateColorOfStripedLines = DrawBasics.defaultColor2_ofAlternatingColorLines; + if (UtilitiesDXXL_Colors.IsDefaultColor(color2) == false) + { + DrawBasics.defaultColor2_ofAlternatingColorLines = color2; + } + float endPlatesSize_inAbsoluteWorldSpaceUnits = UtilitiesDXXL_Math.ApproximatelyZero(endPlatesSize_relToViewportHeight) ? 0.0f : UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, endPlatesSize_relToViewportHeight); + + UtilitiesDXXL_DrawBasics.Set_endPlates_sizeInterpretation_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + LineAnimationProgress lineAnimProgressAfterDrawing = UtilitiesDXXL_DrawBasics.Line(start_worldSpace, end_worldSpace, color1, lineWidth_worldSpace, text, DrawBasics.LineStyle.alternatingColorStripes, 1.0f, animationSpeed_worldSpace, precedingLineAnimationProgress, UtilitiesDXXL_Screenspace.camPlane, true, alphaFadeOutLength_0to1, minTextSize_worldSpace, durationInSec, false, false, false, targetCamera, false, endPlatesSize_inAbsoluteWorldSpaceUnits); + UtilitiesDXXL_DrawBasics.Reverse_endPlates_sizeInterpretation(); + + UtilitiesDXXL_LineStyles.curr_dashLength_forAlternatingColorStripesLine = UtilitiesDXXL_LineStyles.default_dashLength_forAlternatingColorStripesLine; + DrawBasics.defaultColor2_ofAlternatingColorLines = prev_defaultAlternateColorOfStripedLines; + + return lineAnimProgressAfterDrawing; + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineWithAlternatingColors_fadeableAnimSpeed_screenspace.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineWithAlternatingColors_fadeableAnimSpeed_screenspace.cs.meta new file mode 100644 index 0000000..a9c41e7 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/LineWithAlternatingColors_fadeableAnimSpeed_screenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a001dca73c1baac489f438f94e052e8d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Line_fadeableAnimSpeed_screenspace.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Line_fadeableAnimSpeed_screenspace.cs new file mode 100644 index 0000000..3db0e45 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Line_fadeableAnimSpeed_screenspace.cs @@ -0,0 +1,84 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class Line_fadeableAnimSpeed_screenspace : ParentOf_Lines_fadeableAnimSpeed_screenspace + { + public Vector2 start = Vector2.zero; + public Vector2 end = Vector2.one; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public float alphaFadeOutLength_0to1 = 0.0f; + public float enlargeSmallTextToThisMinRelTextSize = DrawScreenspace.minTextSize_relToViewportHeight; + + public Line_fadeableAnimSpeed_screenspace(Vector2 start, Vector2 end) + { + this.start = start; + this.end = end; + } + + public override void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (TryFetchCamera("Line_fadeableAnimSpeed_screenspace.Draw") == false) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace.Add(this); + return; + } + + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(targetCamera, start, end, color, width_relToViewportHeight, text, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + else + { + lineAnimationProgress = InternalDrawColorFade(targetCamera, start, end, color, endColor, width_relToViewportHeight, text, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + } + + public static LineAnimationProgress InternalDraw(Camera targetCamera, Vector2 start, Vector2 end, Color color, float width_relToViewportHeight, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return null; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return null; } + + InternalDXXL_LineParamsFromCamViewportSpace lineParams = UtilitiesDXXL_Screenspace.GetLineParamsFromCamViewportSpace(targetCamera, start, end, width_relToViewportHeight, style, stylePatternScaleFactor, enlargeSmallTextToThisMinRelTextSize, animationSpeed, endPlatesSize_relToViewportHeight); + if (lineParams == null) + { + return null; + } + else + { + UtilitiesDXXL_DrawBasics.Set_endPlates_sizeInterpretation_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + LineAnimationProgress returned_lineAnimationProgress = UtilitiesDXXL_DrawBasics.Line(lineParams.startAnchor_worldSpace, lineParams.endAnchor_worldSpace, color, lineParams.width_worldSpace, text, lineParams.lineStyleForcedTo2D, lineParams.patternScaleFactor_worldSpace, lineParams.animationSpeed_worldSpace, precedingLineAnimationProgress, lineParams.camPlane, true, alphaFadeOutLength_0to1, lineParams.enlargeSmallTextToThisMinTextSize_worldSpace, durationInSec, false, false, false, targetCamera, false, lineParams.endPlatesSize_inAbsoluteWorldSpaceUnits); + UtilitiesDXXL_DrawBasics.Reverse_endPlates_sizeInterpretation(); + return returned_lineAnimationProgress; + } + } + + public static LineAnimationProgress InternalDrawColorFade(Camera targetCamera, Vector2 start, Vector2 end, Color startColor, Color endColor, float width_relToViewportHeight, string text, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return null; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return null; } + InternalDXXL_LineParamsFromCamViewportSpace lineParams = UtilitiesDXXL_Screenspace.GetLineParamsFromCamViewportSpace(targetCamera, start, end, width_relToViewportHeight, style, stylePatternScaleFactor, enlargeSmallTextToThisMinRelTextSize, animationSpeed, endPlatesSize_relToViewportHeight); + if (lineParams == null) + { + return null; + } + else + { + UtilitiesDXXL_DrawBasics.Set_endPlates_sizeInterpretation_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + LineAnimationProgress returned_lineAnimationProgress = UtilitiesDXXL_DrawBasics.LineColorFade(lineParams.startAnchor_worldSpace, lineParams.endAnchor_worldSpace, startColor, endColor, lineParams.width_worldSpace, text, lineParams.lineStyleForcedTo2D, lineParams.patternScaleFactor_worldSpace, lineParams.animationSpeed_worldSpace, precedingLineAnimationProgress, lineParams.camPlane, true, alphaFadeOutLength_0to1, lineParams.enlargeSmallTextToThisMinTextSize_worldSpace, durationInSec, false, false, false, targetCamera, false, lineParams.endPlatesSize_inAbsoluteWorldSpaceUnits, 1.0f); + UtilitiesDXXL_DrawBasics.Reverse_endPlates_sizeInterpretation(); + + return returned_lineAnimationProgress; + } + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Line_fadeableAnimSpeed_screenspace.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Line_fadeableAnimSpeed_screenspace.cs.meta new file mode 100644 index 0000000..299c8dd --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Line_fadeableAnimSpeed_screenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d28f5ea6fc8f1b24485cb5b66fee04da +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsLine_fadeableAnimSpeed_screenspace.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsLine_fadeableAnimSpeed_screenspace.cs new file mode 100644 index 0000000..ba4ab5f --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsLine_fadeableAnimSpeed_screenspace.cs @@ -0,0 +1,100 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class MovingArrowsLine_fadeableAnimSpeed_screenspace : ParentOf_Lines_fadeableAnimSpeed_screenspace + { + public Vector2 start = Vector2.zero; + public Vector2 end = Vector2.one; + public float distanceBetweenArrows_relToViewportHeight = 0.11f; + public float lengthOfArrows_relToViewportHeight = 0.05f; + public bool backwardAnimationFlipsArrowDirection = true; + + public MovingArrowsLine_fadeableAnimSpeed_screenspace(Vector2 start, Vector2 end) + { + this.start = start; + this.end = end; + width_relToViewportHeight = 0.016f; + animationSpeed = 0.5f; + } + + public override void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (TryFetchCamera("MovingArrowsLine_fadeableAnimSpeed_screenspace.Draw") == false) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace.Add(this); + return; + } + + lineAnimationProgress = InternalDraw(targetCamera, start, end, color, width_relToViewportHeight, distanceBetweenArrows_relToViewportHeight, lengthOfArrows_relToViewportHeight, text, animationSpeed, lineAnimationProgress, backwardAnimationFlipsArrowDirection, endPlatesSize_relToViewportHeight, durationInSec); + } + + public static LineAnimationProgress InternalDraw(Camera targetCamera, Vector2 start, Vector2 end, Color color, float lineWidth_relToViewportHeight, float distanceBetweenArrows_relToViewportHeight, float lengthOfArrows_relToViewportHeight, string text, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, bool backwardAnimationFlipsArrowDirection, float endPlatesSize_relToViewportHeight, float durationInSec) + { + //"lengthOfArrows_relToViewportHeight" and "distanceBetweenArrows_relToViewportHeight": Very small (or very big) values may get rounded up (down) internally to prevent an explosive raise of drawn lines, see also "DrawBasics.MaxAllowedDrawnLinesPerFrame" (link). + + //Lines drawn with this function have a higher likelyhood of accidentially using up high numbers of drawnLinePerFrame, because "distanceBetweenArrows_relToViewportHeight" and "lengthOfArrows_relToViewportHeight" can be set manually instead of beeing determined by the lineStyle-code + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return null; } + if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return null; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth_relToViewportHeight, "lineWidth_relToViewportHeight")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(distanceBetweenArrows_relToViewportHeight, "distanceBetweenArrows_relToViewportHeight")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lengthOfArrows_relToViewportHeight, "lengthOfArrows_relToViewportHeight")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(animationSpeed, "animationSpeed")) { return null; } + + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(end, "end")) { return null; } + + Vector3 start_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, start, false); + Vector3 end_worldSpace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, end, false); + Vector2 lineCenter = 0.5f * (start + end); + UtilitiesDXXL_Screenspace.camPlane.Recreate(start_worldSpace, targetCamera.transform.forward); + + lineWidth_relToViewportHeight = UtilitiesDXXL_Math.AbsNonZeroValue(lineWidth_relToViewportHeight); + float lineWidth_worldSpace = UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_relToViewportHeight) ? 0.0f : UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, lineWidth_relToViewportHeight); + //small or big values of "distanceBetweenArrows" and "lengthOfArrows" may additionally get changed in "UtilitiesDXXL_LineStyles" inside the "skipPatternEnlargementFor*Lines == false" mechanic. + distanceBetweenArrows_relToViewportHeight = Mathf.Max(distanceBetweenArrows_relToViewportHeight, 0.0002f); + lengthOfArrows_relToViewportHeight = Mathf.Min(lengthOfArrows_relToViewportHeight, 0.9f * distanceBetweenArrows_relToViewportHeight); + lengthOfArrows_relToViewportHeight = Mathf.Max(lengthOfArrows_relToViewportHeight, 0.0001f); + float distanceBetweenArrows_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, distanceBetweenArrows_relToViewportHeight); + float lengthOfArrows_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, lengthOfArrows_relToViewportHeight); + float animationDirection = Mathf.Sign(animationSpeed); + animationSpeed = UtilitiesDXXL_Screenspace.animationSpeedConversionFactor_viewportToWorldSpace * animationSpeed; + float animationSpeed_worldSpace = UtilitiesDXXL_Math.ApproximatelyZero(animationSpeed) ? 0.0f : UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, animationSpeed); + animationSpeed_worldSpace = animationSpeed_worldSpace * animationDirection; + float minTextSize_worldSpace = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, DrawScreenspace.minTextSize_relToViewportHeight); + float lengthOfEmptySpaces_worldSpace = distanceBetweenArrows_worldSpace - lengthOfArrows_worldSpace; + float endPlatesSize_inAbsoluteWorldSpaceUnits = UtilitiesDXXL_Math.ApproximatelyZero(endPlatesSize_relToViewportHeight) ? 0.0f : UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, lineCenter, true, endPlatesSize_relToViewportHeight); + LineAnimationProgress lineAnimProgressAfterDrawing = null; + + UtilitiesDXXL_LineStyles.curr_pointersDirAlongAnimationDir = backwardAnimationFlipsArrowDirection; + UtilitiesDXXL_DrawBasics.Set_endPlates_sizeInterpretation_reversible(DrawBasics.LengthInterpretation.absoluteUnits); + try + { + UtilitiesDXXL_LineStyles.curr_dashLength_forArrowLine = lengthOfArrows_worldSpace; + if (UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_worldSpace) == false) + { + UtilitiesDXXL_LineStyles.curr_minRatio_for_dashLengthToLineWidth_forArrowLine = lengthOfArrows_worldSpace / lineWidth_worldSpace; + } + UtilitiesDXXL_LineStyles.curr_spaceToDash_ratio_forArrowLine = lengthOfEmptySpaces_worldSpace / lengthOfArrows_worldSpace; + UtilitiesDXXL_LineStyles.curr_minEmptySpacesLength_forArrowLine = lengthOfEmptySpaces_worldSpace; + lineAnimProgressAfterDrawing = UtilitiesDXXL_DrawBasics.Line(start_worldSpace, end_worldSpace, color, lineWidth_worldSpace, text, DrawBasics.LineStyle.arrows, 1.0f, animationSpeed_worldSpace, precedingLineAnimationProgress, UtilitiesDXXL_Screenspace.camPlane, true, 0.0f, minTextSize_worldSpace, durationInSec, false, false, false, targetCamera, false, endPlatesSize_inAbsoluteWorldSpaceUnits); + } + catch { } + + UtilitiesDXXL_DrawBasics.Reverse_endPlates_sizeInterpretation(); + UtilitiesDXXL_LineStyles.curr_pointersDirAlongAnimationDir = UtilitiesDXXL_LineStyles.default_pointersDirAlongAnimationDir; + UtilitiesDXXL_LineStyles.curr_dashLength_forArrowLine = UtilitiesDXXL_LineStyles.default_dashLength_forArrowLine; + UtilitiesDXXL_LineStyles.curr_minRatio_for_dashLengthToLineWidth_forArrowLine = UtilitiesDXXL_LineStyles.default_minRatio_for_dashLengthToLineWidth_forArrowLine; + UtilitiesDXXL_LineStyles.curr_spaceToDash_ratio_forArrowLine = UtilitiesDXXL_LineStyles.default_spaceToDash_ratio_forArrowLine; + UtilitiesDXXL_LineStyles.curr_minEmptySpacesLength_forArrowLine = UtilitiesDXXL_LineStyles.default_minEmptySpacesLength_forArrowLine; + + return lineAnimProgressAfterDrawing; + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsLine_fadeableAnimSpeed_screenspace.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsLine_fadeableAnimSpeed_screenspace.cs.meta new file mode 100644 index 0000000..496b668 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsLine_fadeableAnimSpeed_screenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1378d0e5f4f25aa43977ca4b06c8c47d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsRay_fadeableAnimSpeed_screenspace.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsRay_fadeableAnimSpeed_screenspace.cs new file mode 100644 index 0000000..5c75638 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsRay_fadeableAnimSpeed_screenspace.cs @@ -0,0 +1,49 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class MovingArrowsRay_fadeableAnimSpeed_screenspace : ParentOf_Lines_fadeableAnimSpeed_screenspace + { + public Vector2 start = Vector2.zero; + public Vector2 direction = Vector2.one; + public bool interpretDirectionAsUnwarped = false; + public bool backwardAnimationFlipsArrowDirection = true; + public float distanceBetweenArrows_relToViewportHeight = 0.11f; + public float lengthOfArrows_relToViewportHeight = 0.05f; + + public MovingArrowsRay_fadeableAnimSpeed_screenspace(Vector2 start, Vector2 direction) + { + this.start = start; + this.direction = direction; + width_relToViewportHeight = 0.016f; + animationSpeed = 0.5f; + } + + public override void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (TryFetchCamera("MovingArrowsRay_fadeableAnimSpeed_screenspace.Draw") == false) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace.Add(this); + return; + } + + lineAnimationProgress = InternalDraw(targetCamera, start, direction, color, width_relToViewportHeight, distanceBetweenArrows_relToViewportHeight, lengthOfArrows_relToViewportHeight, text, animationSpeed, lineAnimationProgress, backwardAnimationFlipsArrowDirection, interpretDirectionAsUnwarped, endPlatesSize_relToViewportHeight, durationInSec); + } + + public static LineAnimationProgress InternalDraw(Camera targetCamera, Vector2 start, Vector2 direction, Color color, float lineWidth_relToViewportHeight, float distanceBetweenArrows_relToViewportHeight, float lengthOfArrows_relToViewportHeight, string text, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, bool backwardAnimationFlipsArrowDirection, bool interpretDirectionAsUnwarped, float endPlatesSize_relToViewportHeight, float durationInSec) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + + Vector2 direction_inNonSquareViewportSpace = interpretDirectionAsUnwarped ? DrawScreenspace.DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(direction, targetCamera) : direction; + Vector2 end = start + direction_inNonSquareViewportSpace; + return MovingArrowsLine_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, end, color, lineWidth_relToViewportHeight, distanceBetweenArrows_relToViewportHeight, lengthOfArrows_relToViewportHeight, text, animationSpeed, precedingLineAnimationProgress, backwardAnimationFlipsArrowDirection, endPlatesSize_relToViewportHeight, durationInSec); + } + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsRay_fadeableAnimSpeed_screenspace.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsRay_fadeableAnimSpeed_screenspace.cs.meta new file mode 100644 index 0000000..d5d4207 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/MovingArrowsRay_fadeableAnimSpeed_screenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87f5af2fd65f47e479a0e60eb63b07a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/RayWithAlternatingColors_fadeableAnimSpeed_screenspace.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/RayWithAlternatingColors_fadeableAnimSpeed_screenspace.cs new file mode 100644 index 0000000..1253fe3 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/RayWithAlternatingColors_fadeableAnimSpeed_screenspace.cs @@ -0,0 +1,46 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class RayWithAlternatingColors_fadeableAnimSpeed_screenspace : ParentOf_Lines_fadeableAnimSpeed_screenspace + { + public Vector2 start = Vector2.zero; + public Vector2 direction = Vector2.one; + public Color alternatingColor = DrawBasics.defaultColor2_ofAlternatingColorLines; + public float lengthOfStripes_relToViewportHeight = 0.03f; + public bool interpretDirectionAsUnwarped = false; + public float alphaFadeOutLength_0to1 = 0.0f; + + public RayWithAlternatingColors_fadeableAnimSpeed_screenspace(Vector2 start, Vector2 direction) + { + this.start = start; + this.direction = direction; + } + + public override void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (TryFetchCamera("RayWithAlternatingColors_fadeableAnimSpeed_screenspace.Draw") == false) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace.Add(this); + return; + } + + lineAnimationProgress = InternalDraw(targetCamera, start, direction, color, alternatingColor, width_relToViewportHeight, lengthOfStripes_relToViewportHeight, text, interpretDirectionAsUnwarped, animationSpeed, lineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, durationInSec); + } + + public static LineAnimationProgress InternalDraw(Camera targetCamera, Vector2 start, Vector2 direction, Color color1, Color color2, float lineWidth_relToViewportHeight, float lengthOfStripes_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float durationInSec) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + + Vector2 direction_inNonSquareViewportSpace = interpretDirectionAsUnwarped ? DrawScreenspace.DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(direction, targetCamera) : direction; + Vector2 end = start + direction_inNonSquareViewportSpace; + return LineWithAlternatingColors_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, end, color1, color2, lineWidth_relToViewportHeight, lengthOfStripes_relToViewportHeight, text, animationSpeed, precedingLineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, durationInSec); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/RayWithAlternatingColors_fadeableAnimSpeed_screenspace.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/RayWithAlternatingColors_fadeableAnimSpeed_screenspace.cs.meta new file mode 100644 index 0000000..fbe7f3f --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/RayWithAlternatingColors_fadeableAnimSpeed_screenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c8699cd8b2a1a6428b13f97fc20917e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Ray_fadeableAnimSpeed_screenspace.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Ray_fadeableAnimSpeed_screenspace.cs new file mode 100644 index 0000000..2e5909b --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Ray_fadeableAnimSpeed_screenspace.cs @@ -0,0 +1,64 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class Ray_fadeableAnimSpeed_screenspace : ParentOf_Lines_fadeableAnimSpeed_screenspace + { + public Vector2 start = Vector2.zero; + public Vector2 direction = Vector2.one; + public Color endColor = default(Color); //Can be ignored if the line should have only one color. If it is specified then the line will have a fading color transition, starting with "color"(link) at the start of the line and ending with "endColor" at the end of the line + public DrawBasics.LineStyle style = DrawBasics.LineStyle.solid; + public float stylePatternScaleFactor = 1.0f; + public bool interpretDirectionAsUnwarped = false; + public float alphaFadeOutLength_0to1 = 0.0f; + public float enlargeSmallTextToThisMinRelTextSize = DrawScreenspace.minTextSize_relToViewportHeight; + + public Ray_fadeableAnimSpeed_screenspace(Vector2 start, Vector2 direction) + { + this.start = start; + this.direction = direction; + } + + public override void Draw() + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } + if (TryFetchCamera("Ray_fadeableAnimSpeed_screenspace.Draw") == false) { return; } + + if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem) + { + DrawXXL_LinesManager.instance.listOfSheduled_ParentOf_Lines_fadeableAnimSpeed_screenspace.Add(this); + return; + } + + if (UtilitiesDXXL_Colors.IsDefaultColor(endColor)) + { + lineAnimationProgress = InternalDraw(targetCamera, start, direction, color, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + else + { + lineAnimationProgress = InternalDrawColorFade(targetCamera, start, direction, color, endColor, width_relToViewportHeight, text, interpretDirectionAsUnwarped, style, stylePatternScaleFactor, animationSpeed, lineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + } + + public static LineAnimationProgress InternalDraw(Camera targetCamera, Vector2 start, Vector2 direction, Color color, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + + Vector2 direction_inNonSquareViewportSpace = interpretDirectionAsUnwarped ? DrawScreenspace.DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(direction, targetCamera) : direction; + return Line_fadeableAnimSpeed_screenspace.InternalDraw(targetCamera, start, start + direction_inNonSquareViewportSpace, color, width_relToViewportHeight, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + + public static LineAnimationProgress InternalDrawColorFade(Camera targetCamera, Vector2 start, Vector2 direction, Color startColor, Color endColor, float width_relToViewportHeight, string text, bool interpretDirectionAsUnwarped, DrawBasics.LineStyle style, float stylePatternScaleFactor, float animationSpeed, LineAnimationProgress precedingLineAnimationProgress, float endPlatesSize_relToViewportHeight, float alphaFadeOutLength_0to1, float enlargeSmallTextToThisMinRelTextSize, float durationInSec) + { + if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(start, "start")) { return null; } + if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(direction, "direction")) { return null; } + + Vector2 direction_inNonSquareViewportSpace = interpretDirectionAsUnwarped ? DrawScreenspace.DirectionInUnitsOfUnwarpedSpace_to_sameLookingDirectionInUnitsOfWarpedSpace(direction, targetCamera) : direction; + return Line_fadeableAnimSpeed_screenspace.InternalDrawColorFade(targetCamera, start, start + direction_inNonSquareViewportSpace, startColor, endColor, width_relToViewportHeight, text, style, stylePatternScaleFactor, animationSpeed, precedingLineAnimationProgress, endPlatesSize_relToViewportHeight, alphaFadeOutLength_0to1, enlargeSmallTextToThisMinRelTextSize, durationInSec); + } + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Ray_fadeableAnimSpeed_screenspace.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Ray_fadeableAnimSpeed_screenspace.cs.meta new file mode 100644 index 0000000..400a67c --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/Screenspace/Ray_fadeableAnimSpeed_screenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 067eade0a87557b48a82173e65ff05c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents.meta new file mode 100644 index 0000000..2cccef9 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 103f2c9a32b99bd4fb77c240510b153b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed.cs new file mode 100644 index 0000000..8e02692 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed.cs @@ -0,0 +1,14 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class ParentOf_Lines_fadeableAnimSpeed + { + public Color color = DrawBasics.defaultColor; + public string text = null; + public LineAnimationProgress lineAnimationProgress = new LineAnimationProgress(); + public float durationInSec = 0.0f; + public float animationSpeed = 0.0f; + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed.cs.meta new file mode 100644 index 0000000..8b20c07 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7698c920cfaedea4dabe5a8e19a7d32a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_2D.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_2D.cs new file mode 100644 index 0000000..bfa242f --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_2D.cs @@ -0,0 +1,8 @@ +namespace DrawXXL +{ + public class ParentOf_Lines_fadeableAnimSpeed_2D : ParentOf_Lines_fadeableAnimSpeed_worldspace + { + public float custom_zPos = float.PositiveInfinity; + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_2D.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_2D.cs.meta new file mode 100644 index 0000000..43f0c04 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e89730461f8918c49adca0db96bb5733 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_3D.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_3D.cs new file mode 100644 index 0000000..b5f89e8 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_3D.cs @@ -0,0 +1,11 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class ParentOf_Lines_fadeableAnimSpeed_3D : ParentOf_Lines_fadeableAnimSpeed_worldspace + { + public Vector3 customAmplitudeAndTextDir = default(Vector3); + public bool flattenThickRoundLineIntoAmplitudePlane = false; + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_3D.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_3D.cs.meta new file mode 100644 index 0000000..678fcb6 --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_3D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e31eda1d3c50f834ebf26e8fae9b5814 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_screenspace.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_screenspace.cs new file mode 100644 index 0000000..e33f4cb --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_screenspace.cs @@ -0,0 +1,30 @@ +namespace DrawXXL +{ + using UnityEngine; + + public class ParentOf_Lines_fadeableAnimSpeed_screenspace : ParentOf_Lines_fadeableAnimSpeed + { + public Camera targetCamera; //the camera that defines the viewport to which the line is drawn. If it is not specified then a camera is automatically searched based on "DrawScreenspace.defaultScreenspaceWindowForDrawing" + public float width_relToViewportHeight = 0.0f; + public float endPlatesSize_relToViewportHeight = 0.0f; + public bool TryFetchCamera(string nameOfRequestingFunction) + { + //returns "camera is available" + if (targetCamera == null) + { + return UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out targetCamera, nameOfRequestingFunction); + } + else + { + return true; + } + } + + public virtual void Draw() + { + } + + + } + +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_screenspace.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_screenspace.cs.meta new file mode 100644 index 0000000..ce3414d --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_screenspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0239b635f133ad240bb197fd6893bec4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_worldspace.cs b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_worldspace.cs new file mode 100644 index 0000000..08d166c --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_worldspace.cs @@ -0,0 +1,10 @@ +namespace DrawXXL +{ + public class ParentOf_Lines_fadeableAnimSpeed_worldspace : ParentOf_Lines_fadeableAnimSpeed + { + public float width = 0.0f; + public float endPlates_size = 0.0f; + public bool hiddenByNearerObjects = true; + public float enlargeSmallTextToThisMinTextSize = 0.0f; + } +} diff --git a/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_worldspace.cs.meta b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_worldspace.cs.meta new file mode 100644 index 0000000..9051afb --- /dev/null +++ b/Runtime/DrawDebugLibrary/miscellaneous/animated lines as objects/parents/ParentOf_Lines_fadeableAnimSpeed_worldspace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b2e61d099ed65a4aa615b3702d55779 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/MacroLibrary/MacroDXXL.cs b/Runtime/MacroLibrary/MacroDXXL.cs new file mode 100644 index 0000000..ec20371 --- /dev/null +++ b/Runtime/MacroLibrary/MacroDXXL.cs @@ -0,0 +1,431 @@ +using DrawXXL; +using UnityEngine; + +/// +/// MacroDXXL - DXXL (Draw XXL) 高频操作封装库 +/// +/// 功能:将 DXXL 最常用的调试绘制操作封装为一行式工具函数, +/// 省去每次查阅冗长参数列表的麻烦。 +/// +/// 用法: +/// using static MacroDXXL; +/// EnableRuntimeMode(); // 启动时调用一次 +/// Line(a, b, Color.red); +/// Circle(center, 0.5f); +/// Grid(Vector3.zero, 10f); +/// +public static class MacroDXXL +{ + #region 初始化 + + /// 启用运行时 Mesh 渲染模式,使绘制在 Game 视图和 Build 中可见 + public static void EnableRuntimeMode() + { + DrawBasics.usedUnityLineDrawingMethod = DrawBasics.UsedUnityLineDrawingMethod.wireMesh; + } + + #endregion + + #region 基础线段 / 射线 / 向量 + + /// 从 A 点到 B 点绘制线段 + public static void Line(Vector3 a, Vector3 b, Color? color = null, float width = 0f) + { + DrawBasics.Line(a, b, color ?? Color.white, width); + } + + /// 从起点沿方向绘制射线(无限延伸标识) + public static void Ray(Vector3 origin, Vector3 direction, Color? color = null, float width = 0f) + { + DrawBasics.Ray(origin, direction, color ?? Color.white, width); + } + + /// 从 A 点到 B 点绘制带箭头向量 + public static void Vector(Vector3 from, Vector3 to, Color? color = null, float lineWidth = 0f) + { + DrawBasics.Vector(from, to, color ?? Color.white, lineWidth); + } + + /// 从起点沿方向绘制带箭头向量 + public static void VectorFrom(Vector3 start, Vector3 direction, Color? color = null, float lineWidth = 0f) + { + DrawBasics.VectorFrom(start, direction, color ?? Color.white, lineWidth); + } + + /// 从方向指向终点绘制带箭头向量 + public static void VectorTo(Vector3 direction, Vector3 end, Color? color = null, float lineWidth = 0f) + { + DrawBasics.VectorTo(direction, end, color ?? Color.white, lineWidth); + } + + /// 绘制点标记(十字 + 可选坐标文本) + public static void Point(Vector3 position, Color? color = null, float crossSize = 1f, string text = null) + { + DrawBasics.Point(position, text, color ?? Color.white, crossSize); + } + + /// 绘制多点折线 + public static void LineString(Vector3[] points, Color? color = null, bool closeLoop = false) + { + if (points == null || points.Length < 2) return; + DrawBasics.LineString(points, color ?? Color.white, closeLoop); + } + + /// 绘制圆弧(从 start 到 end 绕 circleCenter 的弧) + public static void Arc(Vector3 circleCenter, Vector3 start, Vector3 end, Color? color = null, float width = 0f) + { + DrawBasics.LineCircled(circleCenter, start - circleCenter, end - circleCenter, color ?? Color.white, width: width); + } + + /// 绘制角度弧(给定圆心、半径、起始角度、结束角度) + public static void AngleArc(Vector3 center, float radius, float startAngleDeg, float endAngleDeg, Color? color = null, Quaternion? orientation = null) + { + DrawBasics.LineCircled(center, orientation ?? Quaternion.identity, startAngleDeg, endAngleDeg, radius, color ?? Color.white); + } + + #endregion + + #region 形状 + + /// 绘制圆环 + public static void Circle(Vector3 center, float radius, Color? color = null, Quaternion? rotation = null) + { + DrawShapes.Circle(center, radius, color ?? Color.white, rotation ?? Quaternion.identity); + } + + /// 绘制球体线框 + public static void Sphere(Vector3 center, float radius, Color? color = null) + { + DrawShapes.Sphere(center, radius, color ?? Color.white); + } + + /// 绘制立方体线框 + public static void Cube(Vector3 position, Vector3 scale, Color? color = null, Quaternion? rotation = null) + { + DrawShapes.Cube(position, scale, color ?? Color.white, rotation ?? Quaternion.identity); + } + + /// 绘制带填充面的立方体 + public static void CubeFilled(Vector3 position, Vector3 scale, Color? color = null, Quaternion? rotation = null) + { + DrawShapes.CubeFilled(position, scale, color ?? Color.white, 0.3f, rotation ?? Quaternion.identity); + } + + /// 绘制平面 + public static void Plane(Vector3 mountPoint, Vector3 normal, float width = 10f, float length = 10f, Color? color = null) + { + DrawShapes.Plane(mountPoint, normal, planeAreaExtentionPosition: mountPoint + normal * 0.5f, color: color ?? Color.white, width: width, length: length); + } + + /// 绘制圆柱体线框(两端点定义位置,radius 定义半径) + public static void Cylinder(Vector3 start, Vector3 end, float radius, Color? color = null) + { + Vector3 dir = end - start; + float height = dir.magnitude; + if (height < 0.001f) return; + Vector3 center = (start + end) * 0.5f; + Quaternion rot = Quaternion.FromToRotation(Vector3.up, dir / height); + DrawShapes.Cylinder(center, new Vector3(radius * 2f, height, radius * 2f), rot, color ?? Color.white); + } + + /// 绘制胶囊体线框 + public static void Capsule(Vector3 start, Vector3 end, float radius, Color? color = null) + { + DrawShapes.Capsule(start, end, radius, color ?? Color.white); + } + + /// 绘制圆锥体线框(basePos 为底面中心,topPos 为顶点,baseRadius 为底面半径) + public static void Cone(Vector3 basePos, Vector3 topPos, float baseRadius, Color? color = null) + { + Vector3 dir = topPos - basePos; + float height = dir.magnitude; + if (height < 0.001f) return; + Vector3 center = (basePos + topPos) * 0.5f; + Quaternion rot = Quaternion.FromToRotation(Vector3.up, dir / height); + DrawShapes.Cone(center, new Vector3(baseRadius * 2f, height, baseRadius * 2f), rot, color ?? Color.white); + } + + /// 绘制 3D 箭头(从 start 到 end 的实心箭头) + public static void Arrow3D(Vector3 start, Vector3 end, Color? color = null) + { + Color c = color ?? Color.white; + Vector3 dir = end - start; + float len = dir.magnitude; + if (len < 0.001f) return; + Vector3 dirN = dir / len; + // 箭杆 + DrawBasics.Line(start, end, c); + // 箭头头部:在终点处添加两条斜线 + float headLen = Mathf.Min(len * 0.25f, 0.5f); + float headWidth = headLen * 0.5f; + Vector3 perp = Vector3.Cross(dirN, Vector3.up).normalized; + if (perp.sqrMagnitude < 0.01f) + perp = Vector3.Cross(dirN, Vector3.forward).normalized; + Vector3 perp2 = Vector3.Cross(dirN, perp).normalized; + DrawBasics.Line(end, end - dirN * headLen + perp * headWidth, c); + DrawBasics.Line(end, end - dirN * headLen - perp * headWidth, c); + DrawBasics.Line(end, end - dirN * headLen + perp2 * headWidth, c); + DrawBasics.Line(end, end - dirN * headLen - perp2 * headWidth, c); + } + + /// 绘制十字准星(三条轴线上的交叉线) + public static void Crosshair(Vector3 position, float size = 1f, Color? color = null) + { + Color c = color ?? Color.white; + float hs = size * 0.5f; + DrawBasics.Line(position - Vector3.right * hs, position + Vector3.right * hs, c); + DrawBasics.Line(position - Vector3.up * hs, position + Vector3.up * hs, c); + DrawBasics.Line(position - Vector3.forward * hs, position + Vector3.forward * hs, c); + } + + /// 绘制正多边形 + public static void Polygon(int sides, Vector3 center, float radius, Color? color = null) + { + sides = Mathf.Max(3, sides); + DrawShapes.RegularPolygon(sides, center, radius, color ?? Color.white); + } + + #endregion + + #region 引擎工具(网格 / 坐标轴 / 旋转 / 缩放 / 包围盒) + + /// 绘制三轴网格平面(X/Y/Z 三个方向) + public static void Grid(Vector3 center, float extent = 10f, Color? colorX = null, Color? colorY = null, Color? colorZ = null) + { + DrawEngineBasics.GridPlanes(center, extent, + overwriteColorForX: colorX ?? Color.white, + overwriteColorForY: colorY ?? Color.white, + overwriteColorForZ: colorZ ?? Color.white); + } + + /// 绘制 X 轴网格平面 + public static void GridX(Vector3 center, float extent = 10f, Color? color = null) + { + DrawEngineBasics.XGridPlanes(center, extent, overwriteColor: color ?? Color.white); + } + + /// 绘制 Y 轴网格平面 + public static void GridY(Vector3 center, float extent = 10f, Color? color = null) + { + DrawEngineBasics.YGridPlanes(center, extent, overwriteColor: color ?? Color.white); + } + + /// 绘制 Z 轴网格平面 + public static void GridZ(Vector3 center, float extent = 10f, Color? color = null) + { + DrawEngineBasics.ZGridPlanes(center, extent, overwriteColor: color ?? Color.white); + } + + /// 在指定位置绘制 XYZ 坐标轴(红 X / 绿 Y / 蓝 Z) + public static void Axes(Vector3 position, float length = 1f, float lineWidth = 0f) + { + Vector3 half = Vector3.one * length * 0.5f; + // X: 红色 + DrawBasics.Line(position - Vector3.right * half.x, position + Vector3.right * half.x, Color.red, lineWidth); + // Y: 绿色 + DrawBasics.Line(position - Vector3.up * half.y, position + Vector3.up * half.y, Color.green, lineWidth); + // Z: 蓝色 + DrawBasics.Line(position - Vector3.forward * half.z, position + Vector3.forward * half.z, Color.blue, lineWidth); + } + + /// 绘制 Transform 的位置标记 + public static void Position(Transform transform, Color? color = null) + { + DrawEngineBasics.Position(transform, color ?? Color.white); + } + + /// 绘制 Transform 的缩放指示 + public static void Scale(Transform transform, Color? color = null) + { + DrawEngineBasics.Scale(transform, overwriteColor: color ?? Color.white); + } + + /// 绘制四元数旋转轴(可视化旋转方向和轴向) + public static void Rotation(Quaternion rotation, Vector3 position, float length = 1f, Color? color = null) + { + DrawEngineBasics.QuaternionRotation(rotation, position, length_ofUpAndForwardVectors: length, color_ofTurnAxis: color ?? Color.white); + } + + /// 绘制欧拉角(万向节可视化) + public static void EulerAngles(Vector3 eulerAngles, Vector3 position, float gimbalSize = 1f) + { + DrawEngineBasics.EulerRotation(eulerAngles, position, gimbalSize: gimbalSize); + } + + /// 绘制 GameObject 的包围盒 + public static void Bounds(GameObject gameObject, Color? color = null) + { + DrawEngineBasics.Bounds(gameObject, color ?? Color.white); + } + + /// 绘制 Bounds 结构体 + public static void Bounds(Bounds bounds, Color? color = null) + { + DrawEngineBasics.Bounds(bounds, color ?? Color.white); + } + + /// 绘制两点间点积的可视化 + public static void DotProduct(Vector3 v1, Vector3 v2, Vector3 position) + { + DrawEngineBasics.DotProduct(v1, v2, position); + } + + /// 绘制两点间叉积的可视化 + public static void CrossProduct(Vector3 v1, Vector3 v2, Vector3 position) + { + DrawEngineBasics.CrossProduct(v1, v2, position); + } + + /// 绘制相机视锥 + public static void CameraFrustum(Vector3 position, Quaternion rotation, float nearClip = 0.3f, float farClip = 1000f, float fov = 60f, float aspect = 16f / 9f, Color? color = null) + { + DrawEngineBasics.CameraFrustum(position, rotation, color ?? Color.white, nearClip, farClip, fov, aspect); + } + + #endregion + + #region 图标 + + /// 在 3D 位置绘制预设图标 + public static void Icon(Vector3 position, DrawBasics.IconType icon, Color? color = null, float size = 1f) + { + DrawBasics.Icon(position, icon, color ?? Color.white, size); + } + + /// 在屏幕上绘制所有图标的图集(快速查阅图标名称) + public static void IconAtlas(Vector3 position = default) + { + DrawBasics.DrawAtlasOfAllIconsWithTheirNames(position); + } + + #endregion + + #region 标注 / 标签 / 文本 + + /// 在 3D 位置绘制文本标签 + public static void Label(Vector3 position, string text, Color? color = null, float size = 0.1f) + { + DrawText.Write(text, position, color ?? Color.white, size, default(Vector3), default(Vector3)); + } + + /// 在 3D 位置绘制带框文本标签 + public static void LabelFramed(Vector3 position, string text, Color? color = null, float size = 0.1f) + { + DrawText.WriteFramed(text, position, color ?? Color.white, size, default(Vector3), default(Vector3)); + } + + /// 给 GameObject 绘制屏幕空间标签(始终面向相机) + public static void Tag(GameObject go, string text = null, Color? textColor = null, Color? boxColor = null) + { + DrawEngineBasics.TagGameObject(go, text ?? go.name, textColor ?? Color.white, boxColor ?? new Color(0, 0, 0, 0.5f)); + } + + /// 给 GameObject 绘制屏幕空间标签(覆盖在屏幕上) + public static void TagScreenspace(GameObject go, string text = null, Color? textColor = null) + { + DrawEngineBasics.TagGameObjectScreenspace(go, text ?? go.name, textColor ?? Color.white); + } + + /// 在屏幕空间(视口坐标)绘制文本 + public static void ScreenText(string text, Vector2 viewportPos, Color? color = null, float size = 0.025f) + { + DrawText.WriteScreenspace(text, viewportPos, color ?? Color.white, size, Vector2.up); + } + + /// 在 3D 位置绘制屏幕空间文本(自动投影到屏幕) + public static void ScreenTextAtWorldPos(string text, Vector3 worldPos, Color? color = null, float size = 0.025f) + { + DrawText.WriteScreenspace(text, worldPos, color ?? Color.white, size, Vector2.up); + } + + /// 显示布尔值的可视化指示器 + public static void BoolDisplay(bool value, Vector3 position, string name = null, Color? color = null) + { + DrawEngineBasics.BoolDisplayer(value, position, name, color_forTextAndFrame: color ?? Color.white); + } + + #endregion + + #region 物理 + + /// 绘制射线检测结果(命中时绿色,未命中时红色) + public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance, out RaycastHit hitInfo, Color? hitColor = null, Color? missColor = null, int layerMask = ~0) + { + bool hit = Physics.Raycast(origin, direction, out hitInfo, maxDistance, layerMask); + Color color = hit ? (hitColor ?? Color.green) : (missColor ?? Color.red); + DrawBasics.Ray(origin, direction, color, width: 0); + if (hit) + { + DrawBasics.Point(hitInfo.point, color, 0.3f); + } + return hit; + } + + /// 绘制球体投射检测结果 + public static bool SphereCast(Vector3 origin, float radius, Vector3 direction, out RaycastHit hitInfo, float maxDistance, Color? color = null, int layerMask = ~0) + { + bool hit = Physics.SphereCast(origin, radius, direction, out hitInfo, maxDistance, layerMask); + Color c = color ?? (hit ? Color.green : Color.red); + Vector3 endPos = hit ? hitInfo.point : origin + direction.normalized * maxDistance; + DrawShapes.Sphere(endPos, radius, c); + DrawBasics.Line(origin, endPos, c); + return hit; + } + + /// 绘制球体重叠检测范围 + public static Collider[] OverlapSphere(Vector3 position, float radius, Color? color = null, int layerMask = ~0) + { + DrawShapes.Sphere(position, radius, color ?? new Color(0, 1, 0, 0.3f)); + return Physics.OverlapSphere(position, radius, layerMask); + } + + /// 绘制盒体重叠检测范围 + public static Collider[] OverlapBox(Vector3 center, Vector3 halfExtents, Color? color = null, Quaternion? rotation = null, int layerMask = ~0) + { + DrawShapes.Cube(center, halfExtents * 2f, color ?? new Color(0, 1, 0, 0.3f), rotation ?? Quaternion.identity); + return Physics.OverlapBox(center, halfExtents, rotation ?? Quaternion.identity, layerMask); + } + + #endregion + + #region 测量 + + /// 绘制两点间距离的阈值指示(超过阈值变样式) + public static void DistanceThreshold(Vector3 from, Vector3 to, float threshold, Color? nearColor = null, Color? farColor = null) + { + DrawMeasurements.DistanceThreshold(from, to, threshold, + displayDistanceAlsoAsText: true, + overwriteColor_forNear: nearColor ?? Color.green, + overwriteColor_forFar: farColor ?? Color.red); + } + + /// 绘制两点间双阈值指示(近/中/远三种样式) + public static void DistanceThresholds(Vector3 from, Vector3 to, float smallThreshold, float bigThreshold) + { + DrawMeasurements.DistanceThresholds(from, to, smallThreshold, bigThreshold, displayDistanceAlsoAsText: true); + } + + #endregion + + #region 2D 辅助 + + /// 在 2D 平面(X-Y 平面)绘制线段 + public static void Line2D(Vector2 a, Vector2 b, Color? color = null, float width = 0f, float zPos = float.PositiveInfinity) + { + DrawBasics2D.Line(a, b, color ?? Color.white, width, custom_zPos: zPos); + } + + /// 在 2D 平面绘制带箭头向量 + public static void Vector2D(Vector2 from, Vector2 to, Color? color = null, float zPos = float.PositiveInfinity) + { + DrawBasics2D.Vector(from, to, color ?? Color.white, custom_zPos: zPos); + } + + /// 在 2D 平面绘制圆形 + public static void Circle2D(Vector2 center, float radius, Color? color = null, float zPos = 0f) + { + DrawShapes.Circle(new Vector3(center.x, center.y, zPos), radius, color ?? Color.white); + } + + #endregion +} diff --git a/Runtime/MacroLibrary/MacroDXXL.cs.meta b/Runtime/MacroLibrary/MacroDXXL.cs.meta new file mode 100644 index 0000000..2bc3875 --- /dev/null +++ b/Runtime/MacroLibrary/MacroDXXL.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 915d7ff0ed436c146852b948da6798b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/MacroLibrary/MacroWebGLLib.cs b/Runtime/MacroLibrary/MacroWebGLLib.cs index 6b5398e..8c87b27 100644 --- a/Runtime/MacroLibrary/MacroWebGLLib.cs +++ b/Runtime/MacroLibrary/MacroWebGLLib.cs @@ -13,7 +13,7 @@ namespace XericLibrary.Runtime.MacroLibrary /// /// Web 平台文件句柄。 /// - public class WebGLHandle : CrossPlatformFileHandle + public class WebGLHandle : MacroFile.CrossPlatformFileHandle { public override string PlatformName => "WebGL"; public static WebGLHandle handle = new WebGLHandle(); @@ -28,14 +28,54 @@ namespace XericLibrary.Runtime.MacroLibrary handle = this; } +#if XERIC_WEBGL_DOWNLOAD [DllImport("__Internal")] private static extern void Download(string base64str, string fileName); +#endif - //[DllImport("__Internal")] - //private static extern void OpenFileDialog(string gameObjectName, string callbackMethodName); +#if XERIC_WEBGL_FILEBROWSER + [DllImport("__Internal")] + private static extern void OpenFileDialog(string gameObjectName, string callbackMethodName); - //[DllImport("__Internal")] - //private static extern void OpenFileDialogBinary(string gameObjectName, string callbackMethodName); + [DllImport("__Internal")] + private static extern void OpenFileDialogBinary(string gameObjectName, string callbackMethodName); +#endif + +#if XERIC_WEBGL_JSBRIDGE + /// + /// 从 JS 端发送消息到 Unity(对应 xeric-jsbridge.js 中的 SendToUnity) + /// + public static void SendToUnity(string gameObject, string method, string message) + { +#if UNITY_WEBGL && !UNITY_EDITOR + SendMessageToUnity(gameObject, method, message); +#else + // Editor 回退:尝试直接查找并调用 + var go = GameObject.Find(gameObject); + if (go != null) + go.SendMessage(method, message, SendMessageOptions.DontRequireReceiver); +#endif + } + + [DllImport("__Internal")] + private static extern void SendMessageToUnity(string gameObject, string method, string message); + + /// + /// 通知 JS 端 Canvas 获得焦点(Unity 可捕获输入) + /// + public static void NotifyCanvasFocus() + { + // JS 端 OnCanvasFocus() 会反向调用 Unity.SendMessage + } + + /// + /// 通知 JS 端 Canvas 失去焦点(前端可处理输入) + /// + public static void NotifyCanvasBlur() + { + // JS 端 OnCanvasBlur() 会反向调用 Unity.SendMessage + } +#endif public override bool ReadTextFromFile(string absolutePathname, out string content) { @@ -58,6 +98,7 @@ namespace XericLibrary.Runtime.MacroLibrary return waitFlag; } +#if XERIC_WEBGL_DOWNLOAD public override bool WriteTextIntoFile(string absolutePathname, string content) { try @@ -71,6 +112,7 @@ namespace XericLibrary.Runtime.MacroLibrary return false; } } +#endif public override async Task AsyncReadTextFromFile(string absolutePathname, Action complete, Action loadError) { @@ -86,6 +128,7 @@ namespace XericLibrary.Runtime.MacroLibrary return result; } +#if XERIC_WEBGL_DOWNLOAD public override async Task AsyncWriteTextIntoFile(string absolutePathname, string content, Action complete, Action loadError) { await Task.Yield(); @@ -101,6 +144,7 @@ namespace XericLibrary.Runtime.MacroLibrary await Task.CompletedTask; return false; } +#endif public override string CombinePath(string pathA, string pathB) { diff --git a/Runtime/XericLibrary.dll b/Runtime/XericLibrary.dll index 55b7bb9..0b5f0f4 100644 Binary files a/Runtime/XericLibrary.dll and b/Runtime/XericLibrary.dll differ