9 protected bool m_bActivated;
12 protected ResourceName m_sReticleTexture;
13 protected ResourceName m_sReticleGlowTexture;
14 protected ResourceName m_sFilterTexture;
17 protected float m_fOpticBaseFov;
18 protected float m_fOpticCurrentFov;
19 protected float m_fReticleSize;
20 protected float m_fReticleAngularSize;
21 protected float m_fReticlePortion;
22 protected float m_fReticleBaseZoom;
23 protected float m_fReticleOffsetX;
24 protected float m_fReticleOffsetY;
25 protected float m_fVignetteScale;
26 protected float m_fVignetteSize;
27 protected float m_fVignetteMoveSpeed;
28 protected float m_fObjectiveFov;
29 protected float m_fObjectiveScale;
30 protected float m_fObjectiveSize;
31 protected float m_fMisalignmentScale;
32 protected float m_fMisalignmentDampingSpeed;
33 protected float m_fRotationScale;
34 protected float m_fRotationDampingSpeed;
35 protected float m_fMovementScale;
36 protected float m_fMovementDampingSpeed;
37 protected float m_fRollScale;
38 protected float m_fRollDampingSpeed;
39 protected float m_fRollOffset;
41 protected vector m_vMisalignmentOffset;
42 protected vector m_vObjectiveOffset;
43 protected vector m_vVignetteOffset;
44 protected vector m_vRotation;
45 protected vector m_vRotationSpeed;
46 protected vector m_vRotationOffset;
47 protected vector m_vMovement;
48 protected vector m_vMovementSpeed;
49 protected vector m_vMovementOffset;
51 protected bool m_bInitialBlurOver;
54 const string WIDGET_LAYOUT_REAR =
"HRearEyePiece";
55 const string WIDGET_LAYOUT_FRONT =
"HFrontObjective";
56 const string WIDGET_IMAGE_COVER =
"ImgCover";
58 const string WIDGET_SIZE_REAR =
"SizeRear";
59 const string WIDGET_SIZE_OBJECTIVE =
"SizeFrontObjective";
61 const string WIDGET_IMAGE_PADDING_LEFT =
"ImgPaddingLeft";
62 const string WIDGET_IMAGE_PADDING_RIGHT =
"ImgPaddingRight";
63 const string WIDGET_IMAGE_PADDING_TOP =
"ImgPaddingTop";
64 const string WIDGET_IMAGE_PADDING_BOTTOM =
"ImgPaddingBottom";
66 const string WIDGET_OVERLAY_RETICLES =
"OverlayReticles";
67 const string WIDGET_IMAGE_RETICLE =
"ImgReticle";
68 const string WIDGET_IMAGE_RETICLE_GLOW =
"ImgReticleGlow";
69 const string WIDGET_IMAGE_VIGNETTE =
"ImgVignette";
70 const string WIDGET_IMAGE_SCRATCHES =
"ImgScratches";
71 const string WIDGET_BLUR =
"Blur";
72 const string WIDGET_IMAGE_FILTER =
"ImgFilter";
74 const string WIDGET_SIZE_LEFT =
"SizePaddingLeft";
75 const string WIDGET_SIZE_TOP =
"SizePaddingTop";
77 const float OPACITY_INITIAL = 0.75;
79 protected Widget m_wLayoutRear;
80 protected Widget m_wLayoutFront;
81 protected ImageWidget m_wImgCover;
82 protected ImageWidget m_wImgScratches;
84 protected Widget m_wOverlayReticles;
85 protected ImageWidget m_wImgReticle;
86 protected ImageWidget m_wImgReticleGlow;
87 protected BlurWidget m_wBlur;
88 protected ImageWidget m_wImgFilter;
90 protected SizeLayoutWidget m_wRearFillLeft;
91 protected SizeLayoutWidget m_wRearFillTop;
92 protected SizeLayoutWidget m_wFrontFillLeft;
93 protected SizeLayoutWidget m_wFrontFillTop;
95 protected SizeLayoutWidget m_wSizeLayoutRear;
96 protected SizeLayoutWidget m_wSizeLayoutObjective;
106 protected override void DisplayStartDraw(IEntity owner)
119 layoutHandler.GetOnLayoutChange().Insert(OnLayoutChanged);
122 if (!s_bOpticDiagRegistered)
124 DiagMenu.RegisterBool(
SCR_DebugMenuID.DEBUGUI_WEAPONS_OPTICS_USE_2D,
"",
"Toggle 2D optics",
"Weapons");
125 DiagMenu.RegisterBool(
SCR_DebugMenuID.DEBUGUI_WEAPONS_OPTICS,
"",
"Show optics diag",
"Weapons");
126 s_bOpticDiagRegistered =
true;
132 protected override void DisplayStopDraw(IEntity owner)
139 m_Optic.OnSetupOpticImage().Remove(SetupOpticImage);
140 m_Optic.OnIlluminationChange().Remove(ChangeReticleTint);
144 protected override void DisplayUpdate(IEntity owner,
float timeSlice)
147 if (s_bToggle2DOptics != DiagMenu.GetBool(
SCR_DebugMenuID.DEBUGUI_WEAPONS_OPTICS_USE_2D))
149 s_bToggle2DOptics = !s_bToggle2DOptics;
150 SetScope2DEnabled(!
SCR_Global.IsScope2DEnabled());
160 if (!
m_bInADS && !SCR_BinocularsComponent.IsZoomedView() && !
m_Optic.GetIsZoomed())
164 if (!m_wLayoutRear || !m_wLayoutFront)
169 MoveScopeWidgets(timeSlice);
170 LowerBlurIntensity(timeSlice,
m_Optic.GetAnimationSpeedBlur());
172 m_fReticleOffsetX =
m_Optic.GetReticleOffsetX();
173 m_fReticleOffsetY =
m_Optic.GetCurrentReticleOffsetY();
174 SetReticleOffset(m_fReticleOffsetX, m_fReticleOffsetY);
179 protected void FindWidgets()
182 m_wLayoutRear =
m_wRoot.FindAnyWidget(WIDGET_LAYOUT_REAR);
183 m_wLayoutFront =
m_wRoot.FindAnyWidget(WIDGET_LAYOUT_FRONT);
184 m_wImgCover = ImageWidget.Cast(
m_wRoot.FindAnyWidget(WIDGET_IMAGE_COVER));
185 m_wImgScratches = ImageWidget.Cast(
m_wRoot.FindAnyWidget(WIDGET_IMAGE_SCRATCHES));
187 if (!m_wLayoutRear || !m_wLayoutFront)
189 Print(
"Scope vignette movement is not possible due to missing widget references!", LogLevel.WARNING);
194 m_wSizeLayoutRear = SizeLayoutWidget.Cast(m_wLayoutRear.FindAnyWidget(WIDGET_SIZE_REAR));
195 m_wRearFillLeft = SizeLayoutWidget.Cast(m_wLayoutRear.FindAnyWidget(WIDGET_SIZE_LEFT));
196 m_wRearFillTop = SizeLayoutWidget.Cast(m_wLayoutRear.FindAnyWidget(WIDGET_SIZE_TOP));
199 m_wSizeLayoutObjective = SizeLayoutWidget.Cast(m_wLayoutFront.FindAnyWidget(WIDGET_SIZE_OBJECTIVE));
200 m_wFrontFillLeft = SizeLayoutWidget.Cast(m_wLayoutFront.FindAnyWidget(WIDGET_SIZE_LEFT));
201 m_wFrontFillTop = SizeLayoutWidget.Cast(m_wLayoutFront.FindAnyWidget(WIDGET_SIZE_TOP));
203 m_wOverlayReticles = m_wLayoutFront.FindAnyWidget(WIDGET_OVERLAY_RETICLES);
204 m_wImgReticle = ImageWidget.Cast(m_wLayoutFront.FindAnyWidget(WIDGET_IMAGE_RETICLE));
205 m_wImgReticleGlow = ImageWidget.Cast(m_wLayoutFront.FindAnyWidget(WIDGET_IMAGE_RETICLE_GLOW));
206 m_wBlur = BlurWidget.Cast(
m_wRoot.FindAnyWidget(WIDGET_BLUR));
207 m_wImgFilter = ImageWidget.Cast(m_wLayoutFront.FindAnyWidget(WIDGET_IMAGE_FILTER));
212 void SetupOpticImage()
215 if (!m_sReticleTexture.IsEmpty())
216 m_wImgReticle.LoadImageTexture(0, m_sReticleTexture);
218 m_wImgReticleGlow.SetVisible(!m_sReticleTexture.IsEmpty());
220 if (!m_sReticleGlowTexture.IsEmpty())
221 m_wImgReticleGlow.LoadImageTexture(0, m_sReticleGlowTexture);
223 m_wImgReticleGlow.SetVisible(!m_sReticleGlowTexture.IsEmpty());
226 if (!m_sFilterTexture.IsEmpty())
227 m_wImgFilter.LoadImageTexture(0, m_sFilterTexture);
229 m_wImgFilter.SetVisible(!m_sFilterTexture.IsEmpty());
231 UpdateCurrentFov(
true);
235 void UpdateCurrentFov(
bool forceUpdate =
false)
249 CameraBase camera =
GetGame().GetCameraManager().CurrentCamera();
251 fov = camera.GetVerticalFOV();
254 if (!
float.AlmostEqual(m_fOpticCurrentFov, fov))
255 m_fOpticCurrentFov = fov;
256 else if (!forceUpdate)
264 void UpdateReticleSize()
267 if (m_fReticleBaseZoom > 0)
268 m_fReticleBaseZoom = -
m_Optic.CalculateZoomFOV(m_fReticleBaseZoom);
271 if (m_fReticleBaseZoom == 0)
272 fovReticle = m_fOpticCurrentFov;
274 fovReticle = -m_fReticleBaseZoom;
277 float reticleAngularSize;
278 if (m_fReticlePortion > 0)
279 reticleAngularSize = m_fReticleAngularSize / m_fReticlePortion;
282 m_fReticleSize = reticleAngularSize / fovReticle;
283 else if (m_fOpticBaseFov > 0)
284 m_fReticleSize = reticleAngularSize / m_fOpticBaseFov;
286 UpdateScale(1, 1, 1);
297 m_Optic.OnSetupOpticImage().Remove(SetupOpticImage);
298 m_Optic.OnIlluminationChange().Remove(ChangeReticleTint);
308 m_Optic.OnSetupOpticImage().Insert(SetupOpticImage);
309 m_Optic.OnIlluminationChange().Insert(ChangeReticleTint);
313 m_Optic.OnSetupOpticImage().Remove(SetupOpticImage);
314 m_Optic.OnIlluminationChange().Remove(ChangeReticleTint);
322 m_bInitialBlurOver =
false;
324 m_vMisalignmentOffset = vector.Zero;
326 m_Optic.GetRotation(m_vRotation, 1);
327 m_vRotationSpeed = vector.Zero;
328 m_vRotationOffset = vector.Zero;
330 m_Optic.GetMovement(m_vMovement, 1);
332 m_vMovementSpeed = vector.Zero;
333 m_vMovementOffset = vector.Zero;
341 protected void Activate()
344 AnimateWidget.StopAnimation(
m_wRoot, WidgetAnimationOpacity);
345 GetGame().GetCallqueue().Remove(DeactivateWidget);
349 m_wImgCover.SetVisible(
false);
353 m_wBlur.SetIntensity(OPACITY_INITIAL);
354 m_wBlur.SetOpacity(1);
359 GetGame().GetCallqueue().CallLater(PlayEntryAnimation,
m_Optic.GetAnimationActivationDelay(),
false,
m_Optic.GetAnimationEnterTime());
364 protected void Deactivate()
366 m_bActivated =
false;
369 AnimateWidget.StopAnimation(
m_wRoot, WidgetAnimationOpacity);
370 GetGame().GetCallqueue().Remove(PlayEntryAnimation);
374 GetGame().GetCallqueue().CallLater(DeactivateWidget,
m_Optic.GetAnimationDeactivationDelay(),
false);
380 protected void PlayEntryAnimation(
float animationSpeed)
382 if (animationSpeed > 0)
383 AnimateWidget.Opacity(
m_wRoot, 1, animationSpeed);
390 protected void DeactivateWidget()
393 m_wImgCover.SetOpacity(0);
403 m_Optic.GetReticleTextures(m_sReticleTexture, m_sReticleGlowTexture, m_sFilterTexture);
404 m_Optic.GetReticleData(m_fReticleAngularSize, m_fReticlePortion, m_fReticleBaseZoom);
405 m_fOpticBaseFov =
m_Optic.GetFovZoomed();
406 m_fObjectiveFov =
m_Optic.GetObjectiveFov();
407 m_fObjectiveScale =
m_Optic.GetObjectiveScale();
408 m_fVignetteScale =
m_Optic.GetVignetteScale();
409 m_fVignetteMoveSpeed =
m_Optic.GetVignetteMoveSpeed();
410 m_fMisalignmentScale =
m_Optic.GetMisalignmentScale();
411 m_fMisalignmentDampingSpeed =
m_Optic.GetMisalignmentDampingSpeed();
412 m_fRotationScale =
m_Optic.GetRotationScale();
413 m_fRotationDampingSpeed =
m_Optic.GetRotationDampingSpeed();
414 m_fMovementScale =
m_Optic.GetMovementScale();
415 m_fMovementDampingSpeed =
m_Optic.GetMovementDampingSpeed();
416 m_fRollScale =
m_Optic.GetRollScale();
417 m_fRollDampingSpeed =
m_Optic.GetRollDampingSpeed();
420 s_bDebugOpticsReset =
true;
426 void UpdateScale(
float reticleScale,
float vignetteScale,
float objectiveScale)
429 WorkspaceWidget workspace =
GetGame().GetWorkspace();
431 uiScale = workspace.DPIUnscale(workspace.GetHeight());
434 if (m_wOverlayReticles)
436 float reticleSize = m_fReticleSize * uiScale * reticleScale;
437 FrameSlot.SetSize(m_wOverlayReticles, reticleSize, reticleSize);
441 if (m_wSizeLayoutRear)
443 m_fVignetteSize = m_fObjectiveFov * m_fVignetteScale * uiScale * vignetteScale / m_fOpticBaseFov;
445 m_wSizeLayoutRear.SetWidthOverride(m_fVignetteSize);
446 m_wSizeLayoutRear.SetHeightOverride(m_fVignetteSize);
450 if (m_wSizeLayoutObjective)
452 m_fObjectiveSize = m_fObjectiveFov * m_fObjectiveScale * uiScale * objectiveScale / m_fOpticBaseFov;
454 m_wSizeLayoutObjective.SetWidthOverride(m_fObjectiveSize);
455 m_wSizeLayoutObjective.SetHeightOverride(m_fObjectiveSize);
463 void SetReticleOffset(
float x,
float y)
465 if (!m_wOverlayReticles)
468 WorkspaceWidget workspace =
GetGame().GetWorkspace();
472 float fov = m_fOpticBaseFov;
473 CameraManager cameraManager =
GetGame().GetCameraManager();
476 CameraBase camera = cameraManager.CurrentCamera();
478 fov = camera.GetVerticalFOV();
481 float uiHeight = workspace.DPIUnscale(workspace.GetHeight());
482 float offsetX = x * uiHeight / fov;
483 float offsetY = y * uiHeight / fov;
485 FrameSlot.SetPos(m_wOverlayReticles, offsetX, offsetY);
487 vector size = FrameSlot.GetSize(m_wOverlayReticles);
490 float pivotX = 0.5 - (offsetX / size[0]);
491 float pivotY = 0.5 - (offsetY / size[1]);
492 m_wImgReticle.SetPivot(pivotX, pivotY);
495 if (m_wImgReticleGlow)
497 float pivotX = 0.5 - (offsetX / size[0]);
498 float pivotY = 0.5 - (offsetY / size[1]);
499 m_wImgReticleGlow.SetPivot(pivotX, pivotY);
507 protected void LowerBlurIntensity(
float timeSlice,
float speed)
512 float intensity = m_wBlur.GetIntensity();
513 intensity = Math.Lerp(intensity, 0, timeSlice * speed);
516 if (intensity < 0.1 && !m_bInitialBlurOver)
518 m_bInitialBlurOver =
true;
522 m_wBlur.SetIntensity(intensity);
529 protected void ChangeReticleTint(Color color, Color colorGlow)
531 if (m_wImgReticleGlow)
532 m_wImgReticleGlow.SetColor(colorGlow);
535 m_wImgReticle.SetColor(color);
540 protected void MoveScopeWidgets(
float timeSlice)
543 CameraManager cameraManager =
GetGame().GetCameraManager();
547 CameraBase camera = cameraManager.CurrentCamera();
552 float fov = camera.GetVerticalFOV();
557 vector misalignment =
m_Optic.GetMisalignmentAngles(camera);
560 float roll = misalignment[2] * m_fRollScale;
561 if (m_fRollDampingSpeed > 0)
563 float rollSmooth = Math.Min(1, timeSlice * m_fRollDampingSpeed);
564 m_fRollOffset = Math.Lerp(m_fRollOffset, roll, rollSmooth);
565 roll -= m_fRollOffset;
569 if (m_fMisalignmentDampingSpeed > 0)
571 float offsetDamping = Math.Min(timeSlice * m_fMisalignmentDampingSpeed, 1);
572 m_vMisalignmentOffset = vector.Lerp(m_vMisalignmentOffset, misalignment, offsetDamping);
573 misalignment = misalignment - m_vMisalignmentOffset;
578 if (m_fRotationDampingSpeed > 0)
580 float rotationDamping = Math.Min(timeSlice * m_fRotationDampingSpeed, 1);
581 m_vRotationOffset = vector.Lerp(m_vRotationOffset,
rotation, rotationDamping);
586 vector movement =
m_Optic.GetMovement(m_vMovement, timeSlice);
587 if (m_fMovementDampingSpeed > 0)
589 float movementDamping = Math.Min(timeSlice * m_fMovementDampingSpeed, 1);
590 m_vMovementOffset = vector.Lerp(m_vMovementOffset, movement, movementDamping);
591 movement = movement - m_vMovementOffset;
595 float vignetteMove = Math.Min(timeSlice * m_fVignetteMoveSpeed, 1);
597 m_vVignetteOffset = vector.Lerp(m_vVignetteOffset, m_fMisalignmentScale * misalignment, vignetteMove);
600 m_vObjectiveOffset = m_fMisalignmentScale * misalignment;
602 if (m_fRotationScale > 0)
603 m_vVignetteOffset = m_vVignetteOffset -
rotation * m_fRotationScale;
605 if (m_fMovementScale > 0)
606 m_vVignetteOffset = m_vVignetteOffset + movement * m_fMovementScale;
608 WorkspaceWidget workspace =
GetGame().GetWorkspace();
610 float screenW, screenH;
611 workspace.GetScreenSize(screenW, screenH);
612 screenW = workspace.DPIUnscale(screenW);
613 screenH = workspace.DPIUnscale(screenH);
615 float pixelsPerDegree = screenH / fov;
618 float defaultRearLeft = VignetteDefaultPosition(screenW, m_fVignetteSize);
619 float defaultRearTop = VignetteDefaultPosition(screenH, m_fVignetteSize);
621 float rearPaddingLeft = defaultRearLeft + pixelsPerDegree * m_vVignetteOffset[0];
622 float rearPaddingTop = defaultRearTop - pixelsPerDegree * m_vVignetteOffset[1];
624 m_wRearFillLeft.SetWidthOverride(rearPaddingLeft);
625 m_wRearFillTop.SetHeightOverride(rearPaddingTop);
628 float defaultFrontLeft = VignetteDefaultPosition(screenW, m_fObjectiveSize);
629 float defaultFrontTop = VignetteDefaultPosition(screenH, m_fObjectiveSize);
631 float frontPaddingLeft = defaultFrontLeft + pixelsPerDegree * m_vObjectiveOffset[0];
632 float frontPaddingTop = defaultFrontTop - pixelsPerDegree * m_vObjectiveOffset[1];
634 m_wFrontFillLeft.SetWidthOverride(frontPaddingLeft);
635 m_wFrontFillTop.SetHeightOverride(frontPaddingTop);
639 m_wImgReticle.SetRotation(roll);
641 if (m_wImgReticleGlow)
642 m_wImgReticleGlow.SetRotation(roll);
645 m_wImgFilter.SetRotation(roll);
648 m_wImgCover.SetRotation(roll);
651 m_wImgScratches.SetRotation(roll +
m_Optic.GetScratchesRoll());
654 if (m_bInitialBlurOver)
655 MotionBlur(m_vVignetteOffset[0], m_vVignetteOffset[1]);
659 protected void MotionBlur(
float posX,
float posY)
669 float intensity = Math.AbsFloat(posX);
670 if (intensity > Math.AbsFloat(posY))
671 intensity = Math.AbsFloat(posY);
674 intensity = intensity *
m_Optic.GetMotionBlurScale();
675 if (intensity >
m_Optic.GetMotionBlurMax())
676 intensity =
m_Optic.GetMotionBlurMax();
678 m_wBlur.SetIntensity(intensity);
682 protected float VignetteDefaultPosition(
float screenSize,
float vignetteSize)
684 float defaultPos = (screenSize - vignetteSize) * 0.5;
691 protected static bool s_bOpticDiagRegistered;
692 protected static bool s_bToggle2DOptics;
693 protected static bool s_bDebugOptics;
694 protected static bool s_bDebugOpticsReset;
695 protected static bool s_bDebug2DOptics;
696 protected static bool s_bDebug2DOpticsReset;
697 protected static bool s_bDebugDrawReset;
698 protected static bool s_bDebugDrawCross =
true;
699 protected static bool s_bDebugDrawNotches =
true;
700 protected static bool s_bDebugDrawFieldOfView =
true;
701 protected static bool s_bDebugDrawRandomColors;
704 protected static float s_fCrossUnit = 0.05625;
705 protected static float s_fCrossRadius = 100;
708 protected static float s_fNotchesUnit = 0.05625;
709 protected static float s_fNotchesSize = 100;
710 protected static float s_fNotchesSmallLength = 5;
711 protected static float s_fNotchesSmallSpacing = 5;
712 protected static float s_fNotchesLargeLength = 10;
713 protected static float s_fNotchesLargeSpacing = 10;
716 protected static float s_fFieldOfViewUnit = 0.05625;
717 protected static float s_fFieldOfViewAngle = 100;
719 protected static ref array<int> s_aRandomColors = {COLOR_BLUE, COLOR_RED, COLOR_GREEN, COLOR_YELLOW};
720 protected static int s_iLineColor;
723 protected void InputFloatClamped(inout
float value,
string label,
float min,
float max,
int pxWidth = 100)
725 DbgUI.InputFloat(label, value, pxWidth);
726 value = Math.Clamp(value, min, max);
732 if (s_bDebugOpticsReset)
734 s_bDebugOpticsReset =
false;
738 SetScope2DEnabled(
true);
739 s_bToggle2DOptics = !DiagMenu.GetBool(
SCR_DebugMenuID.DEBUGUI_WEAPONS_OPTICS_USE_2D);
745 if (s_bDebugDrawReset)
747 s_bDebugDrawReset =
false;
748 s_bDebugDrawCross =
true;
749 s_bDebugDrawNotches =
true;
750 s_bDebugDrawFieldOfView =
true;
751 s_bDebugDrawRandomColors =
false;
754 s_fCrossUnit = 0.05625;
755 s_fCrossRadius = 100;
758 s_fNotchesUnit = 0.05625;
759 s_fNotchesSize = 100;
760 s_fNotchesSmallLength = 5;
761 s_fNotchesSmallSpacing = 5;
762 s_fNotchesLargeLength = 10;
763 s_fNotchesLargeSpacing = 10;
766 s_fFieldOfViewUnit = 0.05625;
767 s_fFieldOfViewAngle = 100;
776 m_Optic.GetSightsTransform(sightMat,
true);
777 sightMat[3] =
m_Optic.GetSightsFrontPosition(
true);
779 m_Optic.GetOwner().GetWorldTransform(ownerMat);
780 Math3D.MatrixMultiply4(ownerMat, sightMat, sightMat);
784 CameraBase camera =
GetGame().GetCameraManager().CurrentCamera();
785 if (camera && m_fRollDampingSpeed != 0)
788 camera.GetTransform(cameraMat);
789 sightMat[0] = cameraMat[0];
790 sightMat[1] = cameraMat[1];
793 DbgUI.Begin(
"Optics", 100, 300);
795 array<string> units = {};
800 DbgUI.Text(
"________________________________________");
801 DbgUI.Check(
"OPTICS ", s_bDebugOptics);
808 InputFloatClamped(m_fObjectiveFov,
"m_fObjectiveFov deg", 0, 100);
809 InputFloatClamped(m_fObjectiveScale,
"m_fObjectiveScale %", 0, 100);
810 InputFloatClamped(m_fReticleBaseZoom,
"m_fReticleBaseZoom x", -60, 200);
811 InputFloatClamped(m_fReticleAngularSize,
"m_fReticleAngularSize deg", 0, 100);
812 InputFloatClamped(m_fReticlePortion,
"m_fReticlePortion %", 0, 100);
813 InputFloatClamped(m_fReticleOffsetX,
"m_fReticleOffsetX deg", -90, 90);
814 InputFloatClamped(m_fReticleOffsetY,
"m_fReticleOffsetY deg", -90, 90);
817 if (
m_Optic && DbgUI.Button(
"LOAD OPTICS ATTRIBUTES"))
820 if (
m_Optic && DbgUI.Button(
"SAVE OPTICS ATTRIBUTES"))
822 m_Optic.SetObjectiveFov(m_fObjectiveFov);
823 m_Optic.SetObjectiveScale(m_fObjectiveScale);
824 m_Optic.SetReticleBaseZoom(m_fReticleBaseZoom);
825 m_Optic.SetReticleAngularSize(m_fReticleAngularSize);
826 m_Optic.SetReticlePortion(m_fReticlePortion);
827 m_Optic.SetReticleOffsetX(m_fReticleOffsetX);
828 m_Optic.SetReticleOffsetY(m_fReticleOffsetY);
834 DbgUI.Text(
"________________________________________");
835 DbgUI.Check(
"2D OPTICS ", s_bDebug2DOptics);
839 if (s_bDebug2DOptics)
842 InputFloatClamped(m_fVignetteScale,
"m_fVignetteScale ", 0, 100);
843 InputFloatClamped(m_fVignetteMoveSpeed,
"m_fVignetteMoveSpeed ", -100, 100);
844 InputFloatClamped(m_fMisalignmentScale,
"m_fMisalignmentScale ", -100, 100);
845 InputFloatClamped(m_fMisalignmentDampingSpeed,
"m_fMisalignmentDampingSpeed ", -100, 100);
846 InputFloatClamped(m_fRotationScale,
"m_fRotationScale ", -100, 100);
847 InputFloatClamped(m_fRotationDampingSpeed,
"m_fRotationDampingSpeed ", -100, 100);
848 InputFloatClamped(m_fMovementScale,
"m_fMovementScale ", -100, 100);
849 InputFloatClamped(m_fMovementDampingSpeed,
"m_fMovementDampingSpeed ", -100, 100);
850 InputFloatClamped(m_fRollScale,
"m_fRollScale ", -100, 100);
851 InputFloatClamped(m_fRollDampingSpeed,
"m_fRollDampingSpeed ", -100, 100);
857 DbgUI.Text(
"________________________________________");
859 if (DbgUI.Button(
"RESET DEBUG ATTRIBUTES"))
860 s_bDebugDrawReset =
true;
862 DbgUI.Check(
"RANDOM LINE COLORS ", s_bDebugDrawRandomColors);
864 if (s_bDebugDrawRandomColors)
865 s_iLineColor = s_aRandomColors.GetRandomElement();
867 s_iLineColor = COLOR_RED;
874 DbgUI.Text(
"________________________________________");
875 DbgUI.Check(
"CROSS ", s_bDebugDrawCross);
879 if (s_bDebugDrawCross)
882 DbgUI.Combo(
"Cross units ", s_eCrossUnit, units);
884 InputFloatClamped(s_fCrossUnit,
"Custom cross unit deg", 0, 180);
886 InputFloatClamped(s_fCrossRadius,
"Cross radius ", 0, 1000);
889 float unit = DebugAngleUnitsToDegrees(s_eCrossUnit, s_fCrossUnit);
891 DebugDrawCross(sightMat, s_fCrossRadius * unit);
896 DbgUI.Text(
"________________________________________");
897 DbgUI.Check(
"NOTCHES ", s_bDebugDrawNotches);
901 if (s_bDebugDrawNotches)
904 DbgUI.Combo(
"Notches units ", s_eNotchesUnit, units);
906 InputFloatClamped(s_fNotchesUnit,
"Custom notches unit deg", 0, 180);
908 InputFloatClamped(s_fNotchesSize,
"Size ", 0, 100);
909 InputFloatClamped(s_fNotchesSmallLength,
"Small length ", 0, 100);
910 InputFloatClamped(s_fNotchesSmallSpacing,
"Small spacing ", 0, 100);
911 InputFloatClamped(s_fNotchesLargeLength,
"Large length ", 0, 100);
912 InputFloatClamped(s_fNotchesLargeSpacing,
"Large spacing ", 0, 100);
915 float unit = DebugAngleUnitsToDegrees(s_eNotchesUnit, s_fNotchesUnit);
916 DebugDrawNotches(sightMat, s_fNotchesSmallLength * unit, s_fNotchesSmallSpacing * unit, s_fNotchesSize * unit * 0.5);
917 DebugDrawNotches(sightMat, s_fNotchesLargeLength * unit, s_fNotchesLargeSpacing * unit, s_fNotchesSize * unit * 0.5);
922 DbgUI.Text(
"________________________________________");
923 DbgUI.Check(
"FIELD OF VIEW ", s_bDebugDrawFieldOfView);
927 if (s_bDebugDrawFieldOfView)
930 DbgUI.Combo(
"Field of view units ", s_eFieldOfViewUnit, units);
932 InputFloatClamped(s_fFieldOfViewUnit,
"Custom field of view unit deg", 0, 180);
934 InputFloatClamped(s_fFieldOfViewAngle,
"Field of view angle ", 0, 1000);
937 float unit = DebugAngleUnitsToDegrees(s_eFieldOfViewUnit, s_fFieldOfViewUnit);
939 DebugDrawFieldOfView(sightMat, s_fFieldOfViewAngle * unit);
945 UpdateCurrentFov(
true);
947 if (
m_Optic && s_bDebug2DOptics)
948 UpdateScale(1, 1, 1);
959 float reticleAngularSize = m_fReticleAngularSize * 0.01;
961 if (m_fReticleBaseZoom < 0)
962 reticleAngularSize *= m_fOpticCurrentFov / -m_fReticleBaseZoom;
963 else if (m_fReticleBaseZoom > 0)
964 reticleAngularSize *= m_fOpticCurrentFov /
m_Optic.CalculateZoomFOV(m_fReticleBaseZoom);
966 return reticleAngularSize;
971 float objectiveSize = m_fObjectiveFov * m_fObjectiveScale * 0.01;
973 if (m_fOpticBaseFov > 0)
974 objectiveSize *= m_fOpticCurrentFov / m_fOpticBaseFov;
976 return objectiveSize;
989 return Math.RAD2DEG * 0.001;
995 static void DebugDrawFieldOfView(vector sightMat[4],
float angle)
997 if (
float.AlmostEqual(angle, 0))
1001 float targetSize = Math.Tan(Math.DEG2RAD * angle * 0.5);
1003 CameraBase currentCamera =
GetGame().GetCameraManager().CurrentCamera();
1005 range = currentCamera.GetFarPlane() * 0.5;
1008 fovMat[0] = sightMat[0];
1009 fovMat[1] = sightMat[2];
1010 fovMat[2] = sightMat[1];
1011 fovMat[3] = sightMat[3] + sightMat[2] * range;
1013 SCR_Shape.DrawCircle(fovMat, targetSize * range, s_iLineColor, COLOR_YELLOW_A, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER | ShapeFlags.TRANSP | ShapeFlags.NOOUTLINE | ShapeFlags.NOZWRITE);
1017 protected void DebugDrawNotches(vector sightMat[4],
float length,
float spacing,
float size)
1019 if (
float.AlmostEqual(length, 0))
1022 if (
float.AlmostEqual(spacing, 0))
1025 vector opticSide = sightMat[0];
1026 vector opticUp = sightMat[1];
1027 vector opticDir = sightMat[2];
1028 vector opticPos = sightMat[3];
1031 int count = Math.Floor(size / spacing);
1032 float notchSpacing = Math.DEG2RAD * spacing;
1033 float notchHalf = Math.Tan(Math.DEG2RAD * length * 0.5);
1035 CameraBase currentCamera =
GetGame().GetCameraManager().CurrentCamera();
1037 range = currentCamera.GetFarPlane() * 0.5;
1039 vector zeroMat[4] = sightMat;
1040 zeroMat[3] = opticPos + opticDir * range;
1042 vector notchMat[4] = zeroMat;
1043 vector notchSide = opticSide * notchHalf * range;
1044 vector notchUp = opticUp * notchHalf * range;
1049 for (
int i; i < count; i++)
1051 SCR_Math3D.RotateAround(notchMat, opticPos, opticUp, -notchSpacing, notchMat);
1052 notch[0] = notchMat[3] + notchUp;
1053 notch[1] = notchMat[3] - notchUp;
1054 Shape.CreateLines(s_iLineColor, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, notch, 2);
1059 for (
int i; i < count; i++)
1061 SCR_Math3D.RotateAround(notchMat, opticPos, opticUp, notchSpacing, notchMat);
1062 notch[0] = notchMat[3] + notchUp;
1063 notch[1] = notchMat[3] - notchUp;
1064 Shape.CreateLines(s_iLineColor, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, notch, 2);
1069 for (
int i; i < count; i++)
1071 SCR_Math3D.RotateAround(notchMat, opticPos, opticSide, -notchSpacing, notchMat);
1072 notch[0] = notchMat[3] + notchSide;
1073 notch[1] = notchMat[3] - notchSide;
1074 Shape.CreateLines(s_iLineColor, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, notch, 2);
1079 for (
int i; i < count; i++)
1081 SCR_Math3D.RotateAround(notchMat, opticPos, opticSide, notchSpacing, notchMat);
1082 notch[0] = notchMat[3] + notchSide;
1083 notch[1] = notchMat[3] - notchSide;
1084 Shape.CreateLines(s_iLineColor, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, notch, 2);
1089 protected void DebugDrawCross(vector sightMat[4],
float radius)
1091 if (
float.AlmostEqual(radius, 0))
1094 vector opticSide = sightMat[0];
1095 vector opticUp = sightMat[1];
1096 vector opticDir = sightMat[2];
1097 vector opticPos = sightMat[3];
1100 float crossRadius = Math.Tan(Math.DEG2RAD * radius * 0.5);
1102 CameraBase currentCamera =
GetGame().GetCameraManager().CurrentCamera();
1104 range = currentCamera.GetFarPlane() * 0.5;
1106 vector crossPos = opticPos + opticDir * range;
1110 cross[0] = opticPos;
1111 cross[1] = crossPos;
1112 Shape.CreateLines(s_iLineColor, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, cross, 2);
1115 vector crossSide = opticSide * crossRadius * range;
1116 cross[0] = crossPos + crossSide;
1117 cross[1] = crossPos - crossSide;
1118 Shape.CreateLines(s_iLineColor, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, cross, 2);
1121 vector crossUp = opticUp * crossRadius * range;
1122 cross[0] = crossPos + crossUp;
1123 cross[1] = crossPos - crossUp;
1124 Shape.CreateLines(s_iLineColor, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, cross, 2);
1127 cross[0] = crossPos - crossUp - crossSide;
1128 cross[1] = crossPos + crossUp + crossSide;
1129 Shape.CreateLines(s_iLineColor, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, cross, 2);
1132 cross[0] = crossPos + crossUp - crossSide;
1133 cross[1] = crossPos - crossUp + crossSide;
1134 Shape.CreateLines(s_iLineColor, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, cross, 2);
1138 static void SetScope2DEnabled(
bool enabled)
1140 BaseContainer gameplaySettings =
GetGame().GetGameUserSettings().GetModule(
"SCR_GameplaySettings");
1141 if (gameplaySettings)
1142 gameplaySettings.Set(
"m_b2DScopes", enabled);