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
}