A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
VRInteractibleFunctionLibrary.h
Go to the documentation of this file.
1// Fill out your copyright notice in the Description page of Project Settings.
2
3#pragma once
4#include "CoreMinimal.h"
5//#include "IMotionController.h"
6#include "VRBPDatatypes.h"
7#include "UObject/ObjectMacros.h"
8#include "Engine/EngineTypes.h"
9#include "UObject/ScriptInterface.h"
10#include "Kismet/BlueprintFunctionLibrary.h"
11#include "GameplayTagContainer.h"
12
13#include "VRInteractibleFunctionLibrary.generated.h"
14
15//General Advanced Sessions Log
16DECLARE_LOG_CATEGORY_EXTERN(VRInteractibleFunctionLibraryLog, Log, All);
17
18// Declares our interactible axis's
19UENUM(Blueprintable)
20enum class EVRInteractibleAxis : uint8
21{
22 Axis_X,
24 Axis_Z
25};
26
27// A data structure to hold important interactible data
28// Should be init'd in Beginplay with BeginPlayInit as well as OnGrip with OnGripInit.
29// Works in "static space", it records the original relative transform of the interactible on begin play
30// so that calculations on the actual component can be done based off of it.
31USTRUCT(BlueprintType, Category = "VRExpansionLibrary")
32struct VREXPANSIONPLUGIN_API FBPVRInteractibleBaseData
33{
34 GENERATED_BODY()
35public:
36
37 // Our initial relative transform to our parent "static space" - Set in BeginPlayInit
38 UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData")
39 FTransform InitialRelativeTransform;
41 // Initial location in "static space" of the interactor on grip - Set in OnGripInit
42 UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData")
43 FVector InitialInteractorLocation;
44
45 // Initial location of the interactible in the "static space" - Set in OnGripInit
46 UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData")
47 FVector InitialGripLoc;
48
49 // Initial location on the interactible of the grip, used for drop calculations - Set in OnGripInit
50 UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData")
51 FVector InitialDropLocation;
52
53 // The initial transform in relative space of the grip to us - Set in OnGripInit
54 UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData")
55 FTransform ReversedRelativeTransform;
56
58 {
59 InitialInteractorLocation = FVector::ZeroVector;
60 InitialGripLoc = FVector::ZeroVector;
61 InitialDropLocation = FVector::ZeroVector;
62 }
63};
64
65UCLASS()
66class VREXPANSIONPLUGIN_API UVRInteractibleFunctionLibrary : public UBlueprintFunctionLibrary
67{
68 GENERATED_BODY()
69public:
70
71 static float GetAtan2Angle(EVRInteractibleAxis AxisToCalc, FVector CurInteractorLocation, float OptionalInitialRotation = 0.0f)
72 {
73 switch (AxisToCalc)
74 {
76 {
77 return FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Y, CurInteractorLocation.Z)) - OptionalInitialRotation;
78 }break;
80 {
81 return FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Z, CurInteractorLocation.X)) - OptionalInitialRotation;
82 }break;
84 {
85 return FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Y, CurInteractorLocation.X)) - OptionalInitialRotation;
86 }break;
87 default:
88 {}break;
89 }
90
91 return 0.0f;
92 }
93
94 static float GetDeltaAngleFromTransforms(EVRInteractibleAxis RotAxis, FTransform & InitialRelativeTransform, FTransform &CurrentRelativeTransform)
95 {
96 return GetDeltaAngle(RotAxis, (CurrentRelativeTransform.GetRelativeTransform(InitialRelativeTransform).GetRotation()).GetNormalized());
97 }
98
99 static float GetDeltaAngle(EVRInteractibleAxis RotAxis, FQuat DeltaQuat)
100 {
101 FVector Axis;
102 float Angle;
103 DeltaQuat.ToAxisAndAngle(Axis, Angle);
104
105 if (RotAxis == EVRInteractibleAxis::Axis_Z)
106 return FRotator::NormalizeAxis(FMath::RadiansToDegrees(Angle)) * (FMath::Sign(GetAxisValue(RotAxis, Axis)));
107 else
108 return FRotator::NormalizeAxis(FMath::RadiansToDegrees(Angle)) * (-FMath::Sign(GetAxisValue(RotAxis, Axis)));
109 }
110
111 static float GetAxisValue(EVRInteractibleAxis RotAxis, FRotator CheckRotation)
112 {
113 switch (RotAxis)
114 {
116 return CheckRotation.Roll; break;
118 return CheckRotation.Pitch; break;
120 return CheckRotation.Yaw; break;
121 default:return 0.0f; break;
123 }
124
125 static float GetAxisValue(EVRInteractibleAxis RotAxis, FVector CheckAxis)
126 {
127 switch (RotAxis)
128 {
130 return CheckAxis.X; break;
132 return CheckAxis.Y; break;
134 return CheckAxis.Z; break;
135 default:return 0.0f; break;
136 }
137 }
138
139 static FVector SetAxisValueVec(EVRInteractibleAxis RotAxis, float SetValue)
140 {
141 FVector vec = FVector::ZeroVector;
142
143 switch (RotAxis)
144 {
146 vec.X = SetValue; break;
148 vec.Y = SetValue; break;
150 vec.Z = SetValue; break;
151 default:break;
152 }
154 return vec;
155 }
156
157 static FRotator SetAxisValueRot(EVRInteractibleAxis RotAxis, float SetValue)
158 {
159 FRotator vec = FRotator::ZeroRotator;
160
161 switch (RotAxis)
162 {
164 vec.Roll = SetValue; break;
166 vec.Pitch = SetValue; break;
168 vec.Yaw = SetValue; break;
169 default:break;
170 }
171
172 return vec;
173 }
174
175 static FRotator SetAxisValueRot(EVRInteractibleAxis RotAxis, float SetValue, FRotator Var)
176 {
177 FRotator vec = Var;
178 switch (RotAxis)
179 {
181 vec.Roll = SetValue; break;
183 vec.Pitch = SetValue; break;
185 vec.Yaw = SetValue; break;
186 default:break;
187 }
188
189 return vec;
190 }
191
192 // Get current parent transform
193 UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
194 static FTransform Interactible_GetCurrentParentTransform(USceneComponent * SceneComponentToCheck)
195 {
196 if (SceneComponentToCheck)
197 {
198 if (USceneComponent * AttachParent = SceneComponentToCheck->GetAttachParent())
199 {
200 return AttachParent->GetComponentTransform();
201 }
202 }
204 return FTransform::Identity;
205 }
206
207 // Get current relative transform (original transform we were at on grip for the current parent transform)
208 UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
209 static FTransform Interactible_GetCurrentRelativeTransform(USceneComponent * SceneComponentToCheck, UPARAM(ref)FBPVRInteractibleBaseData & BaseData)
210 {
211 FTransform ParentTransform = FTransform::Identity;
212 if (SceneComponentToCheck)
213 {
214 if (USceneComponent * AttachParent = SceneComponentToCheck->GetAttachParent())
215 {
216 // during grip there is no parent so we do this, might as well do it anyway for lerping as well
217 ParentTransform = AttachParent->GetComponentTransform();
218 }
219 }
220
221 return BaseData.InitialRelativeTransform * ParentTransform;
222 }
223
224 // Inits the initial relative transform of an interactible on begin play
225 UFUNCTION(BlueprintCallable, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
226 static void Interactible_BeginPlayInit(USceneComponent * InteractibleComp, UPARAM(ref) FBPVRInteractibleBaseData & BaseDataToInit)
227 {
228 if (!InteractibleComp)
229 return;
230
231 BaseDataToInit.InitialRelativeTransform = InteractibleComp->GetRelativeTransform();
232 }
233
234 // Inits the calculated values of a VR Interactible Base Data Structure on a grip event
235 UFUNCTION(BlueprintCallable, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
236 static void Interactible_OnGripInit(USceneComponent * InteractibleComp, UPARAM(ref) FBPActorGripInformation& GripInformation, UPARAM(ref) FBPVRInteractibleBaseData & BaseDataToInit)
237 {
238 if (!InteractibleComp)
239 return;
240
241 BaseDataToInit.ReversedRelativeTransform = FTransform(GripInformation.RelativeTransform.ToInverseMatrixWithScale());
242 BaseDataToInit.InitialDropLocation = BaseDataToInit.ReversedRelativeTransform.GetTranslation(); // Technically a duplicate, but will be more clear
244 FTransform RelativeToGripTransform = BaseDataToInit.ReversedRelativeTransform * InteractibleComp->GetComponentTransform();
245 FTransform CurrentRelativeTransform = BaseDataToInit.InitialRelativeTransform * UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(InteractibleComp);
246 BaseDataToInit.InitialInteractorLocation = CurrentRelativeTransform.InverseTransformPosition(RelativeToGripTransform.GetTranslation());
247
248 BaseDataToInit.InitialGripLoc = BaseDataToInit.InitialRelativeTransform.InverseTransformPosition(InteractibleComp->GetRelativeLocation());
249 }
250
251 // Returns (in degrees) the angle around the axis of a location
252 // Expects the CurInteractorLocation to be in relative space already
253 UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
254 static float Interactible_GetAngleAroundAxis(EVRInteractibleAxis AxisToCalc, FVector CurInteractorLocation)
255 {
256 float ReturnAxis = 0.0f;
257
258 switch (AxisToCalc)
259 {
261 {
262 ReturnAxis = FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Y, CurInteractorLocation.Z));
263 }break;
265 {
266 ReturnAxis = FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Z, CurInteractorLocation.X));
267 }break;
269 {
270 ReturnAxis = FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Y, CurInteractorLocation.X));
271 }break;
272 default:
273 {}break;
274 }
275
276 return ReturnAxis;
277 }
278
279 // Returns (in degrees) the delta rotation from the initial angle at grip to the current interactor angle around the axis
280 // Expects CurInteractorLocation to be in relative space already
281 // You can add this to an initial rotation and clamp the result to rotate over time based on hand position
282 UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
283 static float Interactible_GetAngleAroundAxisDelta(EVRInteractibleAxis AxisToCalc, FVector CurInteractorLocation, float InitialAngle)
284 {
285 return FRotator::NormalizeAxis(Interactible_GetAngleAroundAxis(AxisToCalc, CurInteractorLocation) - InitialAngle);
286 }
287
288
289 // Returns a value that is snapped to the given settings, taking into account the threshold and increment
290 UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
291 static float Interactible_GetThresholdSnappedValue(float ValueToSnap, float SnapIncrement, float SnapThreshold)
292 {
293 if (SnapIncrement > 0.f && FMath::Fmod(ValueToSnap, SnapIncrement) <= FMath::Min(SnapIncrement, SnapThreshold))
294 {
295 return FMath::GridSnap(ValueToSnap, SnapIncrement);
296 }
298 return ValueToSnap;
299 }
300
301};
302
303
DECLARE_LOG_CATEGORY_EXTERN(VRInteractibleFunctionLibraryLog, Log, All)
EVRInteractibleAxis
UENUM(Blueprintable)
static void Interactible_BeginPlayInit(USceneComponent *InteractibleComp, UPARAM(ref) FBPVRInteractibleBaseData &BaseDataToInit)
UFUNCTION(BlueprintCallable, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
static float GetDeltaAngleFromTransforms(EVRInteractibleAxis RotAxis, FTransform &InitialRelativeTransform, FTransform &CurrentRelativeTransform)
static FRotator SetAxisValueRot(EVRInteractibleAxis RotAxis, float SetValue, FRotator Var)
static float GetAxisValue(EVRInteractibleAxis RotAxis, FRotator CheckRotation)
static float GetDeltaAngle(EVRInteractibleAxis RotAxis, FQuat DeltaQuat)
static void Interactible_OnGripInit(USceneComponent *InteractibleComp, UPARAM(ref) FBPActorGripInformation &GripInformation, UPARAM(ref) FBPVRInteractibleBaseData &BaseDataToInit)
UFUNCTION(BlueprintCallable, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
static FRotator SetAxisValueRot(EVRInteractibleAxis RotAxis, float SetValue)
static float Interactible_GetAngleAroundAxis(EVRInteractibleAxis AxisToCalc, FVector CurInteractorLocation)
UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
static float GetAxisValue(EVRInteractibleAxis RotAxis, FVector CheckAxis)
static float GetAtan2Angle(EVRInteractibleAxis AxisToCalc, FVector CurInteractorLocation, float OptionalInitialRotation=0.0f)
static float Interactible_GetAngleAroundAxisDelta(EVRInteractibleAxis AxisToCalc, FVector CurInteractorLocation, float InitialAngle)
UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
static float Interactible_GetThresholdSnappedValue(float ValueToSnap, float SnapIncrement, float SnapThreshold)
UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
static FTransform Interactible_GetCurrentRelativeTransform(USceneComponent *SceneComponentToCheck, UPARAM(ref) FBPVRInteractibleBaseData &BaseData)
UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
static FVector SetAxisValueVec(EVRInteractibleAxis RotAxis, float SetValue)
static FTransform Interactible_GetCurrentParentTransform(USceneComponent *SceneComponentToCheck)
UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
USTRUCT(BlueprintType, Category = "VRExpansionLibrary")
USTRUCT(BlueprintType, Category = "VRExpansionLibrary")
FVector InitialGripLoc
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData")
FTransform InitialRelativeTransform
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData")
FVector InitialDropLocation
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData")
FVector InitialInteractorLocation
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData")
FTransform ReversedRelativeTransform
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData")