Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_2DPIPSightsComponent.c
Go to the documentation of this file.
1[EntityEditorProps(category: "GameScripted/Weapon/Sights", description: "", color: "0 0 255 255")]
3{
4 // PIP -----------------------------
5 [Attribute("{EF091399D840192D}UI/layouts/Sights/PictureInPictureSightsLayout.layout", UIWidgets.ResourcePickerThumbnail, "The layout used for the PIP component", params: "layout", category: "PiPSights")]
7
8 [Attribute("RTTexture0", UIWidgets.EditBox, "Name of RTTexture widget within provided layout\n", category: "PiPSights")]
9 protected string m_sRTTextureWidgetName;
10
11 [Attribute("RenderTarget0", UIWidgets.EditBox, "Name of RenderTarget widget within provided layout\n", category: "PiPSights")]
12 protected string m_sRTargetWidgetName;
13
14 [Attribute("8", UIWidgets.Slider, "Camera index used for this PIP component\n", params: "0 31 1", category: "PiPSights")]
15 protected int m_iCameraIndex;
16
17 [Attribute("0.2", UIWidgets.Slider, "Camera near clipping plane\n[m]", params: "0 1000 0.01", category: "PiPSights")]
18 protected float m_fNearPlane;
19
20 [Attribute("0", UIWidgets.Slider, "Camera far clipping plane. Set to zero to match maximum view distance\n[m]", params: "0 10000 1", category: "PiPSights")]
21 protected float m_fFarPlane;
22
23 // Point info?
24 [Attribute("1.0", UIWidgets.Slider, "Scale of resolution used by the PIP\n[x]", params: "0.1 1 0.1", category: "PiPSights")]
25 protected float m_fResolutionScale;
26
27 [Attribute("{972DF18CB9BFCBD4}Common/Postprocess/HDR_ScopePiP.emat", UIWidgets.EditBox, "HDR material resource\n", params: "emat", category: "PiPSights")]
29
30 // 0 = immediately when entering ADS camera, 1.0 = only after full blend
31 [Attribute("0.25", UIWidgets.Slider, "Percentage of camera transition at which sights activate\n[%]", params: "0.0 1.0 0.01", category: "PiPSights")]
32 protected float m_fADSActivationPercentagePIP;
33
34 // 0 = immediately when leaving ADS camera, 1.0 = only after full blend
35 [Attribute("0.75", UIWidgets.Slider, "Percentage of camera transition at which sights deactivate\n[%]", params: "0.0 1.0 0.01", category: "PiPSights")]
36 protected float m_fADSDeactivationPercentagePIP;
37
38 [Attribute("100", UIWidgets.Slider, "Vignette parallax angle scale, divided by objective FOV.\n[x]", params: "-1000 1000 0.1", category: "PiPSights-Parallax")]
39 protected float m_fVignetteParallaxScale;
40
41 [Attribute("0.014", UIWidgets.Slider, "Optimal distance from scope, where no parallax distant effect is present\n[m]", params: "-0.2 0.2 0.001", category: "PiPSights-Parallax")]
42 protected float m_fCenterDistance;
43
44 [Attribute("0.8", UIWidgets.Slider, "How the parallax is affected when the eye moves closer to scope\n[x]", params: "0 1 0.001", category: "PiPSights-Parallax")]
45 protected float m_fDistanceMoveNear;
46
47 [Attribute("0.4", UIWidgets.Slider, "How the parallax is affected when the eye moves farther from scope\n[x]", params: "0 1 0.001", category: "PiPSights-Parallax")]
48 protected float m_fDistanceMoveFar;
49
50 [Attribute("0.5", UIWidgets.Slider, "Basic value for simulating parallax effect\n", params: "0 2 0.001", category: "PiPSights-Parallax")]
51 protected float m_fBasicParallax;
52
53 [Attribute("1.75", UIWidgets.Slider, "Max parallax value for simulating parallax effect\nShould be bigger than BasicParallax\n", params: "0 2 0.001", category: "PiPSights-Parallax")]
54 protected float m_fMaxParallax;
55
56 [Attribute("0.0", UIWidgets.Slider, "Parallax axis offset in X\n[°]", params: "-90 90 0.001", category: "PiPSights-Parallax")]
57 protected float m_fCenterOffsetX;
58
59 [Attribute("0.0", UIWidgets.Slider, "Parallax axis offset in Y\n[°]", params: "-90 90 0.001", category: "PiPSights-Parallax")]
60 protected float m_fCenterOffsetY;
61
62 [Attribute("1.05", UIWidgets.Slider, "PIP reticle additional scale to compensate discrepancy between camera and reticle\n[x]", params: "0.01 10 0.00001", category: "PiPSights", precision: 5)]
63 protected float m_fReticlePIPScale;
64
65 [Attribute("0.98", UIWidgets.Slider, "PIP objective inner edge. Should be lower than max\n[x]", params: "0.001 10 0.00001", category: "PiPSights-Parallax", precision: 5)]
66 protected float m_fObjectivePIPEdgeMin;
67
68 [Attribute("1.00", UIWidgets.Slider, "PIP objective outer edge\n[x]", params: "0.001 10 0.00001", category: "PiPSights-Parallax", precision: 5)]
69 protected float m_fObjectivePIPEdgeMax;
70
71 [Attribute("0 0 0", UIWidgets.Slider, "Offset when not unfocused to improve view\n[m]", params: "-1 1 0.001", category: "PiPSights")]
72 protected vector m_vMainCameraOffsetUnfocused;
73
74 [Attribute("{5366CEDE2A151631}Terrains/Common/Water/UnderWater/oceanUnderwater.emat", UIWidgets.ResourcePickerThumbnail, "Underwater postprocess material\n", params: "emat", category: "PiPSights")]
76
77 [Attribute("{FA4DE95A7276143D}Common/Postprocess/rain.emat", UIWidgets.ResourcePickerThumbnail, "Rain postprocess material\n", params: "emat", category: "PiPSights")]
79
80 //------------------------------------------------------------------------------------------------
82 {
83 return m_iCameraIndex;
84 }
85
86 //------------------------------------------------------------------------------------------------
88 {
89 return m_fNearPlane;
90 }
91
92 //------------------------------------------------------------------------------------------------
94 {
95 return m_fFarPlane;
96 }
97
98 //------------------------------------------------------------------------------------------------
100 {
101 return m_fResolutionScale;
102 }
103
104 //------------------------------------------------------------------------------------------------
106 {
107 return m_fADSActivationPercentagePIP;
108 }
109
110 //------------------------------------------------------------------------------------------------
112 {
113 return m_fADSDeactivationPercentagePIP;
114 }
115
116 //------------------------------------------------------------------------------------------------
118 {
119 return m_fVignetteParallaxScale;
120 }
121
122 //------------------------------------------------------------------------------------------------
124 {
125 return m_fCenterDistance;
126 }
127
128 //------------------------------------------------------------------------------------------------
130 {
131 return m_fDistanceMoveNear;
132 }
133
134 //------------------------------------------------------------------------------------------------
136 {
137 return m_fDistanceMoveFar;
138 }
139
140 //------------------------------------------------------------------------------------------------
142 {
143 return m_fBasicParallax;
144 }
145
146 //------------------------------------------------------------------------------------------------
148 {
149 return m_fMaxParallax;
150 }
151
152 //------------------------------------------------------------------------------------------------
154 {
155 return m_fCenterOffsetX;
156 }
157
158 //------------------------------------------------------------------------------------------------
160 {
161 return m_fCenterOffsetY;
162 }
163
164 //------------------------------------------------------------------------------------------------
166 {
167 return m_fReticlePIPScale;
168 }
169
170 //------------------------------------------------------------------------------------------------
172 {
173 return m_fObjectivePIPEdgeMin;
174 }
175
176 //------------------------------------------------------------------------------------------------
178 {
179 return m_fObjectivePIPEdgeMax;
180 }
181
182 //------------------------------------------------------------------------------------------------
184 {
185 return m_vMainCameraOffsetUnfocused;
186 }
187
188 //------------------------------------------------------------------------------------------------
190 {
192 }
193
194 //------------------------------------------------------------------------------------------------
196 {
198 }
199
200 //------------------------------------------------------------------------------------------------
205
206 //------------------------------------------------------------------------------------------------
211
212 //------------------------------------------------------------------------------------------------
217
218 //------------------------------------------------------------------------------------------------
223
224#ifdef ENABLE_DIAG
225 //------------------------------------------------------------------------------------------------
226 void DrawSharedDataDiag()
227 {
228 SCR_2DPIPSightsComponent.InputFloatClamped(m_fCenterDistance, "m_fCenterDistance", -0.2, 0.2);
229 SCR_2DPIPSightsComponent.InputFloatClamped(m_fDistanceMoveNear, "m_fDistanceMoveNear", 0.0, 1.0);
230 SCR_2DPIPSightsComponent.InputFloatClamped(m_fDistanceMoveFar, "m_fDistanceMoveFar", 0.0, 1.0);
231 SCR_2DPIPSightsComponent.InputFloatClamped(m_fBasicParallax, "m_fBasicParallax", 0.0, 2.0);
232 SCR_2DPIPSightsComponent.InputFloatClamped(m_fMaxParallax, "m_fMaxParallax", 0.0, 2.0);
233 SCR_2DPIPSightsComponent.InputFloatClamped(m_fCenterOffsetX, "m_fCenterOffsetX", -90.0, 90.0);
234 SCR_2DPIPSightsComponent.InputFloatClamped(m_fCenterOffsetY, "m_fCenterOffsetY", -90.0, 90.0);
235 SCR_2DPIPSightsComponent.InputFloatClamped(m_fReticlePIPScale, "m_fReticlePIPScale", 0.01, 100.0);
236 SCR_2DPIPSightsComponent.InputFloatClamped(m_fObjectivePIPEdgeMin, "m_fObjectivePIPEdgeMin", 0.0, 10.0);
237 SCR_2DPIPSightsComponent.InputFloatClamped(m_fObjectivePIPEdgeMax, "m_fObjectivePIPEdgeMax", 0.0, 10.0);
238 SCR_2DPIPSightsComponent.InputFloatClamped(m_fVignetteParallaxScale, "m_fVignetteParallaxScale", -100.0, 100.0);
239 }
240#endif
241}
242
244enum SCR_EPIPZeroingType
245{
248 EPZ_CAMERA_TURN = 2
249}
250
251//------------------------------------------------------------------------------------------------
252class SCR_2DPIPSightsComponent : SCR_2DSightsComponent
253{
254 [Attribute("0.01", UIWidgets.Slider, "Radius of PIP scope ocular\n[m]", params: "0.001 1 0.0001", category: "PiPSights", precision: 5)]
255 protected float m_fScopeRadius;
256
257 [Attribute("21", UIWidgets.Slider, "Camera field of view used by this PIP component. Determines LOD used. Set to 0 to use Focus FOV.\n[°]", params: "0 89.99 0.01", category: "PiPSights")]
258 protected float m_fMainCameraFOV;
259
260 // 2D -----------------------------
262 protected bool m_b2DIsEnabled;
263
264 protected int m_iLastProjectionFrame = -1;
265 protected vector m_vScreenScopeCenter;
266 protected float m_fScreenScopeRadiusSq;
267 protected float m_fScreenScopeRadius;
268 protected float m_fReticleScale;
269 protected float m_fEdgeScale = 1;
270 protected float m_fParallaxX;
271 protected float m_fParallaxY;
272
273 protected IEntity m_ControlledEntity;
274
276 protected ref Color m_cReticleColor;
277
283 bool IsScreenPositionInSights(vector screenPosition)
284 {
285 if (!m_PIPCamera || !IsSightADSActive()) // With no active camera or disabled sights, the point is never in PIP
286 return false;
287
288 BaseWorld world = GetGame().GetWorld();
289 int index = world.GetFrameNumber();
290
291 // Recalculate the projection data only once per frame, so we save some perf on huge queries
292 if (m_iLastProjectionFrame != index)
293 {
294 WorkspaceWidget workspaceWidget = GetGame().GetWorkspace();
295
296 vector sightsRear = GetSightsRearPosition();
297 m_vScreenScopeCenter = workspaceWidget.ProjWorldToScreen(sightsRear, world);
298 m_vScreenScopeCenter[2] = 0.0;
299
300 vector extent = workspaceWidget.ProjWorldToScreen(sightsRear + GetOwner().GetWorldTransformAxis(0) * m_fScopeRadius, world);
301 extent[2] = 0.0;
302
303 const float invSqrt2 = 0.70710678118; // 1.0 / Math.Sqrt(2.0);
304 m_fScreenScopeRadiusSq = invSqrt2 * vector.DistanceSq(extent, m_vScreenScopeCenter);
305 m_iLastProjectionFrame = index;
306 }
307
308 float screenDistanceSq = vector.DistanceSq(screenPosition, m_vScreenScopeCenter);
309 return screenDistanceSq < m_fScreenScopeRadiusSq;
310 }
311
312 //------------------------------------------------------------------------------------------------
314 //------------------------------------------------------------------------------------------------
315 float GetSightsRadiusScreen()
316 {
317 BaseWorld world = GetGame().GetWorld();
318
319 WorkspaceWidget workspaceWidget = GetGame().GetWorkspace();
320
321 vector sightsRear = GetSightsRearPosition();
322 vector scopeScreenCenter = workspaceWidget.ProjWorldToScreen(sightsRear, world);
323 scopeScreenCenter[2] = 0;
324
325 vector extent = workspaceWidget.ProjWorldToScreen(sightsRear + GetOwner().GetWorldTransformAxis(0) * m_fScopeRadius, world);
326 extent[2] = 0;
327
328 m_fScreenScopeRadius = vector.Distance(extent, scopeScreenCenter);
329
330 return m_fScreenScopeRadius;
331 }
332
334 protected ref Widget m_wPIPRoot;
335
337 protected bool m_bPIPIsEnabled;
338 protected static int s_bIsPIPActive;
339
341 protected RTTextureWidget m_wRenderTargetTextureWidget;
342
344 protected RenderTargetWidget m_wRenderTargetWidget;
345
347 protected SCR_PIPCamera m_PIPCamera;
348
349 ref Material m_pMaterial;
350 int m_iVignetteCenterXIndex = -1;
351 int m_iVignetteCenterYIndex = -1;
352 int m_iVignettePowerIndex = -1;
353 int m_iLensDistortIndex = -1;
354 int m_iReticleOffsetXIndex = -1;
355 int m_iReticleOffsetYIndex = -1;
356 int m_iReticleColorIndex = -1;
357 int m_iReticleScaleIndex = -1;
358 int m_iEdgeMinIndex = -1;
359 int m_iEdgeMaxIndex = -1;
360 int m_iEdgeCenterXIndex = -1;
361 int m_iEdgeCenterYIndex = -1;
362
363 //------------------------------------------------------------------------------------------------
367 SCR_PIPCamera GetPIPCamera()
368 {
369 return m_PIPCamera;
370 }
371
372 //------------------------------------------------------------------------------------------------
376 int GetPIPCameraIndex()
377 {
378 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(GetOwner()));
379 if (data)
380 return data.GetCameraIndex();
381
382 return 8; // 8 as it is the default value for m_iCameraIndex so it might be fairly safe as a default fallback option
383 }
384
385 //------------------------------------------------------------------------------------------------
386 override float GetADSActivationPercentageScript()
387 {
388 if (SCR_Global.IsScope2DEnabled())
389 return super.GetADSActivationPercentageScript();
390
391 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(GetOwner()));
392 if (!data)
393 return 1;
394
395 return data.GetADSActivationPercentagePIP();
396 }
397
398 //------------------------------------------------------------------------------------------------
400 {
401 if (SCR_Global.IsScope2DEnabled())
402 return super.GetADSDeactivationPercentageScript();
403
404 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(GetOwner()));
405 if (!data)
406 return 0;
407
408 return data.GetADSDeactivationPercentagePIP();
409 }
410
411 //------------------------------------------------------------------------------------------------
412 bool IsPIPEnabled()
413 {
414 return m_bPIPIsEnabled;
415 }
416
417 //------------------------------------------------------------------------------------------------
421 static bool IsPIPActive()
422 {
423 return s_bIsPIPActive;
424 }
425
426 //------------------------------------------------------------------------------------------------
427 float GetMainCameraFOV()
428 {
429 if (SCR_Global.IsScope2DEnabled())
430 return GetFOV();
431
432 if (m_fMainCameraFOV <= 0)
433 m_fMainCameraFOV = CalculateZoomFOV(1);
434
435 return GetFocusFOV();
436 }
437
438 //------------------------------------------------------------------------------------------------
439 protected float GetFocusFOV()
440 {
441 CameraManager cameraManager = GetGame().GetCameraManager();
442 if (!cameraManager)
443 return m_fMainCameraFOV;
444
445 PlayerCamera camera = PlayerCamera.Cast(cameraManager.CurrentCamera());
446 if (camera)
447 return Math.Lerp(cameraManager.GetFirstPersonFOV(), m_fMainCameraFOV, camera.GetFocusMode());
448
449 return m_fMainCameraFOV;
450 }
451
452 //------------------------------------------------------------------------------------------------
453 vector GetMainCameraOffset()
454 {
455 CameraManager cameraManager = GetGame().GetCameraManager();
456 if (!cameraManager)
457 return vector.Zero;
458
459 PlayerCamera camera = PlayerCamera.Cast(cameraManager.CurrentCamera());
460 if (camera)
461 {
462 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(GetOwner()));
463 if (!data)
464 return vector.Zero;
465
466 return vector.Lerp(data.GetMainCameraOffsetUnfocused(), vector.Zero, camera.GetFocusMode());
467 }
468
469 return vector.Zero;
470 }
471
472 //------------------------------------------------------------------------------------------------
473 protected bool IsLocalControlledEntity(IEntity pEntity, bool checkHierarchy = true)
474 {
475 m_ControlledEntity = null;
476
477 if (!pEntity)
478 return false;
479
480 // We make sure that we only perform any local items on our local controlled entity
481 IEntity controlledEntity = SCR_PlayerController.GetLocalControlledEntity();
482 if (!controlledEntity)
483 return false;
484
485 // Straight hit
486 if (controlledEntity == pEntity)
487 {
488 m_ControlledEntity = controlledEntity;
489 return true;
490 }
491
492 // Common hierarchy means common root
493 if (checkHierarchy && controlledEntity.GetRootParent() == pEntity.GetRootParent())
494 {
495 m_ControlledEntity = controlledEntity;
496 return true;
497 }
498
499 return false;
500 }
501
502 //------------------------------------------------------------------------------------------------
509 protected CameraBase CreateCamera(IEntity parent, vector position, vector angles, int cameraIndex, float fov, float nearPlane, float farPlane)
510 {
511 // Limit camera's far distance to game's settings.
512 farPlane = GetMaxViewDistance(farPlane);
513
514 // Spawn camera
515 BaseWorld baseWorld = parent.GetWorld();
516
517 // Spawn it close
519 parent.GetWorldTransform(params.Transform);
520 SCR_PIPCamera pipCamera = SCR_PIPCamera.Cast(GetGame().SpawnEntity(SCR_PIPCamera, baseWorld, params));
521
522 vector mat[4];
523 parent = GetCameraLocalTransform(mat);
524
525 pipCamera.SetCameraIndex(cameraIndex);
526 pipCamera.SetVerticalFOV(fov);
527 pipCamera.SetNearPlane(nearPlane);
528 pipCamera.SetFarPlane(farPlane);
529 pipCamera.ApplyProps(cameraIndex);
530 baseWorld.SetCameraLensFlareSet(cameraIndex, CameraLensFlareSetType.FirstPerson, string.Empty);
531
532 // Set camera to hierarchy
533 parent.AddChild(pipCamera, -1, EAddChildFlags.AUTO_TRANSFORM);
534 pipCamera.SetLocalTransform(mat);
535 pipCamera.UpdatePIPCamera(1.0);
536 return pipCamera;
537 }
538
539 //------------------------------------------------------------------------------------------------
540 protected Widget CreateUI(string layout, string rtTextureName, string rtName, out RTTextureWidget RTTexture, out RenderTargetWidget RTWidget)
541 {
542 // Empty layout, cannot create any widget
543 if (layout == string.Empty)
544 return null;
545
546 // Create layout
547 Widget root = GetGame().GetWorkspace().CreateWidgets(layout);
548
549 // Layout was not created successfully
550 if (!root)
551 return null;
552
553 // We dont have required RT widgets, delete layout and terminate
554 RTTexture = RTTextureWidget.Cast(root.FindAnyWidget(rtTextureName));
555 RTWidget = RenderTargetWidget.Cast(root.FindAnyWidget(rtName));
556 if (!RTTexture || !RTWidget)
557 {
558 root.RemoveFromHierarchy();
559 return null;
560 }
561
562 return root;
563 }
564
565 //------------------------------------------------------------------------------------------------
566 void SetPIPEnabled(bool enabled)
567 {
568 // disabled->enabled
569 // Create neccessary items
570 if (enabled && !m_bPIPIsEnabled)
571 {
572 IEntity owner = GetOwner();
573 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(owner));
574 if (!data)
575 return;
576
577 // Try to create UI for PIP,
578 // output params are either set to valid ones,
579 // or root itself is set to null and destroyed
580 if (!m_wPIPRoot || !m_wRenderTargetTextureWidget || !m_wRenderTargetWidget)
581 m_wPIPRoot = CreateUI(data.GetPIPLayoutResource(), data.GetRTTextureWidgetName(), data.GetRTargetWidgetName(), m_wRenderTargetTextureWidget, m_wRenderTargetWidget);
582
583 if (!m_wPIPRoot)
584 {
585 Print("Could not create PIP layouts!", LogLevel.ERROR);
586 return;
587 }
588
589 // Create PIP camera
590 if (!m_PIPCamera)
591 {
592 // TODO: restart camera when view distance changes
593 float viewDistance = GetGame().GetViewDistance();
594 float farPlane = data.GetFarPlane();
595 if (farPlane > 0)
596 viewDistance = Math.Min(viewDistance, farPlane);
597
598 m_PIPCamera = SCR_PIPCamera.Cast(CreateCamera(owner, GetSightsFrontPosition(true) + data.GetCameraOffset(), data.GetCameraAngles(), data.GetCameraIndex(), GetFOV(), data.GetNearPlane(), viewDistance));
599 }
600
601 if (!m_PIPCamera)
602 {
603 Print("Could not create PIP camera!", LogLevel.ERROR);
604 return;
605 }
606
607 // Now that everything is ready, we can start observing possible changes of the game settings, so we can react to them
608 SCR_MenuHelper.GetOnMenuClose().Insert(OnSettingsMenuClosed);
609
610 const int cameraIndex = data.GetCameraIndex();
611 // Set camera index of render target widget
612 BaseWorld baseWorld = owner.GetWorld();
613 m_wRenderTargetWidget.SetWorld(baseWorld, cameraIndex);
614
615 float resolutionScale = data.GetResolutionScale();
616 // Set resolution scale
617 m_wRenderTargetWidget.SetResolutionScale(resolutionScale, resolutionScale);
618
619 if (!owner.IsDeleted())
620 m_wRenderTargetTextureWidget.SetRenderTarget(owner);
621
622 if (m_pMaterial)
623 GetGame().GetWorld().SetCameraPostProcessEffect(cameraIndex, 10, PostProcessEffectType.HDR, data.GetScopeHDRMaterial());
624
625 string material = data.GetUnderwaterPPMaterial();
626 if (!material.IsEmpty())
627 GetGame().GetWorld().SetCameraPostProcessEffect(cameraIndex, 2, PostProcessEffectType.UnderWater, material);
628
629 material = data.GetRainPPMaterial();
630 if (!material.IsEmpty())
631 GetGame().GetWorld().SetCameraPostProcessEffect(cameraIndex, 4, PostProcessEffectType.Rain, material);
632
633 s_bIsPIPActive = true;
634 m_bPIPIsEnabled = true;
635 return;
636 }
637
638 // enabled -> disabled
639 if (!enabled && m_bPIPIsEnabled)
640 {
641 Destroy();
642 s_bIsPIPActive = false;
643 m_bPIPIsEnabled = false;
644 return;
645 }
646 }
647
648 //------------------------------------------------------------------------------------------------
649 protected void DestroyCamera(CameraBase camera)
650 {
651 if (!camera)
652 return;
653
654 IEntity cameraParent = camera.GetParent();
655 if (cameraParent)
656 cameraParent.RemoveChild(camera);
657
658 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(GetOwner()));
659 if (data)
660 {
661 const int cameraIndex = data.GetCameraIndex();
662 camera.GetWorld().SetCameraPostProcessEffect(cameraIndex, 10, PostProcessEffectType.HDR, string.Empty);
663 camera.GetWorld().SetCameraPostProcessEffect(cameraIndex, 2, PostProcessEffectType.UnderWater, string.Empty);
664 camera.GetWorld().SetCameraLensFlareSet(cameraIndex, CameraLensFlareSetType.None, string.Empty);
665 }
666
667 delete camera;
668 }
669
670 //------------------------------------------------------------------------------------------------
674 protected float GetMaxViewDistance(float desiredDistance)
675 {
676 // Min view distance value allowed by the project
677 float absoluteMax = GetGame().GetMaximumViewDistance();
678 // Max view distance value allowed by the project
679 float absoluteMin = GetGame().GetMinimumViewDistance();
680 // Limit camera's far distance to game's settings.
681 float serverMax = GetGame().GetViewDistanceServerLimit();
682
683 // Max view distance is enforced by server, then consider that while clamping.
684 if (serverMax > 0)
685 return Math.Clamp(desiredDistance, absoluteMin, Math.Min(serverMax, absoluteMax));
686
687 return Math.Clamp(desiredDistance, absoluteMin, absoluteMax);
688 }
689
690 //------------------------------------------------------------------------------------------------
693 protected void OnSettingsMenuClosed(ChimeraMenuBase menu)
694 {
695 if (!SCR_SettingsSuperMenu.Cast(menu))
696 return;
697
698 if (!m_PIPCamera)
699 return;
700
701 float maxViewDistance = GetMaxViewDistance(GetGame().GetViewDistance());
702 if (m_PIPCamera.GetFarPlane() != maxViewDistance)
703 m_PIPCamera.SetFarPlane(maxViewDistance);
704 }
705
706 //------------------------------------------------------------------------------------------------
707 // Destroy everything this component created during its lifetime
708 protected void Destroy()
709 {
710 IEntity owner = GetOwner();
711 if (m_wRenderTargetTextureWidget && owner && !owner.IsDeleted())
712 m_wRenderTargetTextureWidget.RemoveRenderTarget(owner);
713
714 if (m_wPIPRoot)
715 {
716 m_wPIPRoot.RemoveFromHierarchy();
717 m_wPIPRoot = null;
718 }
719
720 SCR_MenuHelper.GetOnMenuClose().Remove(OnSettingsMenuClosed);
721 DestroyCamera(m_PIPCamera);
722 }
723
724 //------------------------------------------------------------------------------------------------
726 protected override void EnableReticleIllumination(bool enable)
727 {
728 SCR_2DOpticsComponentClass data = SCR_2DOpticsComponentClass.Cast(GetComponentData(GetOwner()));
729 if (!data)
730 return;
731
732 super.EnableReticleIllumination(enable);
733
734 if (data.HasIllumination() && enable)
735 m_cReticleColor = data.GetReticleIlluminationColor();
736 else
737 m_cReticleColor = data.GetReticleColor();
738 }
739
740 //------------------------------------------------------------------------------------------------
741 protected override void HandleSightActivation()
742 {
743 // A component without an owner shouldnt exist
744 IEntity owner = GetOwner();
745 if (!owner)
746 return;
747
748 // We make sure that we only perform any local items on our local controlled entity
749 if (!IsLocalControlledEntity(owner))
750 return;
751
752 SCR_2DOpticsComponentClass data = SCR_2DOpticsComponentClass.Cast(GetComponentData(owner));
753 if (!data)
754 return;
755
756 // Set fov TODO@AS: Copied from base?
757 if (!m_SightsFovInfo)
758 {
759 m_SightsFovInfo = SCR_SightsZoomFOVInfo.Cast(GetFOVInfo());
760 SetupFovInfo();
761 }
762
763 // Initialize to current zero value
764 m_fCurrentReticleOffsetY = GetReticleOffsetYTarget();
765
766 bool scope2d = SCR_Global.IsScope2DEnabled();
767 if (!scope2d)
768 {
769 SetPIPEnabled(true);
770
771 if (m_pMaterial)
772 UpdateScopeMaterial();
773
774 // Setup illumination
775 if (data.HasIllumination())
776 EnableReticleIllumination(m_bIsIlluminationOn);
777 }
778
779 s_OnSightsADSChanged.Invoke(true, m_fMainCameraFOV);
780
781 if (scope2d)
782 {
783 if (m_bPIPIsEnabled)
784 SetPIPEnabled(false);
785
786 m_b2DIsEnabled = true;
787 }
788 else if (!scope2d && m_b2DIsEnabled)
789 {
790 m_b2DIsEnabled = false;
791 }
792
793 if (m_b2DIsEnabled)
794 super.HandleSightActivation();
795 else
796 super.HandleSightDeactivation();
797 }
798
799 //------------------------------------------------------------------------------------------------
800 protected override void HandleSightDeactivation()
801 {
802 // A component without an owner shouldnt exist
803 IEntity owner = GetOwner();
804 if (!owner)
805 return;
806
807 if (!m_ControlledEntity)
808 {
809 if (IsPIPEnabled())
810 {
811 // Make sure to revert overlay camera to default
812 if (m_PIPCamera)
813 {
814 auto camMgr = GetGame().GetCameraManager();
815 if (camMgr && camMgr.GetOverlayCamera() == m_PIPCamera)
816 camMgr.SetOverlayCamera(null);
817 }
818
819 SetPIPEnabled(false);
820 }
821
822 return;
823 }
824
825 s_OnSightsADSChanged.Invoke(false, 0);
826
827 bool scope2d = SCR_Global.IsScope2DEnabled();
828 if (scope2d)
829 {
830 super.HandleSightDeactivation();
831 m_b2DIsEnabled = false;
832 }
833 else
834 {
835 SetPIPEnabled(false);
836 }
837 }
838
839 //------------------------------------------------------------------------------------------------
840 void UpdateCamera(float timeSlice)
841 {
842 if (!m_PIPCamera)
843 return;
844
845 if (m_fScopeRadius <= 0)
846 return;
847
848 // Compute FOV scale based on radius of the scope
849 CameraManager cameraManager = GetGame().GetCameraManager();
850 if (!cameraManager)
851 return;
852
853 CameraBase mainCamera = cameraManager.CurrentCamera();
854 if (!mainCamera)
855 return;
856
857 // Get camera to sight matrix
858 vector cameraToSightMat[4];
859 SCR_EntityHelper.GetRelativeLocalTransform(GetOwner(), mainCamera, cameraToSightMat);
860 vector localCameraPosition = cameraToSightMat[3]; // Camera's position in sight local space
861
862 vector pipSurfaceCenter = GetSightsRearPosition(true);
863 float distance = vector.Distance(pipSurfaceCenter, localCameraPosition);
864 if (distance == 0)
865 return;
866
867 // Get base FOV for camera, zoom levels can vary
868 float fov;
869 SightsFOVInfo fovInfo = GetFOVInfo();
870 if (fovInfo)
871 {
872 fov = fovInfo.GetFOV();
873 SCR_CharacterCameraHandlerComponent.SetOverlayCameraFOV(fov);
874 }
875 else
876 {
877 fov = mainCamera.GetVerticalFOV();
878 }
879
880 // Account for distance of camera to scope and its diameter
881 float scopeSize = Math.Atan2(m_fScopeRadius * 2, distance) * Math.RAD2DEG;
882 // PIPCQB Account for focus
883 float screenPortion = scopeSize / m_fMainCameraFOV;
884
885 float currentFOV = m_PIPCamera.GetVerticalFOV();
886 bool fovChanged = !float.AlmostEqual(fov * screenPortion, currentFOV, currentFOV * 0.005);
887
888 // Smooth adjustment for variable FOV sights
889 SCR_BaseVariableSightsFOVInfo variableSights = SCR_BaseVariableSightsFOVInfo.Cast(fovInfo);
890 if (variableSights && !fovChanged)
891 fovChanged = variableSights.IsAdjusting();
892
893 if (fovChanged)
894 {
895 m_PIPCamera.SetVerticalFOV(fov * screenPortion);
896
897 // Adjust objective edge field of view
898 if (variableSights)
899 m_fEdgeScale = fov / variableSights.GetBaseFOV();
900 }
901
902 if (fovChanged && m_fReticleAngularSize != 0)
903 {
904 // Compute reticle base FOV once to be scaled with screenPortion
905 if (m_fReticleBaseZoom > 0)
906 m_fReticleBaseZoom = -CalculateZoomFOV(m_fReticleBaseZoom);
907
908 float fovReticle;
909 if (m_fReticleBaseZoom == 0)
910 fovReticle = fov;
911 else if (m_fReticleBaseZoom < 0)
912 fovReticle = -m_fReticleBaseZoom;
913
914 if (fovReticle > 0)
915 m_fReticleScale = fovReticle * screenPortion * m_fReticlePortion / m_fReticleAngularSize;
916 }
917
918 // Get local tm in relation to actual parent
919 vector mat[4];
920 GetCameraLocalTransform(mat);
921
922 // Compute direction to center of ocular
923 // Based on eye position to avoid constant errors in case of inaccurate placement of rear sight and eye position
924 vector sightsTransform[4];
925 GetSightsTransform(sightsTransform, true);
926
927 vector parallaxPoint = sightsTransform[3] + sightsTransform[2] * distance;
928 vector parallaxDirection = (parallaxPoint - localCameraPosition).Normalized();
929 vector angles = SCR_Math3D.FixEulerVector180(parallaxDirection.VectorToAngles());
930
931 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(GetOwner()));
932 if (data)
933 angles += Vector(data.GetCenterOffsetX(), data.GetCenterOffsetY(), 0); // Parallax offset
934
935 // Scale parallax angle with apparent FOV
936 angles *= fov / m_fMainCameraFOV;
937
938 // Limit angles again after they are scaled with parallax
939 angles = SCR_Math3D.FixEulerVector180(angles);
940
941 // modify camera, reticle and objective with the same angles
942 m_fParallaxX = -angles[0];
943 m_fParallaxY = angles[1];
944
945 // Modify camera with same angles as reticle
946 vector parallax[4];
947 Math3D.AnglesToMatrix(angles, parallax);
948 Math3D.MatrixMultiply3(mat, parallax, mat);
949
950 // Apply zero angles to default rot
951 m_PIPCamera.SetLocalTransform(mat);
952
953 // Finally update camera props
954 m_PIPCamera.ApplyTransform(timeSlice);
955 }
956
957 //------------------------------------------------------------------------------------------------
958 void UpdateHDR()
959 {
960 int mainCameraIndex = 0;
961 CameraManager manager = GetGame().GetCameraManager();
962 if (manager)
963 {
964 CameraBase cam = manager.CurrentCamera();
965 if (cam)
966 mainCameraIndex = cam.GetCameraIndex();
967 }
968
969 IEntity owner = GetOwner();
970 //don't forget to disable preexposure on scope material !
971 BaseWorld world = owner.GetWorld();
972 float hdrBrightness = world.GetCameraHDRBrightness(mainCameraIndex);
973
974 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(owner));
975 if (data)
976 world.SetCameraHDRBrightness(data.GetCameraIndex(), hdrBrightness);
977 }
978
979 //------------------------------------------------------------------------------------------------
980 void UpdateScopeMaterial()
981 {
982 CameraManager cameraManager = GetGame().GetCameraManager();
983 if (!cameraManager)
984 return;
985
986 ChimeraCharacter character = ChimeraCharacter.Cast(SCR_PlayerController.GetLocalControlledEntity());
987 if (!character)
988 return;
989
990 CharacterControllerComponent controller = character.GetCharacterController();
991 if (!controller)
992 return;
993
994 BaseWeaponManagerComponent weaponManager = controller.GetWeaponManagerComponent();
995 if (!weaponManager)
996 return;
997
998 CameraBase mainCamera = cameraManager.CurrentCamera();
999 if (!mainCamera)
1000 return;
1001
1002 //main camera matrix in local coordinates
1003 vector mainCam[4];
1004 mainCamera.GetLocalTransform(mainCam);
1005
1006 //sights matrix in local coordinates
1007 vector sightsLSCam[4];
1008 float fov;
1009
1010 // if there is no sight, do not continue
1011 if (!weaponManager.GetCurrentSightsCameraTransform(sightsLSCam, fov))
1012 return;
1013
1014 //position of scope in main camera space
1015 vector scopePosCam = sightsLSCam[3] - mainCam[3];
1016
1017 //vectors
1018 vector scopeFwd = sightsLSCam[2];//m_pOwner.GetWorldTransformAxis(2);
1019 vector camFwd = mainCam[2];//m_PIPCamera.GetWorldTransformAxis(2);
1020
1021 //Print(scopeFwd);
1022 //Print(camFwd);
1023
1024 //project to reticle plane at scopePosCam, plane = n*P + d = 0 -> scopeFwd dot scopePosLS + d = 0
1025 //ray = C + s*t = camPos + camFwd*t
1026 // t = (n*P - n*C) / (n*s)
1027 //camPos is zero in this case
1028 float ns = vector.Dot(camFwd, scopeFwd);
1029 float nP = vector.Dot(scopePosCam, scopeFwd);
1030
1031 float t = nP/ns;
1032 vector projP = camFwd*t;
1033
1034 vector locPos = scopePosCam - projP;
1035
1036 //final move of vignette
1037 // float centerX = locPos[0]*m_fProjectionDifferenceScale + m_fCenterOffsetX;
1038 // float centerY = locPos[1]*m_fProjectionDifferenceScale + m_fCenterOffsetY;
1039
1040 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(GetOwner()));
1041 if (!data)
1042 return;
1043
1044 //distance from center distance - base of the eye pos from the projection plane
1045 //TODO: t is for ARTII weapon negative !
1046 float distance = Math.AbsFloat(t) - data.GetCenterDistance();
1047
1048 //change some material setting based on parameters
1049 float vignettePower = 0;
1050 //float lensPower = 0;
1051
1052 //bigger power = much faster change with distance
1053 float distancePower;
1054 if (distance > 0)
1055 {
1056 //when we are farther to scope
1057 distancePower = data.GetDistanceMoveFar();
1058 }
1059 else
1060 {
1061 //when we are closer to scope
1062 distancePower = data.GetDistanceMoveNear();
1063 //lensPower = -5.5;
1064 }
1065
1066 //stronger at beginning then slower -> some power function, log2 as Math from some reason doesn't contain power function
1067 float fc = 1 - 1 /(Math.Log2(distancePower*Math.AbsFloat(distance) + 2));
1068
1069 //max vignette power is 2, let a little opened
1070 vignettePower = Math.Clamp(fc* 100, data.GetBasicParallax(), data.GetMaxParallax());
1071
1072 //how is it with lens distortion? now at zero is the -5.5
1073 //lensPower = lensPower*Math.Clamp(-distance/m_fCenterDistance, 0, 5);
1074
1075
1076 //modify vignete power also by distance from scope center
1077 //locPos[2] = 0;
1078 //const float ProjectionCenterDistanceModif = 140.0;
1079 //vignettePower += locPos.Length()*ProjectionCenterDistanceModif;
1080
1081 //Print(centerX);
1082 //Print(centerY);
1083 //Print(vignettePower);
1084
1085 //centerX = Math.Clamp(centerX, -4, 4);
1086 //centerY = Math.Clamp(centerY, -4, 4);
1087
1088 // All effects are relative to actual FOV of the PIP surface
1089 float pipFOV = m_PIPCamera.GetVerticalFOV();
1090
1091 // Vignette
1092 float vignetteParallaxScale;
1093 if (m_fObjectiveFov > 0)
1094 vignetteParallaxScale = data.GetVignetteParallaxScale() / (m_fObjectiveFov * m_fObjectiveScale);
1095
1096 m_pMaterial.SetParamByIndex(m_iVignetteCenterXIndex, -m_fParallaxX * vignetteParallaxScale / pipFOV);
1097 m_pMaterial.SetParamByIndex(m_iVignetteCenterYIndex, -m_fParallaxY * vignetteParallaxScale / pipFOV);
1098 m_pMaterial.SetParamByIndex(m_iVignettePowerIndex, vignettePower);
1099
1100 float reticlePIPScale = data.GetReticlePIPScale();
1101 // Objective edge
1102 m_pMaterial.SetParamByIndex(m_iEdgeCenterXIndex, m_fParallaxX * reticlePIPScale / pipFOV);
1103 m_pMaterial.SetParamByIndex(m_iEdgeCenterYIndex, m_fParallaxY * reticlePIPScale / pipFOV);
1104 float edgeSize = m_fObjectiveFov * m_fObjectiveScale * m_fEdgeScale / pipFOV;
1105 m_pMaterial.SetParamByIndex(m_iEdgeMinIndex, 0.5 * reticlePIPScale * edgeSize * edgeSize * data.GetObjectivePIPEdgeMin());
1106 m_pMaterial.SetParamByIndex(m_iEdgeMaxIndex, 0.5 * reticlePIPScale * edgeSize * edgeSize * data.GetObjectivePIPEdgeMax());
1107
1108 // Reticle
1109 m_pMaterial.SetParamByIndex(m_iReticleScaleIndex, m_fReticleScale / reticlePIPScale);
1110 m_pMaterial.SetParamByIndex(m_iReticleOffsetXIndex, m_fReticleScale * (m_fParallaxX + m_fReticleOffsetX) / pipFOV);
1111 m_pMaterial.SetParamByIndex(m_iReticleOffsetYIndex, m_fReticleScale * (m_fParallaxY + m_fCurrentReticleOffsetY) / pipFOV);
1112
1113 // Reticle color
1114 float reticleRGBA[4] = {m_cReticleColor.R(), m_cReticleColor.G(), m_cReticleColor.B(), m_cReticleColor.A()};
1115 m_pMaterial.SetParamByIndex(m_iReticleColorIndex, reticleRGBA);
1116
1117 //m_pMaterial.SetParamByIndex(m_iLensDistortIndex, lensPower); // disabled for now, set in material directly
1118 }
1119
1120
1121 //------------------------------------------------------------------------------------------------
1122 protected override void OnSightADSPostFrame(IEntity owner, float timeSlice)
1123 {
1124 super.OnSightADSPostFrame(owner, timeSlice);
1125
1126
1127 // Before any updates make sure that we are in target state
1128 bool use2D = SCR_Global.IsScope2DEnabled();
1129 if ((m_bPIPIsEnabled && use2D) || (!m_bPIPIsEnabled && !use2D))
1130 {
1131 // Reactivate on change
1134 }
1135
1136 if (m_bPIPIsEnabled)
1137 {
1138 UpdateCamera(timeSlice);
1139 UpdateHDR();
1140
1141 if (m_pMaterial && m_PIPCamera)
1142 UpdateScopeMaterial();
1143 }
1144
1145 #ifdef ENABLE_DIAG
1146 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_WEAPONS_PIP_SIGHTS))
1147 DrawDiagWindow();
1148 #endif
1149 }
1150
1151 //------------------------------------------------------------------------------------------------
1152 protected override void OnInit(IEntity owner)
1153 {
1154 super.OnInit(owner);
1155
1156 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(owner));
1157 if (!data)
1158 return;
1159
1160 m_cReticleColor = data.GetReticleColor();
1161
1162 ResourceName mat = data.GetScopeHDRMaterial();
1163 if (mat.IsEmpty())
1164 Print("Scope HDR material is empty!", LogLevel.WARNING);
1165
1166 m_pMaterial = Material.GetOrLoadMaterial(mat, 0);
1167
1168 if (m_pMaterial)
1169 {
1170 m_iVignetteCenterXIndex = m_pMaterial.GetParamIndex("VignetteCenterX");
1171 m_iVignetteCenterYIndex = m_pMaterial.GetParamIndex("VignetteCenterY");
1172 m_iVignettePowerIndex = m_pMaterial.GetParamIndex("Vignette");
1173 m_iLensDistortIndex = m_pMaterial.GetParamIndex("LensDistort");
1174 m_iReticleOffsetXIndex = m_pMaterial.GetParamIndex("ReticleOffsetX");
1175 m_iReticleOffsetYIndex = m_pMaterial.GetParamIndex("ReticleOffsetY");
1176 m_iReticleColorIndex = m_pMaterial.GetParamIndex("ReticleColor");
1177 m_iReticleScaleIndex = m_pMaterial.GetParamIndex("ReticleScale");
1178 m_iEdgeMinIndex = m_pMaterial.GetParamIndex("EdgeMin");
1179 m_iEdgeMaxIndex = m_pMaterial.GetParamIndex("EdgeMax");
1180 m_iEdgeCenterXIndex = m_pMaterial.GetParamIndex("EdgeCenterX");
1181 m_iEdgeCenterYIndex = m_pMaterial.GetParamIndex("EdgeCenterY");
1182 }
1183 else
1184 {
1185 Print("Cannot initialize PiP HDR PP !", LogLevel.ERROR);
1186 }
1187 }
1188
1189
1190 //------------------------------------------------------------------------------------------------
1191 protected override void ApplyRecoilToCamera(inout vector pOutCameraTransform[4], vector aimModAngles)
1192 {
1193 if (m_bPIPIsEnabled)
1194 return;
1195
1196 vector weaponAnglesMat[3];
1197 Math3D.AnglesToMatrix(aimModAngles, weaponAnglesMat);
1198 Math3D.MatrixMultiply3(pOutCameraTransform, weaponAnglesMat, pOutCameraTransform);
1199 }
1200
1201 //------------------------------------------------------------------------------------------------
1202 override bool CanFreelook()
1203 {
1204 if (m_bPIPIsEnabled)
1205 return true;
1206
1207 return super.CanFreelook();
1208 }
1209
1210 #ifdef WORKBENCH
1211 //------------------------------------------------------------------------------------------------
1212 override int _WB_GetAfterWorldUpdateSpecs(IEntity owner, IEntitySource src)
1213 {
1214 return EEntityFrameUpdateSpecs.CALL_WHEN_ENTITY_VISIBLE;
1215 }
1216
1217 //------------------------------------------------------------------------------------------------
1218 protected override void _WB_AfterWorldUpdate(IEntity owner, float timeSlice)
1219 {
1220 const ShapeFlags shapeFlags = ShapeFlags.ONCE | ShapeFlags.NOZBUFFER | ShapeFlags.TRANSP | ShapeFlags.DOUBLESIDE | ShapeFlags.NOOUTLINE;
1221 const float axisLength = 0.1;
1222
1223 vector ownerTransform[4];
1224 owner.GetWorldTransform(ownerTransform);
1225
1226 SCR_2DOpticsComponentClass data = SCR_2DOpticsComponentClass.Cast(GetComponentData(owner));
1227 if (!data)
1228 return;
1229
1230 vector objectiveTransform[4];
1231 Math3D.AnglesToMatrix(data.GetCameraAngles(), objectiveTransform);
1232 Math3D.MatrixMultiply3(objectiveTransform, ownerTransform, objectiveTransform);
1233 objectiveTransform[3] = (GetSightsFrontPosition(true) + data.GetCameraOffset()).Multiply4(ownerTransform);
1234
1235 vector objectiveSide = objectiveTransform[0];
1236 vector objectiveUp = objectiveTransform[1];
1237 vector objectiveForward = objectiveTransform[2];
1238 vector objectiveCenter = objectiveTransform[3];
1239
1240 Shape rightArrow = Shape.CreateArrow(objectiveCenter, objectiveCenter + objectiveSide * axisLength, 0.01, Color.DARK_RED, shapeFlags);
1241 Shape upArrow = Shape.CreateArrow(objectiveCenter, objectiveCenter + objectiveUp * axisLength, 0.01, Color.DARK_GREEN, shapeFlags);
1242 Shape fwdArrow = Shape.CreateArrow(objectiveCenter, objectiveCenter + objectiveForward * axisLength, 0.01, Color.DARK_BLUE, shapeFlags);
1243
1244 // Flip the transform for objective circle drawing
1245 objectiveTransform[1] = objectiveForward;
1246 objectiveTransform[2] = objectiveUp;
1247 objectiveTransform[3] = objectiveCenter;
1248 SCR_Shape.DrawCircle(objectiveTransform, m_fScopeRadius, Color.DARK_RED, COLOR_YELLOW_A, shapeFlags);
1249
1250 // Draw ocular circle
1251 vector ocularTransform[4];
1252 ocularTransform[0] = ownerTransform[0];
1253 ocularTransform[1] = ownerTransform[2];
1254 ocularTransform[2] = ownerTransform[1];
1255 ocularTransform[3] = GetSightsRearPosition(true).Multiply4(ownerTransform);
1256
1257 SCR_Shape.DrawCircle(ocularTransform, m_fScopeRadius, Color.DARK_RED, COLOR_YELLOW_A, shapeFlags);
1258
1259 // Draw ocular cross
1260 vector ocularHorizontal[2];
1261 vector ocularSide = ownerTransform[0] * m_fScopeRadius;
1262 ocularHorizontal[0] = ocularTransform[3] + ocularSide;
1263 ocularHorizontal[1] = ocularTransform[3] - ocularSide;
1264
1265 vector ocularVertical[2];
1266 vector ocularUp = ownerTransform[1] * m_fScopeRadius;
1267 ocularVertical[0] = ocularTransform[3] - ocularUp;
1268 ocularVertical[1] = ocularTransform[3] + ocularUp;
1269
1270 Shape.CreateLines(Color.DARK_RED, shapeFlags, ocularHorizontal, 2);
1271 Shape.CreateLines(Color.DARK_RED, shapeFlags, ocularVertical, 2);
1272
1273 // Draw eye position
1274 vector eyeTransform[4]
1275 GetSightsTransform(eyeTransform);
1276 Shape.CreateArrow(eyeTransform[3], ocularTransform[3], m_fScopeRadius* 0.3, Color.DARK_CYAN, shapeFlags);
1277 Shape.CreateSphere(Color.DARK_CYAN, shapeFlags, eyeTransform[3], 0.001);
1278 }
1279 #endif
1280
1281 #ifdef ENABLE_DIAG
1282 protected static bool s_PIPDiagRegistered;
1283
1284 //------------------------------------------------------------------------------------------------
1285 static void InputFloatClamped(inout float value, string label, float min, float max, int pxWidth = 100)
1286 {
1287 DbgUI.InputFloat(label, value, pxWidth);
1288 value = Math.Clamp(value, min, max);
1289 }
1290
1291 //------------------------------------------------------------------------------------------------
1292 protected void DrawDiagWindow()
1293 {
1294 DbgUI.Begin("2DPIPSights");
1295 {
1296
1297 SCR_2DPIPSightsComponentClass data = SCR_2DPIPSightsComponentClass.Cast(GetComponentData(GetOwner()));
1298 if (data)
1299 data.DrawSharedDataDiag();
1300
1301 InputFloatClamped(m_fCurrentCameraPitch, "m_fCurrentCameraPitch", -90.0, 90.0);
1302 InputFloatClamped(m_fScopeRadius, "m_fScopeRadius", -90.0, 90.0);
1303 }
1304
1305 DbgUI.End();
1306 }
1307 #endif
1308
1309 //------------------------------------------------------------------------------------------------
1311 void SCR_2DPIPSightsComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
1312 {
1313 #ifdef ENABLE_DIAG
1314 if (!s_PIPDiagRegistered)
1315 {
1316 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_WEAPONS_PIP_SIGHTS,"","Show PIP settings diag","Weapons");
1317 s_PIPDiagRegistered = true;
1318 }
1319 #endif
1320 }
1321
1322 //------------------------------------------------------------------------------------------------
1324 void ~SCR_2DPIPSightsComponent()
1325 {
1326 Destroy();
1327 if (m_pMaterial)
1328 {
1329 m_pMaterial = null;
1330 }
1331
1332 /*
1333 This should prevent some static leakness.
1334 */
1335 if (IsPIPEnabled())
1336 SetPIPEnabled(false);
1337 }
1338}
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
ArmaReforgerScripted GetGame()
Definition game.c:1398
ref array< string > angles
params precision
SCR_2DPIPSightsComponentClass EPZ_RETICLE_OFFSET
SCR_2DPIPSightsComponentClass EPZ_NONE
Defines different means of adjusting zeroing for PIP sights.
void SetupFovInfo()
override void ApplyRecoilToCamera(inout vector pOutCameraTransform[4], vector aimModAngles)
override void HandleSightActivation()
SCR_2DSightsComponentClass m_SightsFovInfo
override float GetReticleOffsetYTarget()
override void HandleSightDeactivation()
override bool CanFreelook()
void OnSettingsMenuClosed(ChimeraMenuBase menu)
IEntity SpawnEntity(ResourceName entityResourceName, notnull IEntity slotOwner)
SCR_CharacterSoundComponentClass GetComponentData()
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
float distance
vector position
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
override bool Destroy(int editorPlayerID)
Get all prefabs that have the spawner data
UI layouts Menus CleanSweep CleanSweepAreaSelection layout
SCR_PIPCameraClass CameraBaseClass SCR_PIPCamera(IEntitySource src, IEntity parent)
enum EVehicleType IEntity
proto external int AddChild(notnull IEntity child, TNodeId pivot, EAddChildFlags flags=EAddChildFlags.AUTO_TRANSFORM)
Add Entity to hierarchy. Pivot is pivot index, or -1 for center of parent.
proto external void GetWorldTransform(out vector mat[])
See IEntity::GetTransform.
proto external BaseWorld GetWorld()
proto external void RemoveChild(notnull IEntity child, bool keepTransform=false)
Remove Entity from hierarchy.
proto external bool IsDeleted()
proto external IEntity GetRootParent()
float GetBaseFOV()
Returns true when current FOV of the optic does not match the target FOV.
bool IsAdjusting()
Returns true when current FOV of the optic does not match the target FOV.
void EntitySpawnParams()
Definition gameLib.c:130
IEntity GetOwner()
Owner entity of the fuel tank.
proto external float GetFocusFOV()
Returns the focus field of view in degrees.
const int COLOR_YELLOW_A
Definition constants.c:29
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
ShapeFlags
Definition ShapeFlags.c:13
SCR_FieldOfViewSettings Attribute
EAddChildFlags
proto native vector Vector(float x, float y, float z)
CameraLensFlareSetType
Type of the camera lens flare set.
event float GetADSDeactivationPercentageScript()
Called to get the ADS percentage when the sights go inactive.
event void OnSightADSPostFrame(IEntity owner, float timeSlice)
event void OnSightADSDeactivated()
Called every time the sight is deactivated.
event float GetADSActivationPercentageScript()
Called to get the ADS percentage when the sights go active.
event void OnSightADSActivated()
Called every time the sight is activated.
PostProcessEffectType
Definition EnWorld.c:20